aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authordiogo464 <[email protected]>2025-12-06 14:31:54 +0000
committerdiogo464 <[email protected]>2025-12-06 14:31:54 +0000
commite5416e848c8caeed59e8aca6fb3e191fbc621b1b (patch)
treebd086e6d96f7acf2e051d29c5ce2fee3be4ea5f5 /src
parent0fbce715a32f5e05c2a66e5cc401105f72083ff5 (diff)
Refactor sensor API to support generic sensor types with configurable display precision
Replaced TemperatureSensor with a generic Sensor type that accepts sensor class, state class, unit, and display precision to support various sensor types. Added suggested_display_precision field to control decimal places in Home Assistant UI. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <[email protected]>
Diffstat (limited to 'src')
-rw-r--r--src/entity.rs1
-rw-r--r--src/entity_sensor.rs27
-rw-r--r--src/lib.rs12
3 files changed, 25 insertions, 15 deletions
diff --git a/src/entity.rs b/src/entity.rs
index ac15921..ef2b9ad 100644
--- a/src/entity.rs
+++ b/src/entity.rs
@@ -33,4 +33,5 @@ pub struct EntityConfig {
33 pub max: Option<f32>, 33 pub max: Option<f32>,
34 pub step: Option<f32>, 34 pub step: Option<f32>,
35 pub mode: Option<&'static str>, 35 pub mode: Option<&'static str>,
36 pub suggested_display_precision: Option<u8>,
36} 37}
diff --git a/src/entity_sensor.rs b/src/entity_sensor.rs
index 702c9de..1a99754 100644
--- a/src/entity_sensor.rs
+++ b/src/entity_sensor.rs
@@ -1,5 +1,5 @@
1use crate::{ 1use crate::{
2 Entity, EntityCommonConfig, EntityConfig, NumericSensorState, TemperatureUnit, constants, 2 Entity, EntityCommonConfig, EntityConfig, NumericSensorState, constants,
3}; 3};
4 4
5#[derive(Debug, Default, Clone, Copy, PartialEq, Eq)] 5#[derive(Debug, Default, Clone, Copy, PartialEq, Eq)]
@@ -144,36 +144,41 @@ impl SensorClass {
144} 144}
145 145
146#[derive(Debug, Default)] 146#[derive(Debug, Default)]
147pub struct TemperatureSensorConfig { 147pub struct SensorConfig {
148 pub common: EntityCommonConfig, 148 pub common: EntityCommonConfig,
149 pub unit: TemperatureUnit, 149 pub class: SensorClass,
150 pub state_class: StateClass,
151 pub unit: Option<&'static str>,
152 pub suggested_display_precision: Option<u8>,
150} 153}
151 154
152impl TemperatureSensorConfig { 155impl SensorConfig {
153 pub(crate) fn populate(&self, config: &mut EntityConfig) { 156 pub(crate) fn populate(&self, config: &mut EntityConfig) {
154 self.common.populate(config); 157 self.common.populate(config);
155 config.domain = constants::HA_DOMAIN_SENSOR; 158 config.domain = constants::HA_DOMAIN_SENSOR;
156 config.device_class = Some(constants::HA_DEVICE_CLASS_SENSOR_TEMPERATURE); 159 config.device_class = self.class.as_str();
157 config.measurement_unit = Some(self.unit.as_str()); 160 config.state_class = Some(self.state_class.as_str());
161 config.measurement_unit = self.unit;
162 config.suggested_display_precision = self.suggested_display_precision;
158 } 163 }
159} 164}
160 165
161pub struct TemperatureSensor<'a>(Entity<'a>); 166pub struct Sensor<'a>(Entity<'a>);
162 167
163impl<'a> TemperatureSensor<'a> { 168impl<'a> Sensor<'a> {
164 pub(crate) fn new(entity: Entity<'a>) -> Self { 169 pub(crate) fn new(entity: Entity<'a>) -> Self {
165 Self(entity) 170 Self(entity)
166 } 171 }
167 172
168 pub fn publish(&mut self, temperature: f32) { 173 pub fn publish(&mut self, value: f32) {
169 let publish = self.0.with_data(|data| { 174 let publish = self.0.with_data(|data| {
170 let storage = data.storage.as_numeric_sensor_mut(); 175 let storage = data.storage.as_numeric_sensor_mut();
171 let prev_state = storage.state.replace(NumericSensorState { 176 let prev_state = storage.state.replace(NumericSensorState {
172 value: temperature, 177 value,
173 timestamp: embassy_time::Instant::now(), 178 timestamp: embassy_time::Instant::now(),
174 }); 179 });
175 match prev_state { 180 match prev_state {
176 Some(state) => state.value != temperature, 181 Some(state) => state.value != value,
177 None => true, 182 None => true,
178 } 183 }
179 }); 184 });
diff --git a/src/lib.rs b/src/lib.rs
index 1571255..0107116 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -115,6 +115,9 @@ struct EntityDiscovery<'a> {
115 #[serde(skip_serializing_if = "Option::is_none")] 115 #[serde(skip_serializing_if = "Option::is_none")]
116 mode: Option<&'a str>, 116 mode: Option<&'a str>,
117 117
118 #[serde(skip_serializing_if = "Option::is_none")]
119 suggested_display_precision: Option<u8>,
120
118 device: &'a DeviceDiscovery<'a>, 121 device: &'a DeviceDiscovery<'a>,
119} 122}
120 123
@@ -427,11 +430,11 @@ impl<'a> Device<'a> {
427 } 430 }
428 } 431 }
429 432
430 pub fn create_temperature_sensor( 433 pub fn create_sensor(
431 &self, 434 &self,
432 id: &'static str, 435 id: &'static str,
433 config: TemperatureSensorConfig, 436 config: SensorConfig,
434 ) -> TemperatureSensor<'a> { 437 ) -> Sensor<'a> {
435 let mut entity_config = EntityConfig::default(); 438 let mut entity_config = EntityConfig::default();
436 entity_config.id = id; 439 entity_config.id = id;
437 config.populate(&mut entity_config); 440 config.populate(&mut entity_config);
@@ -440,7 +443,7 @@ impl<'a> Device<'a> {
440 entity_config, 443 entity_config,
441 EntityStorage::NumericSensor(Default::default()), 444 EntityStorage::NumericSensor(Default::default()),
442 ); 445 );
443 TemperatureSensor::new(entity) 446 Sensor::new(entity)
444 } 447 }
445 448
446 pub fn create_button(&self, id: &'static str, config: ButtonConfig) -> Button<'a> { 449 pub fn create_button(&self, id: &'static str, config: ButtonConfig) -> Button<'a> {
@@ -573,6 +576,7 @@ impl<'a> Device<'a> {
573 max: entity_config.max, 576 max: entity_config.max,
574 step: entity_config.step, 577 step: entity_config.step,
575 mode: entity_config.mode, 578 mode: entity_config.mode,
579 suggested_display_precision: entity_config.suggested_display_precision,
576 device: &device_discovery, 580 device: &device_discovery,
577 }; 581 };
578 crate::log::debug!( 582 crate::log::debug!(