pub mod actuator;
pub mod sensor;
pub mod translator;
pub mod utils;
use alloc::format;
use core::fmt::{Debug, Display, Formatter};
use core::hash::{Hash, Hasher};
use heapless::{LinearMap, String, Vec};
use serde::{Deserialize, Serialize};
use crate::communication::connection::{Address, Connection, ConnectionFactory};
use crate::communication::messages::{IdentificableMessage, SimpleCodifier, Messages, PackageBuilder};
use crate::communication::router::{Router, UNKNOWN_ROUTE_STARTING_ID};
use crate::coordination::{CoordinationService, Stopwatch};
use crate::membership::client::{MembersAddresses, MembershipMessage};
use crate::membership::metadata::{BasicMetadata, CommunicationMetadata, CoordinationMetadataBuilder, SerializableMetadata};
use crate::properties::{CLUSTER_NODE_COUNT, CLUSTERS_PER_TRANSLATOR};
use crate::rules::measurements::ClusterType;
#[derive(Clone, Debug, Eq, PartialEq, Serialize, Deserialize)]
pub enum NodeRole {
ACTUATOR,
SENSOR(ClusterType),
TRANSLATOR,
}
#[derive(Debug, Default, Eq, PartialEq, Ord, PartialOrd, Copy, Clone, Serialize, Deserialize, Hash, )]
pub struct SystemNodeId {
id: u32,
}
impl PartialEq<u32> for SystemNodeId {
fn eq(&self, other: &u32) -> bool {
self.id == *other
}
}
impl Display for SystemNodeId {
fn fmt(&self, formatter: &mut Formatter<'_>) -> core::fmt::Result {
write!(formatter, "{}", self.id)
}
}
impl SystemNodeId {
pub fn next(&self) -> Self {
Self { id: self.id + 1 }
}
pub fn is_unknown(&self) -> bool { self.id >= UNKNOWN_ROUTE_STARTING_ID }
}
impl From<u32> for SystemNodeId {
fn from(id: u32) -> Self {
Self { id }
}
}
impl Into<u32> for SystemNodeId {
fn into(self) -> u32 {
self.id
}
}
#[derive(Debug, Default, Eq, PartialEq, Ord, PartialOrd, Copy, Clone, Serialize, Deserialize)]
pub struct SystemClusterId {
id: u32,
}
impl Hash for SystemClusterId {
fn hash<H: Hasher>(&self, state: &mut H) {
let bytes = self.id.to_le_bytes();
state.write(&bytes)
}
}
impl Display for SystemClusterId {
fn fmt(&self, formatter: &mut Formatter<'_>) -> core::fmt::Result {
write!(formatter, "{}", self.id)
}
}
impl From<u32> for SystemClusterId {
fn from(id: u32) -> Self {
Self { id }
}
}
#[derive(Serialize, Deserialize, Debug, Clone, Eq, PartialEq)]
pub struct SystemMetadata<CommMetadata: CommunicationMetadata> {
pub id: SystemNodeId,
pub role: NodeRole,
pub clusters: Vec<SystemClusterId, CLUSTERS_PER_TRANSLATOR>,
pub communication: CommMetadata,
}
impl<CommMetadata: CommunicationMetadata> SystemMetadata<CommMetadata> {
pub fn same_cluster(&self, cluster_id: SystemClusterId) -> bool {
self.clusters.contains(&cluster_id)
}
pub fn log_clusters(&self) -> String<50> {
let mut clusters = String::<50>::new();
for cluster_id in self.clusters.iter() {
if !clusters.is_empty() {
clusters.push_str(", ").unwrap();
}
clusters.push_str(format!("#{}", cluster_id).as_str()).unwrap();
}
clusters
}
}
impl<CommMetadata: CommunicationMetadata + SerializableMetadata> Display
for SystemMetadata<CommMetadata>
{
fn fmt(&self, formatter: &mut Formatter<'_>) -> core::fmt::Result {
let mut clusters = String::<50>::new();
for cluster_id in self.clusters.iter() {
if !clusters.is_empty() {
clusters.push_str(", ").unwrap();
}
clusters.push_str(format!("#{}", cluster_id).as_str()).unwrap();
}
write!(
formatter,
"[ID: #{} | Role: {:?} | Clusters: [{}] | Communication: {}]",
self.id, self.role, clusters, self.communication
)
}
}
impl<CommMetadata: CommunicationMetadata + SerializableMetadata> BasicMetadata
for SystemMetadata<CommMetadata>
{
}
impl<CommMetadata: CommunicationMetadata + SerializableMetadata> SerializableMetadata
for SystemMetadata<CommMetadata>
{
}
pub trait CoordinationSDK {
type Clock: Stopwatch + Default;
type Members: Clone + Debug + From<LinearMap<SystemNodeId, Self::Metadata, CLUSTER_NODE_COUNT>>;
type Message: IdentificableMessage;
type Metadata: BasicMetadata + SerializableMetadata;
type Service: CoordinationService<Self::Clock, Self::Message, Self::Members, Self::Metadata>;
type PackageBuilder: PackageBuilder<NodeId =SystemNodeId, Message = Self::Message> + Default;
type MetadataBuilder: CoordinationMetadataBuilder<Self::Metadata>;
}
pub trait CommunicationSDK {
type Address: Address;
type Connection: Connection;
type Metadata: CommunicationMetadata<Addr = Self::Address>;
type Router: Router<Address = Self::Address>;
type Factory: ConnectionFactory<Address = Self::Address, Connection = Self::Connection>;
}
pub trait SerializationSDK<
Addr: Address,
CoordMessage: IdentificableMessage,
CoordMetadata: BasicMetadata + SerializableMetadata,
CommMetadata: CommunicationMetadata<Addr = Addr>,
>
{
type GeneralMessageCodifier: SimpleCodifier<Data=Messages<CoordMessage>>;
type MembershipMessageCodifier: SimpleCodifier<Data=MembershipMessage>;
type AddressCodifier: SimpleCodifier<Data=MembersAddresses<Addr>>;
type SystemMetadataCodifier: SimpleCodifier<Data=SystemMetadata<CommMetadata>>;
type CoordinatedMetadataCodifier: SimpleCodifier<Data=CoordMetadata>;
}