aboutsummaryrefslogtreecommitdiff
path: root/src/lib.rs
diff options
context:
space:
mode:
authordiogo464 <[email protected]>2025-12-04 23:59:21 +0000
committerdiogo464 <[email protected]>2025-12-04 23:59:21 +0000
commit40a16d099c2bf2b3e5bf537aa14d37fdf9e52668 (patch)
treefae2ec76ca797e1e55d678cabea743c91d30de5c /src/lib.rs
parentabdcb51d7e9d6ebfacdf17b32e5296464e0aa2d4 (diff)
added basic binary sensor example
Diffstat (limited to 'src/lib.rs')
-rw-r--r--src/lib.rs110
1 files changed, 98 insertions, 12 deletions
diff --git a/src/lib.rs b/src/lib.rs
index d954883..408dbb9 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -213,6 +213,13 @@ impl SwitchState {
213 Self::Off => constants::HA_SWITCH_STATE_OFF, 213 Self::Off => constants::HA_SWITCH_STATE_OFF,
214 } 214 }
215 } 215 }
216
217 pub fn flip(self) -> Self {
218 match self {
219 Self::On => Self::Off,
220 Self::Off => Self::On,
221 }
222 }
216} 223}
217 224
218impl core::fmt::Display for SwitchState { 225impl core::fmt::Display for SwitchState {
@@ -253,23 +260,13 @@ impl<'a> Switch<'a> {
253 } 260 }
254 261
255 pub fn toggle(&mut self) -> SwitchState { 262 pub fn toggle(&mut self) -> SwitchState {
256 let curr_state = self.state().unwrap_or(SwitchState::Off); 263 let new_state = self.state().unwrap_or(SwitchState::Off).flip();
257 let new_state = match curr_state {
258 SwitchState::On => SwitchState::Off,
259 SwitchState::Off => SwitchState::On,
260 };
261 self.set(new_state); 264 self.set(new_state);
262 new_state 265 new_state
263 } 266 }
264 267
265 pub fn set(&mut self, state: SwitchState) { 268 pub fn set(&mut self, state: SwitchState) {
266 self.0.publish( 269 self.0.publish(state.as_str().as_bytes());
267 match state {
268 SwitchState::On => constants::HA_SWITCH_STATE_ON,
269 SwitchState::Off => constants::HA_SWITCH_STATE_OFF,
270 }
271 .as_bytes(),
272 );
273 } 270 }
274 271
275 pub async fn wait(&mut self) -> SwitchState { 272 pub async fn wait(&mut self) -> SwitchState {
@@ -282,6 +279,79 @@ impl<'a> Switch<'a> {
282 } 279 }
283} 280}
284 281
282pub struct InvalidBinarySensorState;
283
284#[derive(Debug, Clone, Copy, PartialEq, Eq)]
285pub enum BinarySensorState {
286 On,
287 Off,
288}
289
290impl BinarySensorState {
291 pub fn as_str(&self) -> &'static str {
292 match self {
293 Self::On => constants::HA_BINARY_SENSOR_STATE_ON,
294 Self::Off => constants::HA_BINARY_SENSOR_STATE_OFF,
295 }
296 }
297
298 pub fn flip(self) -> Self {
299 match self {
300 Self::On => Self::Off,
301 Self::Off => Self::On,
302 }
303 }
304}
305
306impl core::fmt::Display for BinarySensorState {
307 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
308 f.write_str(self.as_str())
309 }
310}
311
312impl FromStr for BinarySensorState {
313 type Err = InvalidBinarySensorState;
314
315 fn from_str(s: &str) -> Result<Self, Self::Err> {
316 if s.eq_ignore_ascii_case(constants::HA_BINARY_SENSOR_STATE_ON) {
317 return Ok(Self::On);
318 }
319 if s.eq_ignore_ascii_case(constants::HA_BINARY_SENSOR_STATE_OFF) {
320 return Ok(Self::Off);
321 }
322 Err(InvalidBinarySensorState)
323 }
324}
325
326impl TryFrom<&[u8]> for BinarySensorState {
327 type Error = InvalidBinarySensorState;
328
329 fn try_from(value: &[u8]) -> Result<Self, Self::Error> {
330 let string = str::from_utf8(value).map_err(|_| InvalidBinarySensorState)?;
331 string.parse()
332 }
333}
334
335pub struct BinarySensor<'a>(Entity<'a>);
336
337impl<'a> BinarySensor<'a> {
338 pub fn set(&mut self, state: BinarySensorState) {
339 self.0.publish(state.as_str().as_bytes());
340 }
341
342 pub fn value(&self) -> Option<BinarySensorState> {
343 self.0
344 .with_data(|data| BinarySensorState::try_from(data.publish_value.as_slice()))
345 .ok()
346 }
347
348 pub fn toggle(&mut self) -> BinarySensorState {
349 let new_state = self.value().unwrap_or(BinarySensorState::Off).flip();
350 self.set(new_state);
351 new_state
352 }
353}
354
285#[derive(Default)] 355#[derive(Default)]
286pub struct EntityConfig { 356pub struct EntityConfig {
287 pub id: &'static str, 357 pub id: &'static str,
@@ -487,6 +557,22 @@ impl<'a> Device<'a> {
487 Switch(entity) 557 Switch(entity)
488 } 558 }
489 559
560 pub fn create_binary_sensor(
561 &self,
562 id: &'static str,
563 name: &'static str,
564 class: &'static str,
565 ) -> BinarySensor<'a> {
566 let entity = self.create_entity(EntityConfig {
567 id,
568 name,
569 domain: constants::HA_DOMAIN_BINARY_SENSOR,
570 device_class: Some(class),
571 ..Default::default()
572 });
573 BinarySensor(entity)
574 }
575
490 pub async fn run<T: Transport>(&mut self, transport: &mut T) -> ! { 576 pub async fn run<T: Transport>(&mut self, transport: &mut T) -> ! {
491 loop { 577 loop {
492 self.run_iteration(&mut *transport).await; 578 self.run_iteration(&mut *transport).await;