Skip to content

Commit

Permalink
Initial support for some vent sensors.
Browse files Browse the repository at this point in the history
  • Loading branch information
StephanU committed Dec 5, 2023
1 parent 7b5f4bf commit b37a1fc
Show file tree
Hide file tree
Showing 5 changed files with 246 additions and 10 deletions.
62 changes: 56 additions & 6 deletions custom_components/mygekko/climate.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
"""Climate platform for MyGekko."""
from math import ceil

from homeassistant.components.climate import ATTR_TEMPERATURE
from homeassistant.components.climate import ClimateEntity
from homeassistant.components.climate import ClimateEntityFeature
Expand All @@ -8,6 +10,8 @@
from PyMyGekko.resources.RoomTemps import RoomTemp
from PyMyGekko.resources.RoomTemps import RoomTempsFeature
from PyMyGekko.resources.RoomTemps import RoomTempsMode
from PyMyGekko.resources.vents import Vent
from PyMyGekko.resources.vents import VentOperatingMode

from .const import DOMAIN
from .entity import MyGekkoEntity
Expand All @@ -16,14 +20,18 @@
async def async_setup_entry(hass, entry, async_add_devices):
"""Setup cover platform."""
coordinator = hass.data[DOMAIN][entry.entry_id]
room_temps = coordinator.api.get_room_temps()
if room_temps is not None:
async_add_devices(
MyGekkoClimate(coordinator, room_temp) for room_temp in room_temps
)

async_add_devices(
MyGekkoRoomTempClimate(coordinator, room_temp)
for room_temp in coordinator.api.get_room_temps()
)

# async_add_devices(
# MyGekkoVentClimate(coordinator, vent) for vent in coordinator.api.get_vents()
# )


class MyGekkoClimate(MyGekkoEntity, ClimateEntity):
class MyGekkoRoomTempClimate(MyGekkoEntity, ClimateEntity):
"""mygekko Climate class."""

_attr_temperature_unit = UnitOfTemperature.CELSIUS
Expand Down Expand Up @@ -72,3 +80,45 @@ async def async_set_hvac_mode(self, hvac_mode: HVACMode) -> None:
await self._room_temp.set_working_mode(RoomTempsMode.OFF)
else:
await self._room_temp.set_working_mode(RoomTempsMode.COMFORT)


class MyGekkoVentClimate(MyGekkoEntity, ClimateEntity):
"""mygekko Climate class."""

_attr_temperature_unit = UnitOfTemperature.CELSIUS
_attr_preset_modes = ["Comfort", "Reduced", "Manual", "Standby"]

def __init__(self, coordinator, vent: Vent):
super().__init__(coordinator, vent, "vents")
self._vent = vent
supported_features = self._vent.supported_features
self._attr_supported_features = 0
self._attr_hvac_modes = [HVACMode.OFF, HVACMode.AUTO]

if RoomTempsFeature.TARGET_TEMPERATURE in supported_features:
self._attr_supported_features |= ClimateEntityFeature.TARGET_TEMPERATURE

@callback
def _handle_coordinator_update(self) -> None:
"""Handle updated data from the coordinator."""
self.async_write_ha_state()

@property
def current_humidity(self) -> int | None:
"""Return the current humidity."""
return ceil(self._vent.relative_humidity)

@property
def hvac_mode(self) -> HVACMode | str | None:
"""Return hvac operation ie. heat, cool mode."""
if self._vent.operating_mode == VentOperatingMode.MANUAL:
return HVACMode.OFF
else:
return HVACMode.AUTO

async def async_set_hvac_mode(self, hvac_mode: HVACMode) -> None:
"""Set new target hvac mode."""
if hvac_mode == HVACMode.OFF:
await self._vent.set_operating_mode(VentOperatingMode.MANUAL)
else:
await self._vent.set_operating_mode(VentOperatingMode.AUTO)
2 changes: 1 addition & 1 deletion custom_components/mygekko/light.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
async def async_setup_entry(hass, entry, async_add_devices):
"""Setup light platform."""
coordinator = hass.data[DOMAIN][entry.entry_id]
lights = coordinator.api.get_lights()
lights: list[Light] = coordinator.api.get_lights()
if lights is not None:
async_add_devices(
MyGekkoLight(coordinator, light)
Expand Down
2 changes: 1 addition & 1 deletion custom_components/mygekko/manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,6 @@
"iot_class": "cloud_polling",
"issue_tracker": "https://github.com/stephanu/mygekko/issues",
"loggers": ["PyMyGekko"],
"requirements": ["PyMyGekko==1.1.0rc1"],
"requirements": ["PyMyGekko==1.1.0rc2"],
"version": "1.0.0"
}
188 changes: 187 additions & 1 deletion custom_components/mygekko/sensor.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@
from PyMyGekko.resources.HotWaterSystems import HotWaterSystemFeature
from PyMyGekko.resources.RoomTemps import RoomTemp
from PyMyGekko.resources.RoomTemps import RoomTempsFeature
from PyMyGekko.resources.vents import Vent
from PyMyGekko.resources.vents import VentFeature

