1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256
//! This module defines the metadata on devices and services. //! //! Note that all the data structures in this module represent //! snapshots of subsets of the devices available. None of these data //! structures are live, so there is always the possibility that //! devices may have been added or removed from the FoxBox by the time //! these data structures are read. use values::*; use util::Id; use serde::ser::{Serialize, Serializer}; use serde::de::{Deserialize, Deserializer, Error}; /// A marker for Id. /// Only useful for writing `Id<NodeId>`. #[derive(Debug, Clone, PartialEq, Serialize, Deserialize, Hash, Eq)] pub struct NodeId; /// Metadata on a node. A node is a device or collection of devices /// that may offer services. The FoxBox itself a node offering /// services such as a clock, communication with the user through her /// smart devices, etc. #[derive(Debug, Clone, Serialize, Deserialize)] pub struct Node { /// Tags describing the node. /// /// These tags can be set by the user, adapters or /// applications. They are used by applications to find nodes and /// services. /// /// For instance, a user may set tag "entrance" to all nodes /// placed in the entrance of his house, or a tag "blue" to a node /// controlling blue lights. An adapter may set tags "plugged" or /// "battery" to devices that respectively depend on a plugged /// power source or on a battery. pub tags: Vec<String>, /// An id unique to this node. pub id: Id<NodeId>, /// Channels connected directly to this node. pub inputs: Vec<Channel<Get>>, pub outputs: Vec<Channel<Set>>, /// Make sure that we can't instantiate from another crate. #[serde(default, skip_serializing)] private: (), } /// The kind of the service, i.e. a strongly-typed description of /// _what_ the service can do. Used both for locating services /// (e.g. "I need a clock" or "I need something that can provide /// pictures") and for determining the data structure that these /// services can provide or consume. /// /// A number of service kinds are standardized, and provided as a set /// of strongly-typed enum constructors. It is clear, however, that /// many devices will offer services that cannot be described by /// pre-existing constructors. For this purpose, this enumeration /// offers a constructor `Extension`, designed to describe novel /// services. #[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] pub enum ChannelKind { /// /// # No payload /// /// The service is ready. Used for instance once a countdown has /// reached completion. Ready, /// /// # Boolean /// /// The service is used to detect or decide whether some device /// is on or off. OnOff, /// The service is used to detect or decide whether some device /// is open or closed. OpenClosed, /// /// # Time /// /// The service is used to read or set the current absolute time. /// Used for instance to wait until a specific time and day before /// triggering an action, or to set the appropriate time on a new /// device. CurrentTime, /// The service is used to read or set the current time of day. /// Used for instance to trigger an action at a specific hour /// every day. CurrentTimeOfDay, /// The service is part of a countdown. This is the time /// remaining until the countdown is elapsed. RemainingTime, /// /// # Temperature /// Thermostat, ActualTemperature, /// TODO: Add more /// An operation of a kind that has not been standardized yet. Extension { /// The vendor. Used for namespacing purposes, to avoid /// confusing two incompatible extensions with similar /// names. For instance, "foxlink@mozilla.com". vendor: String, /// Identification of the adapter introducing this operation. /// Designed to aid with tracing and debugging. adapter: String, /// A string describing the nature of the value, designed to /// let applications discover the devices. /// /// Examples: `"GroundHumidity"`. kind: String, /// The data type of the value. typ: Type } } impl ChannelKind { /// Get the type of values used to communicate with this service. pub fn get_type(&self) -> Type { use self::ChannelKind::*; use values::Type::*; match *self { Ready => Unit, OnOff | OpenClosed => Bool, CurrentTime => TimeStamp, CurrentTimeOfDay | RemainingTime => Duration, Thermostat | ActualTemperature => Temperature, Extension { ref typ, ..} => typ.clone(), } } } /// An input operation available on an service. #[derive(Debug, Clone, Serialize, Deserialize)] pub struct Get { /// The kind of value that can be obtained from this service. pub kind: ChannelKind, /// If `Some(duration)`, this service can be polled, i.e. it /// will respond when the FoxBox requests the latest value. /// Parameter `duration` indicates the smallest interval /// between two updates. /// /// Otherwise, the service cannot be polled and will push /// data to the FoxBox when it is available. /// /// # Examples /// /// - Long-running pollution or humidity sensors typically /// do not accept requests and rather send batches of /// data every 24h. #[serde(default)] pub poll: Option<ValDuration>, /// If `Some(duration)`, this service can send the data to /// the FoxBox whenever it is updated. Parameter `duration` /// indicates the smallest interval between two updates. /// /// Otherwise, the service cannot send data to the FoxBox /// and needs to be polled. #[serde(default)] pub trigger: Option<ValDuration>, /// Date at which the latest value was received, whether through /// polling or through a trigger. pub updated: Option<TimeStamp>, /// Make sure that we can't instantiate from another crate. #[serde(default, skip_serializing)] private: (), } impl IOMechanism for Get { } /// An output operation available on an service. #[derive(Debug, Clone, Serialize, Deserialize)] pub struct Set { /// The kind of value that can be sent to this service. pub kind: ChannelKind, /// If `Some(duration)`, this service supports pushing, /// i.e. the FoxBox can send values. #[serde(default)] pub push: Option<ValDuration>, /// Date at which the latest value was sent to the service. #[serde(default)] pub updated: Option<TimeStamp>, /// Make sure that we can't instantiate from another crate. #[serde(default, skip_serializing)] private: (), } impl IOMechanism for Set { } /// An service represents a single place where data can enter or /// leave a device. Note that services support either a single kind /// of input or a single kind of output. Devices that support both /// inputs or outputs, or several kinds of inputs, or several kinds of /// outputs, are represented as nodes containing several services. #[derive(Debug, Clone, Serialize, Deserialize)] pub struct Channel<IO> where IO: IOMechanism { /// Tags describing the service. /// /// These tags can be set by the user, adapters or /// applications. They are used to regroup services for rules. /// /// For instance "entrance". #[serde(default)] pub tags: Vec<String>, /// An id unique to this service. pub id: Id<IO>, /// The node owning this service. pub node: Id<NodeId>, /// The update mechanism for this service. pub mechanism: IO, /// The last time the device was seen. #[serde(default)] pub last_seen: Option<TimeStamp>, /// Make sure that we can't instantiate from another crate. #[serde(default, skip_serializing)] private: (), } /// A mechanism used for communicating between the application and the /// service. pub trait IOMechanism: Deserialize + Serialize { }