mirror of
https://github.com/esphome/esphome.git
synced 2025-07-28 14:16:40 +00:00
Reduce memory required for sensor entities (#9201)
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
This commit is contained in:
parent
6d0c6329ad
commit
17497eec43
@ -23,16 +23,22 @@ std::string state_class_to_string(StateClass state_class) {
|
|||||||
Sensor::Sensor() : state(NAN), raw_state(NAN) {}
|
Sensor::Sensor() : state(NAN), raw_state(NAN) {}
|
||||||
|
|
||||||
int8_t Sensor::get_accuracy_decimals() {
|
int8_t Sensor::get_accuracy_decimals() {
|
||||||
if (this->accuracy_decimals_.has_value())
|
if (this->sensor_flags_.has_accuracy_override)
|
||||||
return *this->accuracy_decimals_;
|
return this->accuracy_decimals_;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
void Sensor::set_accuracy_decimals(int8_t accuracy_decimals) { this->accuracy_decimals_ = accuracy_decimals; }
|
void Sensor::set_accuracy_decimals(int8_t accuracy_decimals) {
|
||||||
|
this->accuracy_decimals_ = accuracy_decimals;
|
||||||
|
this->sensor_flags_.has_accuracy_override = true;
|
||||||
|
}
|
||||||
|
|
||||||
void Sensor::set_state_class(StateClass state_class) { this->state_class_ = state_class; }
|
void Sensor::set_state_class(StateClass state_class) {
|
||||||
|
this->state_class_ = state_class;
|
||||||
|
this->sensor_flags_.has_state_class_override = true;
|
||||||
|
}
|
||||||
StateClass Sensor::get_state_class() {
|
StateClass Sensor::get_state_class() {
|
||||||
if (this->state_class_.has_value())
|
if (this->sensor_flags_.has_state_class_override)
|
||||||
return *this->state_class_;
|
return this->state_class_;
|
||||||
return StateClass::STATE_CLASS_NONE;
|
return StateClass::STATE_CLASS_NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -80,9 +80,9 @@ class Sensor : public EntityBase, public EntityBase_DeviceClass, public EntityBa
|
|||||||
* state changes to the database when they are published, even if the state is the
|
* state changes to the database when they are published, even if the state is the
|
||||||
* same as before.
|
* same as before.
|
||||||
*/
|
*/
|
||||||
bool get_force_update() const { return force_update_; }
|
bool get_force_update() const { return sensor_flags_.force_update; }
|
||||||
/// Set force update mode.
|
/// Set force update mode.
|
||||||
void set_force_update(bool force_update) { force_update_ = force_update; }
|
void set_force_update(bool force_update) { sensor_flags_.force_update = force_update; }
|
||||||
|
|
||||||
/// Add a filter to the filter chain. Will be appended to the back.
|
/// Add a filter to the filter chain. Will be appended to the back.
|
||||||
void add_filter(Filter *filter);
|
void add_filter(Filter *filter);
|
||||||
@ -155,9 +155,17 @@ class Sensor : public EntityBase, public EntityBase_DeviceClass, public EntityBa
|
|||||||
|
|
||||||
Filter *filter_list_{nullptr}; ///< Store all active filters.
|
Filter *filter_list_{nullptr}; ///< Store all active filters.
|
||||||
|
|
||||||
optional<int8_t> accuracy_decimals_; ///< Accuracy in decimals override
|
// Group small members together to avoid padding
|
||||||
optional<StateClass> state_class_{STATE_CLASS_NONE}; ///< State class override
|
int8_t accuracy_decimals_{-1}; ///< Accuracy in decimals (-1 = not set)
|
||||||
bool force_update_{false}; ///< Force update mode
|
StateClass state_class_{STATE_CLASS_NONE}; ///< State class (STATE_CLASS_NONE = not set)
|
||||||
|
|
||||||
|
// Bit-packed flags for sensor-specific settings
|
||||||
|
struct SensorFlags {
|
||||||
|
uint8_t has_accuracy_override : 1;
|
||||||
|
uint8_t has_state_class_override : 1;
|
||||||
|
uint8_t force_update : 1;
|
||||||
|
uint8_t reserved : 5; // Reserved for future use
|
||||||
|
} sensor_flags_{};
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace sensor
|
} // namespace sensor
|
||||||
|
@ -8,5 +8,8 @@ sensor:
|
|||||||
name: Test Sensor
|
name: Test Sensor
|
||||||
id: test_sensor
|
id: test_sensor
|
||||||
unit_of_measurement: °C
|
unit_of_measurement: °C
|
||||||
|
accuracy_decimals: 2
|
||||||
|
state_class: measurement
|
||||||
|
force_update: true
|
||||||
lambda: return 42.0;
|
lambda: return 42.0;
|
||||||
update_interval: 0.1s
|
update_interval: 0.1s
|
||||||
|
@ -4,6 +4,7 @@ from __future__ import annotations
|
|||||||
|
|
||||||
import asyncio
|
import asyncio
|
||||||
|
|
||||||
|
import aioesphomeapi
|
||||||
from aioesphomeapi import EntityState
|
from aioesphomeapi import EntityState
|
||||||
import pytest
|
import pytest
|
||||||
|
|
||||||
@ -47,3 +48,23 @@ async def test_host_mode_with_sensor(
|
|||||||
# Verify the sensor state
|
# Verify the sensor state
|
||||||
assert test_sensor_state.state == 42.0
|
assert test_sensor_state.state == 42.0
|
||||||
assert len(states) > 0, "No states received"
|
assert len(states) > 0, "No states received"
|
||||||
|
|
||||||
|
# Verify the optimized fields are working correctly
|
||||||
|
# Get entity info to check accuracy_decimals, state_class, etc.
|
||||||
|
entities, _ = await client.list_entities_services()
|
||||||
|
sensor_info: aioesphomeapi.SensorInfo | None = None
|
||||||
|
for entity in entities:
|
||||||
|
if isinstance(entity, aioesphomeapi.SensorInfo):
|
||||||
|
sensor_info = entity
|
||||||
|
break
|
||||||
|
|
||||||
|
assert sensor_info is not None, "Sensor entity info not found"
|
||||||
|
assert sensor_info.accuracy_decimals == 2, (
|
||||||
|
f"Expected accuracy_decimals=2, got {sensor_info.accuracy_decimals}"
|
||||||
|
)
|
||||||
|
assert sensor_info.state_class == 1, (
|
||||||
|
f"Expected state_class=1 (measurement), got {sensor_info.state_class}"
|
||||||
|
)
|
||||||
|
assert sensor_info.force_update is True, (
|
||||||
|
f"Expected force_update=True, got {sensor_info.force_update}"
|
||||||
|
)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user