oin/oin_thermostat/select.py

101 lines
3.6 KiB
Python
Raw Permalink Normal View History

2024-12-07 15:22:08 +01:00
import logging
import math
2024-12-09 12:16:26 +01:00
from collections.abc import Callable
2024-12-09 13:25:00 +01:00
from typing import Any
2024-12-07 15:22:08 +01:00
2024-12-09 13:25:00 +01:00
from sense_hat.sense_hat import SenseHat
from sense_hat.stick import ACTION_HELD, ACTION_RELEASED, InputEvent
2024-12-07 15:22:08 +01:00
logger = logging.getLogger(__name__)
class Selector:
2024-12-09 15:56:30 +01:00
default_data = {"temperature": None, "mode": None, "switch": None}
2024-12-09 13:25:00 +01:00
def __init__(self, send_data: Callable[[dict[str, Any]], Any]):
2024-12-07 15:22:08 +01:00
self.stick = SenseHat().stick
2024-12-09 13:25:00 +01:00
self.temperature: float | None = None
self.mode: str | None = None
self.switch: bool | None = None
2024-12-09 12:16:26 +01:00
self.preset_modes: list[str] = []
2024-12-07 15:22:08 +01:00
self.send_data = send_data
self.switch_held = False
self.stick.direction_middle = self.toggle
self.stick.direction_up = self.increase_temperature
self.stick.direction_down = self.decrease_temperature
self.stick.direction_right = self.next_mode
self.stick.direction_left = self.prev_mode
@property
2024-12-09 12:16:26 +01:00
def ha_options(self) -> dict[str, dict[str, str]]:
2024-12-07 15:22:08 +01:00
return {
"temperature": {
"p": "sensor",
"value_template": "{{ value_json.temperature }}",
"unique_id": "oin_temp",
"device_class": "temperature",
"entity_category": "diagnostic",
"icon": "mdi:thermostat",
"unit_of_measurement": "°C",
},
"mode": {
"p": "sensor",
"name": "Mode",
"value_template": "{{ value_json.mode }}",
"unique_id": "oin_mode",
"entity_category": "diagnostic",
"icon": "mdi:thermostat-auto",
},
"switch": {
"p": "sensor",
"name": "Switch",
"value_template": "{{ value_json.switch }}",
"unique_id": "oin_switch",
"entity_category": "diagnostic",
"icon": "mdi:thermostat-auto",
},
}
2024-12-09 12:16:26 +01:00
def increase_temperature(self, event: InputEvent) -> None:
2024-12-07 15:22:08 +01:00
if event.action != ACTION_RELEASED and self.temperature is not None:
2024-12-09 12:16:26 +01:00
self.callback({"temperature": math.floor(self.temperature * 2) / 2 + 0.5})
2024-12-07 15:22:08 +01:00
2024-12-09 12:16:26 +01:00
def decrease_temperature(self, event: InputEvent) -> None:
2024-12-07 15:22:08 +01:00
if event.action != ACTION_RELEASED and self.temperature is not None:
2024-12-09 12:16:26 +01:00
self.callback({"temperature": math.ceil(self.temperature * 2) / 2 - 0.5})
2024-12-07 15:22:08 +01:00
2024-12-09 12:16:26 +01:00
def next_mode(self, event: InputEvent) -> None:
2024-12-07 15:22:08 +01:00
if event.action != ACTION_RELEASED and self.mode is not None:
self.callback(
2024-12-09 12:16:26 +01:00
{
"mode": self.preset_modes[
(self.preset_modes.index(self.mode) + 1)
% len(self.preset_modes)
]
}
2024-12-07 15:22:08 +01:00
)
2024-12-09 12:16:26 +01:00
def prev_mode(self, event: InputEvent) -> None:
2024-12-07 15:22:08 +01:00
if event.action != ACTION_RELEASED and self.mode is not None:
self.callback(
2024-12-09 12:16:26 +01:00
{
"mode": self.preset_modes[
(self.preset_modes.index(self.mode) - 1)
% len(self.preset_modes)
]
}
2024-12-07 15:22:08 +01:00
)
2024-12-09 12:16:26 +01:00
def toggle(self, event: InputEvent) -> None:
2024-12-07 15:22:08 +01:00
if not self.switch_held and event.action == ACTION_HELD:
self.switch_held = True
2024-12-09 12:16:26 +01:00
self.callback({"switch": "off" if self.switch else "heat"})
2024-12-07 15:22:08 +01:00
elif self.switch_held and event.action == ACTION_RELEASED:
self.switch_held = False
2024-12-09 13:25:00 +01:00
def callback(self, data: dict[str, Any]) -> None:
2024-12-09 12:16:26 +01:00
self.send_data(self.default_data | data)