from .const import DOMAIN

Expand Down Expand Up @@ -104,10 +106,22 @@
state_class=SensorStateClass.TOTAL,
device_class=SensorDeviceClass.ENERGY,
),
SensorEntityDescription(
key="voc",
name="VOC",
state_class=SensorStateClass.MEASUREMENT,
device_class=SensorDeviceClass.VOLATILE_ORGANIC_COMPOUNDS_PARTS,
),
SensorEntityDescription(
key="air_quality",
name="Air Quality",
state_class=SensorStateClass.MEASUREMENT,
device_class=SensorDeviceClass.AQI,
),
SensorEntityDescription(
key="co2",
name="CO2",
state_class=SensorStateClass.MEASUREMENT,
device_class=SensorDeviceClass.CO2,
),
SensorEntityDescription(
Expand Down Expand Up @@ -193,6 +207,25 @@ async def async_setup_entry(hass, entry, async_add_devices):
)
]
)
vents: list[Vent] = coordinator.api.get_vents()
for vent in vents:
if VentFeature.HUMIDITY in vent.supported_features:
async_add_devices([MyGekkoVentHumiditySensor(coordinator, vent)])
if VentFeature.AIR_QUALITY in vent.supported_features:
async_add_devices([MyGekkoVentAirQualitySensor(coordinator, vent)])
if VentFeature.CO2 in vent.supported_features:
async_add_devices([MyGekkoVentCo2Sensor(coordinator, vent)])

async_add_devices(
[
MyGekkoVentExhaustAirTemperatureSensor(coordinator, vent),
MyGekkoVentOutgoingAirTemperatureSensor(coordinator, vent),
MyGekkoVentOutsideAirTemperatureSensor(coordinator, vent),
MyGekkoVentSupplyAirTemperatureSensor(coordinator, vent),
MyGekkoVentSupplyAirWorkingLevelSensor(coordinator, vent),
MyGekkoVentExhaustAirWorkingLevelSensor(coordinator, vent),
]
)


class MyGekkoAlarmsLogicsSensor(MyGekkoControllerEntity, SensorEntity):
Expand Down Expand Up @@ -272,7 +305,7 @@ class MyGekkoRoomTempsAirQualitySensor(MyGekkoEntity, SensorEntity):
def __init__(self, coordinator, room_temp: RoomTemp):
super().__init__(coordinator, room_temp, "room_temps", "Air Quality")
self._room_temp = room_temp
self.entity_description = SENSORS["air_quality"]
self.entity_description = SENSORS["voc"]

@property
def native_value(self):
Expand Down Expand Up @@ -316,3 +349,156 @@ def __init__(self, coordinator, hotwater_system: HotWaterSystem):
def native_value(self):
"""Return the state of the sensor."""
return self._hotwater_system.current_temperature_top


class MyGekkoVentHumiditySensor(MyGekkoEntity, SensorEntity):
"""mygekko Vent Humidity Sensor class."""

_attr_has_entity_name = True
_attr_native_unit_of_measurement = PERCENTAGE

def __init__(self, coordinator, vent: Vent):
super().__init__(coordinator, vent, "vents", "Humidity")
self._vent = vent
self.entity_description = SENSORS["humidity"]

@property
def native_value(self):
"""Return the state of the sensor."""
return self._vent.relative_humidity


class MyGekkoVentAirQualitySensor(MyGekkoEntity, SensorEntity):
"""mygekko Vent Air Quality Sensor class."""

_attr_has_entity_name = True
_attr_native_unit_of_measurement = PERCENTAGE

def __init__(self, coordinator, vent: Vent):
super().__init__(coordinator, vent, "vents", "Air Quality")
self._vent = vent
self.entity_description = SENSORS["air_quality"]

