Repository navigation
Expand file tree
/
Copy pathtemperature_sync.py
More file actions
83 lines (60 loc) · 2.74 KB
/
Copy pathtemperature_sync.py
File metadata and controls
83 lines (60 loc) · 2.74 KB
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
"""TemperatureSync app: synchronize a source temperature sensor to multiple target entities.
Main features:
- Mirror a numeric temperature sensor to one or more `number` entities or setpoint controls.
- Validate numeric input and ignore invalid sensor states.
Key configuration keys:
- input: entity id of the source temperature sensor (required).
- outputs: list of target entity ids to set (e.g., number.setpoint_*).
Example:
```yaml
temperature_sync:
module: temperature_sync
class: TemperatureSync
input: sensor.temperature_outside
outputs:
- number.setpoint_living
- number.setpoint_bedroom
```
See module docstring and inline examples for usage.
"""
import inspect
import appdaemon.plugins.hass.hassapi as hass
class TemperatureSync(hass.Hass):
def initialize(self):
"""Initialize TemperatureSync: register input listener and schedule periodic sync.
Reads configured input/output entities from args and ensures the sync
runs on changes and periodically.
"""
self.log("Hello from TemperatureSync")
self._input = self.args.get("input")
self._outputs = self.args.get("outputs", [])
self.listen_state(self.sensor_change_callback, self._input)
# Set start time to now, aligning to the next full 10-minute mark
self.run_every(self.periodic_time_callback, "now+10", 10 * 60)
def periodic_time_callback(self, kwargs):
"""Timer callback to periodically synchronize the temperature.
Args:
kwargs (dict): timer kwargs from AppDaemon (ignored).
"""
self.log(f"{inspect.currentframe().f_code.co_name}")
self.sync_temperature()
def sensor_change_callback(self, entity, attribute, old, new, kwargs):
"""State change callback for the source temperature sensor.
Invokes `sync_temperature` to mirror the latest numeric value to outputs.
"""
self.log(f"{self.__class__.__name__}.{inspect.currentframe().f_code.co_name} from {entity}:{attribute} {old}->{new}")
self.sync_temperature()
def sync_temperature(self):
"""Read the source temperature and set configured outputs to the numeric value.
Invalid or non-numeric input values are logged and ignored.
"""
temperature = self.get_state(self._input)
try:
numeric_value = float(temperature)
# Proceed with numeric_value
except (TypeError, ValueError):
self.error(f"Ignoring invalid temperature value: {temperature}")
return
for entity_id in self._outputs:
self.log(f"[{entity_id}] Setting number value to {numeric_value}")
self.call_service("number/set_value", entity_id=entity_id, value=numeric_value)