-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
8f32b13
commit 075b8b7
Showing
26 changed files
with
3,534 additions
and
834 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,4 @@ | ||
README.md | ||
.DS_Store | ||
custom_components/ithodaalderop/__pycache__ | ||
*.pyc |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,112 @@ | ||
"""Sensor class for handling Autotemp sensors.""" | ||
|
||
import json | ||
|
||
from homeassistant.components import mqtt | ||
from homeassistant.config_entries import ConfigEntry | ||
from homeassistant.core import callback | ||
from homeassistant.helpers.device_registry import DeviceInfo | ||
|
||
from ._sensor_base import IthoBaseSensor | ||
from .const import ( | ||
ADDON_TYPES, | ||
AUTOTEMP_ERROR, | ||
AUTOTEMP_MODE, | ||
CONF_ADDON_TYPE, | ||
DOMAIN, | ||
MANUFACTURER, | ||
) | ||
from .definitions.base import IthoSensorEntityDescription | ||
|
||
|
||
class IthoSensorAutotemp(IthoBaseSensor): | ||
"""Representation of Itho add-on sensor for Autotemp data that is updated via MQTT.""" | ||
|
||
def __init__( | ||
self, | ||
description: IthoSensorEntityDescription, | ||
config_entry: ConfigEntry, | ||
) -> None: | ||
"""Construct sensor for Autotemp.""" | ||
super().__init__(description, config_entry) | ||
|
||
async def async_added_to_hass(self) -> None: | ||
"""Subscribe to MQTT events.""" | ||
|
||
@callback | ||
def message_received(message): | ||
"""Handle new MQTT messages.""" | ||
payload = json.loads(message.payload) | ||
json_field = self.entity_description.json_field | ||
if json_field not in payload: | ||
value = None | ||
else: | ||
value = payload[json_field] | ||
if json_field == "Error": | ||
self._extra_state_attributes = { | ||
"Code": value, | ||
} | ||
value = AUTOTEMP_ERROR.get(value, "Unknown error") | ||
|
||
if json_field == "Mode": | ||
self._extra_state_attributes = { | ||
"Code": value, | ||
} | ||
value = AUTOTEMP_MODE.get(value, "Unknown mode") | ||
|
||
if json_field == "State off": | ||
if value == 1: | ||
value = "Off" | ||
if payload["State cool"] == 1: | ||
value = "Cooling" | ||
if payload["State heating"] == 1: | ||
value = "Heating" | ||
if payload["state hand"] == 1: | ||
value = "Hand" | ||
|
||
self._attr_native_value = value | ||
self.async_write_ha_state() | ||
|
||
await mqtt.async_subscribe( | ||
self.hass, self.entity_description.key, message_received, 1 | ||
) | ||
|
||
|
||
class IthoSensorAutotempRoom(IthoBaseSensor): | ||
"""Representation of Itho add-on room sensor for Autotemp data that is updated via MQTT.""" | ||
|
||
def __init__( | ||
self, description: IthoSensorEntityDescription, config_entry: ConfigEntry | ||
) -> None: | ||
"""Construct sensor for Autotemp.""" | ||
|
||
self._attr_device_info = DeviceInfo( | ||
identifiers={ | ||
( | ||
DOMAIN, | ||
f"{config_entry.data[CONF_ADDON_TYPE]}_room_{description.room.lower()}", | ||
) | ||
}, | ||
manufacturer=MANUFACTURER, | ||
model=f"{ADDON_TYPES[config_entry.data[CONF_ADDON_TYPE]]} Spider", | ||
name=f"Spider {description.room.capitalize()}", | ||
via_device=(DOMAIN, config_entry.data[CONF_ADDON_TYPE]), | ||
) | ||
|
||
super().__init__(description, config_entry, use_base_sensor_device=False) | ||
|
||
async def async_added_to_hass(self) -> None: | ||
"""Subscribe to MQTT events.""" | ||
|
||
@callback | ||
def message_received(message): | ||
"""Handle new MQTT messages.""" | ||
payload = json.loads(message.payload) | ||
value = payload.get(self.entity_description.json_field, None) | ||
|
||
self._attr_native_value = value | ||
self.async_write_ha_state() | ||
|
||
await mqtt.async_subscribe( | ||
self.hass, self.entity_description.key, message_received, 1 | ||
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,64 @@ | ||
"""Sensor base class.""" | ||
|
||
from homeassistant.components.sensor import SensorEntity | ||
from homeassistant.config_entries import ConfigEntry | ||
from homeassistant.helpers.device_registry import DeviceInfo | ||
|
||
from .const import ( | ||
ADDON_TYPES, | ||
CONF_ADDON_TYPE, | ||
CONF_NONCVE_MODEL, | ||
DOMAIN, | ||
MANUFACTURER, | ||
NONCVE_DEVICES, | ||
UNITTYPE_ICONS, | ||
) | ||
from .definitions.base import IthoSensorEntityDescription | ||
|
||
|
||
class IthoBaseSensor(SensorEntity): | ||
"""Base class sharing foundation for WPU, remotes and Fans.""" | ||
|
||
_attr_has_entity_name = True | ||
entity_description: IthoSensorEntityDescription | ||
|
||
_extra_state_attributes = None | ||
|
||
def __init__( | ||
self, | ||
description: IthoSensorEntityDescription, | ||
config_entry: ConfigEntry, | ||
use_base_sensor_device: bool = True, | ||
) -> None: | ||
"""Initialize the sensor.""" | ||
self.entity_description = description | ||
|
||
if use_base_sensor_device: | ||
model = ADDON_TYPES[config_entry.data[CONF_ADDON_TYPE]] | ||
if config_entry.data[CONF_ADDON_TYPE] == "noncve": | ||
model = ( | ||
model + " - " + NONCVE_DEVICES[config_entry.data[CONF_NONCVE_MODEL]] | ||
) | ||
|
||
self._attr_device_info = DeviceInfo( | ||
identifiers={(DOMAIN, config_entry.data[CONF_ADDON_TYPE])}, | ||
manufacturer=MANUFACTURER, | ||
model=model, | ||
name=ADDON_TYPES[config_entry.data[CONF_ADDON_TYPE]], | ||
) | ||
|
||
if description.unique_id is not None: | ||
self._attr_unique_id = f"itho_{ADDON_TYPES[config_entry.data[CONF_ADDON_TYPE]]}_{description.unique_id.lower()}" | ||
else: | ||
self._attr_unique_id = f"itho_{ADDON_TYPES[config_entry.data[CONF_ADDON_TYPE]]}_{description.translation_key}" | ||
self.entity_id = f"sensor.{self._attr_unique_id}" | ||
|
||
@property | ||
def icon(self) -> str | None: | ||
"""Pick the right icon.""" | ||
|
||
if self.entity_description.icon is not None: | ||
return self.entity_description.icon | ||
if self.entity_description.native_unit_of_measurement in UNITTYPE_ICONS: | ||
return UNITTYPE_ICONS[self.entity_description.native_unit_of_measurement] | ||
return None |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,43 @@ | ||
"""Sensor class for handling CO2 Remote sensors.""" | ||
|
||
import json | ||
|
||
from homeassistant.components import mqtt | ||
from homeassistant.config_entries import ConfigEntry | ||
from homeassistant.core import callback | ||
|
||
from ._sensor_base import IthoBaseSensor | ||
from .const import ADDON_TYPES, CONF_ADDON_TYPE | ||
Check failure on line 10 in custom_components/ithodaalderop/_sensor_co2_remote.py GitHub Actions / buildRuff (F401)
|
||
from .definitions.base import IthoSensorEntityDescription | ||
|
||
|
||
class IthoSensorCO2Remote(IthoBaseSensor): | ||
"""Representation of Itho add-on sensor for a Remote that is updated via MQTT.""" | ||
|
||
def __init__( | ||
self, | ||
description: IthoSensorEntityDescription, | ||
config_entry: ConfigEntry, | ||
) -> None: | ||
"""Construct sensor for Remote.""" | ||
super().__init__(description, config_entry) | ||
|
||
async def async_added_to_hass(self) -> None: | ||
"""Subscribe to MQTT events.""" | ||
|
||
@callback | ||
def message_received(message): | ||
"""Handle new MQTT messages.""" | ||
payload = json.loads(message.payload) | ||
json_field = self.entity_description.json_field | ||
if json_field not in payload: | ||
value = None | ||
else: | ||
value = payload[json_field]["co2"] | ||
|
||
self._attr_native_value = value | ||
self.async_write_ha_state() | ||
|
||
await mqtt.async_subscribe( | ||
self.hass, self.entity_description.key, message_received, 1 | ||
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,142 @@ | ||
"""Sensor class for handling Fan sensors.""" | ||
|
||
from datetime import datetime, timedelta | ||
import json | ||
|
||
from homeassistant.components import mqtt | ||
from homeassistant.config_entries import ConfigEntry | ||
from homeassistant.core import callback | ||
|
||
from ._sensor_base import IthoBaseSensor | ||
from .const import ( | ||
HRU_ECO_250_300_ERROR_CODE, | ||
HRU_ECO_350_ACTUAL_MODE, | ||
HRU_ECO_350_GLOBAL_FAULT_CODE, | ||
HRU_ECO_350_RH_ERROR_CODE, | ||
HRU_ECO_STATUS, | ||
) | ||
from .definitions.base import IthoSensorEntityDescription | ||
|
||
|
||
class IthoSensorFan(IthoBaseSensor): | ||
"""Representation of a Itho add-on sensor that is updated via MQTT.""" | ||
|
||
_attr_has_entity_name = True | ||
entity_description: IthoSensorEntityDescription | ||
|
||
_extra_state_attributes = None | ||
|
||
def __init__( | ||
self, | ||
description: IthoSensorEntityDescription, | ||
config_entry: ConfigEntry, | ||
) -> None: | ||
"""Initialize the sensor.""" | ||
super().__init__(description, config_entry) | ||
|
||
@property | ||
def extra_state_attributes(self) -> list[str] | None: | ||
"""Return the state attributes.""" | ||
return self._extra_state_attributes | ||
|
||
async def async_added_to_hass(self) -> None: | ||
"""Subscribe to MQTT events.""" | ||
|
||
@callback | ||
def message_received(message): | ||
"""Handle new MQTT messages.""" | ||
payload = json.loads(message.payload) | ||
json_field = self.entity_description.json_field | ||
if json_field not in payload: | ||
value = None | ||
else: | ||
value = payload[json_field] | ||
# HRU ECO 350 | ||
if json_field == "Actual Mode": | ||
self._extra_state_attributes = {"Code": value} | ||
value = HRU_ECO_350_ACTUAL_MODE.get(value, "Unknown mode") | ||
|
||
# HRU ECO 350 | ||
if json_field == "Air Quality (%)": | ||
_error_description = "Unknown error code" | ||
if isinstance(value, (int, float)) and float(value) > 100: | ||
_error_description = "Unknown error" | ||
value = None | ||
|
||
self._extra_state_attributes = { | ||
"Error Description": _error_description, | ||
} | ||
|
||
# HRU ECO 350 / HRU ECO | ||
if json_field in ["Airfilter counter", "Air filter counter"]: | ||
_last_maintenance = "" | ||
_next_maintenance_estimate = "" | ||
if str(value).isnumeric(): | ||
_last_maintenance = ( | ||
datetime.now() - timedelta(hours=int(value)) | ||
).date() | ||
_next_maintenance_estimate = ( | ||
datetime.now() + timedelta(days=180, hours=-int(value)) | ||
).date() | ||
else: | ||
_last_maintenance = "Invalid value" | ||
|
||
self._extra_state_attributes = { | ||
"Last Maintenance": _last_maintenance, | ||
"Next Maintenance Estimate": _next_maintenance_estimate, | ||
} | ||
|
||
# HRU ECO 250/300 | ||
if json_field == "Error number": | ||
_description = "" | ||
if str(value).isnumeric(): | ||
_error_description = HRU_ECO_250_300_ERROR_CODE.get( | ||
int(value), _description | ||
) | ||
|
||
self._extra_state_attributes = { | ||
"Description": _description, | ||
} | ||
|
||
# HRU ECO 350 | ||
if json_field == "Global fault code": | ||
_description = "Unknown fault code" | ||
if str(value).isnumeric(): | ||
_description = HRU_ECO_350_GLOBAL_FAULT_CODE.get( | ||
int(value), _description | ||
) | ||
|
||
self._extra_state_attributes = { | ||
"Description": _description, | ||
} | ||
|
||
# HRU ECO 350 | ||
if json_field == "Highest received RH value (%RH)": | ||
_error_description = "" | ||
if isinstance(value, (int, float)) and float(value) > 100: | ||
_error_description = HRU_ECO_350_RH_ERROR_CODE.get( | ||
int(value), "Unknown error" | ||
) | ||
value = None | ||
|
||
self._extra_state_attributes = { | ||
"Error Description": _error_description, | ||
} | ||
|
||
# HRU ECO | ||
if json_field == "Status": | ||
self._extra_state_attributes = { | ||
"Code": value, | ||
} | ||
|
||
_description = "Unknown status" | ||
if str(value).isnumeric(): | ||
_description = HRU_ECO_STATUS.get(int(value), _description) | ||
value = _description | ||
|
||
self._attr_native_value = value | ||
self.async_write_ha_state() | ||
|
||
await mqtt.async_subscribe( | ||
self.hass, self.entity_description.key, message_received, 1 | ||
) |
Oops, something went wrong.