@property
def native_value(self):
"""Return the state of the sensor."""
return self._vent.air_quality


class MyGekkoVentCo2Sensor(MyGekkoEntity, SensorEntity):
"""mygekko Vent CO2 Sensor class."""

_attr_has_entity_name = True
_attr_native_unit_of_measurement = CONCENTRATION_PARTS_PER_MILLION

def __init__(self, coordinator, vent: Vent):
super().__init__(coordinator, vent, "vents", "CO2")
self._vent = vent
self.entity_description = SENSORS["co2"]

@property
def native_value(self):
"""Return the state of the sensor."""
return self._vent.co2


class MyGekkoVentExhaustAirTemperatureSensor(MyGekkoEntity, SensorEntity):
"""mygekko Top Temperature Sensor class."""

_attr_has_entity_name = True
_attr_native_unit_of_measurement = UnitOfTemperature.CELSIUS

def __init__(self, coordinator, vent: Vent):
super().__init__(coordinator, vent, "vents", "Exhaust Air Temperature")
self._vent = vent
self.entity_description = SENSORS["temperature"]

@property
def native_value(self):
"""Return the state of the sensor."""
return self._vent.exhaust_air_temperature


class MyGekkoVentExhaustAirWorkingLevelSensor(MyGekkoEntity, SensorEntity):
"""mygekko Top Temperature Sensor class."""

_attr_has_entity_name = True
_attr_native_unit_of_measurement = PERCENTAGE
_attr_icon = "mdi:gauge"

def __init__(self, coordinator, vent: Vent):
super().__init__(coordinator, vent, "vents", "Exhaust Air Working Level")
self._vent = vent

@property
def native_value(self):
"""Return the state of the sensor."""
return self._vent.exhaust_air_working_level


class MyGekkoVentOutgoingAirTemperatureSensor(MyGekkoEntity, SensorEntity):
"""mygekko Top Temperature Sensor class."""

_attr_has_entity_name = True
_attr_native_unit_of_measurement = UnitOfTemperature.CELSIUS

def __init__(self, coordinator, vent: Vent):
super().__init__(coordinator, vent, "vents", "Outgoing Air Temperature")
self._vent = vent
self.entity_description = SENSORS["temperature"]

@property
def native_value(self):
"""Return the state of the sensor."""
return self._vent.outgoing_air_temperature


class MyGekkoVentOutsideAirTemperatureSensor(MyGekkoEntity, SensorEntity):
"""mygekko Top Temperature Sensor class."""

_attr_has_entity_name = True
_attr_native_unit_of_measurement = UnitOfTemperature.CELSIUS

def __init__(self, coordinator, vent: Vent):
super().__init__(coordinator, vent, "vents", "Outside Air Temperature")
self._vent = vent
self.entity_description = SENSORS["temperature"]

@property
def native_value(self):
"""Return the state of the sensor."""
return self._vent.outside_air_temperature


class MyGekkoVentSupplyAirTemperatureSensor(MyGekkoEntity, SensorEntity):
"""mygekko Top Temperature Sensor class."""

_attr_has_entity_name = True
_attr_native_unit_of_measurement = UnitOfTemperature.CELSIUS

def __init__(self, coordinator, vent: Vent):
super().__init__(coordinator, vent, "vents", "Supply Air Temperature")
self._vent = vent
self.entity_description = SENSORS["temperature"]

@property
def native_value(self):
"""Return the state of the sensor."""
return self._vent.supply_air_temperature


class MyGekkoVentSupplyAirWorkingLevelSensor(MyGekkoEntity, SensorEntity):
"""mygekko Supply Air Working Level class."""

_attr_has_entity_name = True
_attr_native_unit_of_measurement = PERCENTAGE
_attr_icon = "mdi:gauge"

def __init__(self, coordinator, vent: Vent):
super().__init__(coordinator, vent, "vents", "Supply Air Working Level")
self._vent = vent

@property
def native_value(self):
"""Return the state of the sensor."""
return self._vent.supply_air_working_level
2 changes: 1 addition & 1 deletion requirements_test.txt
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
-r requirements_dev.txt
pytest-asyncio
pytest-homeassistant-custom-component==0.13.79
PyMyGekko==1.1.0rc1
PyMyGekko==1.1.0rc2

0 comments on commit b37a1fc

Please sign in to comment.