aboutsummaryrefslogtreecommitdiff
path: root/src/lib.rs
diff options
context:
space:
mode:
authordiogo464 <[email protected]>2025-12-04 21:14:27 +0000
committerdiogo464 <[email protected]>2025-12-04 21:14:27 +0000
commitabdcb51d7e9d6ebfacdf17b32e5296464e0aa2d4 (patch)
tree69b91ea6271abb8c1080f7bc3abb1bff4a46c32c /src/lib.rs
parent01eab62d1d6b1ce77e63d29efb7bf57da74da8a1 (diff)
added switch example
Diffstat (limited to 'src/lib.rs')
-rw-r--r--src/lib.rs96
1 files changed, 95 insertions, 1 deletions
diff --git a/src/lib.rs b/src/lib.rs
index 1f9d2d5..d954883 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -1,6 +1,6 @@
1#![no_std] 1#![no_std]
2 2
3use core::{cell::RefCell, task::Waker}; 3use core::{cell::RefCell, str::FromStr, task::Waker};
4 4
5use defmt::Format; 5use defmt::Format;
6use embassy_sync::waitqueue::AtomicWaker; 6use embassy_sync::waitqueue::AtomicWaker;
@@ -198,6 +198,90 @@ impl<'a> Number<'a> {
198 } 198 }
199} 199}
200 200
201pub struct InvalidSwitchState;
202
203#[derive(Debug, Clone, Copy, PartialEq, Eq)]
204pub enum SwitchState {
205 On,
206 Off,
207}
208
209impl SwitchState {
210 pub fn as_str(&self) -> &'static str {
211 match self {
212 Self::On => constants::HA_SWITCH_STATE_ON,
213 Self::Off => constants::HA_SWITCH_STATE_OFF,
214 }
215 }
216}
217
218impl core::fmt::Display for SwitchState {
219 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
220 f.write_str(self.as_str())
221 }
222}
223
224impl FromStr for SwitchState {
225 type Err = InvalidSwitchState;
226
227 fn from_str(s: &str) -> Result<Self, Self::Err> {
228 if s.eq_ignore_ascii_case(constants::HA_SWITCH_STATE_ON) {
229 return Ok(Self::On);
230 }
231 if s.eq_ignore_ascii_case(constants::HA_SWITCH_STATE_OFF) {
232 return Ok(Self::Off);
233 }
234 Err(InvalidSwitchState)
235 }
236}
237
238impl TryFrom<&[u8]> for SwitchState {
239 type Error = InvalidSwitchState;
240
241 fn try_from(value: &[u8]) -> Result<Self, Self::Error> {
242 let string = str::from_utf8(value).map_err(|_| InvalidSwitchState)?;
243 string.parse()
244 }
245}
246
247pub struct Switch<'a>(Entity<'a>);
248
249impl<'a> Switch<'a> {
250 pub fn state(&self) -> Option<SwitchState> {
251 self.0
252 .with_data(|data| SwitchState::try_from(data.command_value.as_slice()).ok())
253 }
254
255 pub fn toggle(&mut self) -> SwitchState {
256 let curr_state = self.state().unwrap_or(SwitchState::Off);
257 let new_state = match curr_state {
258 SwitchState::On => SwitchState::Off,
259 SwitchState::Off => SwitchState::On,
260 };
261 self.set(new_state);
262 new_state
263 }
264
265 pub fn set(&mut self, state: SwitchState) {
266 self.0.publish(
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 }
274
275 pub async fn wait(&mut self) -> SwitchState {
276 loop {
277 self.0.wait_command().await;
278 if let Some(state) = self.state() {
279 return state;
280 }
281 }
282 }
283}
284
201#[derive(Default)] 285#[derive(Default)]
202pub struct EntityConfig { 286pub struct EntityConfig {
203 pub id: &'static str, 287 pub id: &'static str,
@@ -393,6 +477,16 @@ impl<'a> Device<'a> {
393 Number(entity) 477 Number(entity)
394 } 478 }
395 479
480 pub fn create_switch(&self, id: &'static str, name: &'static str) -> Switch<'a> {
481 let entity = self.create_entity(EntityConfig {
482 id,
483 name,
484 domain: constants::HA_DOMAIN_SWITCH,
485 ..Default::default()
486 });
487 Switch(entity)
488 }
489
396 pub async fn run<T: Transport>(&mut self, transport: &mut T) -> ! { 490 pub async fn run<T: Transport>(&mut self, transport: &mut T) -> ! {
397 loop { 491 loop {
398 self.run_iteration(&mut *transport).await; 492 self.run_iteration(&mut *transport).await;