Skip to content

Commit

Permalink
Updated dependency to new PyMyGekko lib.
Browse files Browse the repository at this point in the history
Added mygekko actions as scenes.
  • Loading branch information
StephanU committed Nov 20, 2023
1 parent dadc00c commit 3cd9f67
Show file tree
Hide file tree
Showing 11 changed files with 117 additions and 69 deletions.
34 changes: 17 additions & 17 deletions custom_components/mygekko/climate.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,9 @@
from homeassistant.components.climate import HVACMode
from homeassistant.const import UnitOfTemperature
from homeassistant.core import callback
from PyMyGekko.resources.Thermostats import Thermostat
from PyMyGekko.resources.Thermostats import ThermostatFeature
from PyMyGekko.resources.Thermostats import ThermostatMode
from PyMyGekko.resources.RoomTemps import RoomTemp
from PyMyGekko.resources.RoomTemps import RoomTempsFeature
from PyMyGekko.resources.RoomTemps import RoomTempsMode

from .const import CLIMATE
from .const import DOMAIN
Expand All @@ -17,10 +17,10 @@
async def async_setup_entry(hass, entry, async_add_devices):
"""Setup cover platform."""
coordinator = hass.data[DOMAIN][entry.entry_id]
thermostats = coordinator.api.get_thermostats()
if thermostats is not None:
room_temps = coordinator.api.get_room_temps()
if room_temps is not None:
async_add_devices(
MyGekkoClimate(coordinator, thermostat) for thermostat in thermostats
MyGekkoClimate(coordinator, room_temp) for room_temp in room_temps
)


Expand All @@ -30,14 +30,14 @@ class MyGekkoClimate(MyGekkoEntity, ClimateEntity):
_attr_temperature_unit = UnitOfTemperature.CELSIUS
_attr_preset_modes = ["Comfort", "Reduced", "Manual", "Standby"]

def __init__(self, coordinator, thermostat: Thermostat):
super().__init__(coordinator, thermostat, CLIMATE)
self._thermostat = thermostat
supported_features = self._thermostat.supported_features
def __init__(self, coordinator, room_temp: RoomTemp):
super().__init__(coordinator, room_temp, CLIMATE)
self._room_temp = room_temp
supported_features = self._room_temp.supported_features
self._attr_supported_features = 0
self._attr_hvac_modes = [HVACMode.OFF, HVACMode.AUTO]

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

@callback
Expand All @@ -48,28 +48,28 @@ def _handle_coordinator_update(self) -> None:
@property
def current_temperature(self) -> float | None:
"""Return the current temperature."""
return self._thermostat.current_temperature
return self._room_temp.current_temperature

@property
def target_temperature(self) -> float | None:
"""Return the temperature we try to reach."""
return self._thermostat.target_temperature
return self._room_temp.target_temperature

async def async_set_temperature(self, **kwargs) -> None:
"""Set new target temperature."""
await self._thermostat.set_target_temperature(float(kwargs[ATTR_TEMPERATURE]))
await self._room_temp.set_target_temperature(float(kwargs[ATTR_TEMPERATURE]))

@property
def hvac_mode(self) -> HVACMode | str | None:
"""Return hvac operation ie. heat, cool mode."""
if self._thermostat.mode == ThermostatMode.Off:
if self._room_temp.working_mode == RoomTempsMode.Off:
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._thermostat.set_mode(ThermostatMode.Off)
await self._room_temp.set_working_mode(RoomTempsMode.Off)
else:
await self._thermostat.set_mode(ThermostatMode.Comfort)
await self._room_temp.set_working_mode(RoomTempsMode.Comfort)
5 changes: 3 additions & 2 deletions custom_components/mygekko/const.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
NAME = "MyGekko"
DOMAIN = "mygekko"
DOMAIN_DATA = f"{DOMAIN}_data"
VERSION = "0.0.32"
VERSION = "0.0.33"

ATTRIBUTION = "Data provided by http://jsonplaceholder.typicode.com/"
ISSUE_URL = "https://github.com/stephanu/mygekko/issues"
Expand All @@ -18,8 +18,9 @@
LIGHT = "light"
CLIMATE = "climate"
SWITCH = "switch"
SCENE = "scene"
WATER_HEATER = "water_heater"
PLATFORMS = [COVER, LIGHT, CLIMATE, SWITCH, WATER_HEATER]
PLATFORMS = [COVER, LIGHT, CLIMATE, SWITCH, SCENE, WATER_HEATER]


# Configuration and options
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",
"logger": ["PyMyGekko"],
"requirements": ["pymygekko==0.0.5rc4"],
"requirements": ["pymygekko==0.0.5rc5"],
"version": "1.0.0"
}
35 changes: 35 additions & 0 deletions custom_components/mygekko/scene.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
"""Scene platform for MyGekko."""
from typing import Any

from homeassistant.components.scene import Scene
from homeassistant.core import callback
from PyMyGekko.resources.Actions import Action
from PyMyGekko.resources.Actions import ActionState

from .const import DOMAIN
from .const import SCENE
from .entity import MyGekkoEntity


async def async_setup_entry(hass, entry, async_add_devices):
"""Setup scene platform."""
coordinator = hass.data[DOMAIN][entry.entry_id]
actions = coordinator.api.get_actions()
if actions is not None:
async_add_devices(MyGekkoScene(coordinator, action) for action in actions)


class MyGekkoScene(MyGekkoEntity, Scene):
"""mygekko Scene class."""

def __init__(self, coordinator, action: Action):
super().__init__(coordinator, action, SCENE)
self._action = action

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

async def activate(self, **kwargs: Any) -> None:
await self._action.set_state(ActionState.ON)
28 changes: 15 additions & 13 deletions custom_components/mygekko/sensor.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,8 @@
from homeassistant.components.sensor import SensorEntity
from homeassistant.components.sensor import SensorEntityDescription
from homeassistant.components.sensor import SensorStateClass
from PyMyGekko.resources.EnergyMeters import EnergyMeter
from PyMyGekko.resources.EnergyCosts import EnergyCost

from .const import DEFAULT_NAME
from .const import DOMAIN
from .const import ICON
from .const import SENSOR
Expand All @@ -30,32 +29,35 @@
async def async_setup_entry(hass, entry, async_add_devices):
"""Setup sensor platform."""
coordinator = hass.data[DOMAIN][entry.entry_id]
energy_meters: list[EnergyMeter] = coordinator.api.get_energy_meters()
if energy_meters is not None:
for energy_meter in energy_meters:
if energy_meter.sensor_data and "values" in energy_meter.sensor_data:
for sensor in energy_meter.sensor_data["values"]:
async_add_devices(MyGekkoSensor(coordinator, sensor))
energy_costs: list[EnergyCost] = coordinator.api.get_energy_costs()
if energy_costs is not None:
for energy_cost in energy_costs:
if energy_cost.sensor_data and "values" in energy_cost.sensor_data:
async_add_devices(
MyGekkoSensor(coordinator, energy_cost, sensor)
for sensor in energy_cost.sensor_data["values"]
)


class MyGekkoSensor(MyGekkoEntity, SensorEntity):
"""mygekko Sensor class."""

def __init__(self, coordinator, energy_meter: EnergyMeter):
super().__init__(coordinator, energy_meter, SENSOR)
self._energy_meter = energy_meter
def __init__(self, coordinator, energy_cost: EnergyCost, sensor_data):
super().__init__(coordinator, energy_cost, SENSOR)
self._energy_cost = energy_cost
self._sensor_data = sensor_data
# supported_features = self._blind.supported_features
self._attr_supported_features = 0

@property
def name(self):
"""Return the name of the sensor."""
return f"{DEFAULT_NAME}_{SENSOR}"
return self._sensor_data["name"]

@property
def state(self):
"""Return the state of the sensor."""
return self.coordinator.data.get("body")
return self._sensor_data["value"]

@property
def icon(self):
Expand Down
26 changes: 15 additions & 11 deletions custom_components/mygekko/switch.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
"""Switch platform for MyGekko."""
from homeassistant.components.switch import SwitchEntity
from homeassistant.core import callback
from PyMyGekko.resources.Switches import Switch
from PyMyGekko.resources.Switches import SwitchState
from PyMyGekko.resources.Loads import Load
from PyMyGekko.resources.Loads import LoadState

from .const import DOMAIN
from .const import SWITCH
Expand All @@ -12,28 +12,32 @@
async def async_setup_entry(hass, entry, async_add_devices):
"""Setup switch platform."""
coordinator = hass.data[DOMAIN][entry.entry_id]
switches = coordinator.api.get_switches()
if switches is not None:
async_add_devices(MyGekkoSwitch(coordinator, switch) for switch in switches)
loads = coordinator.api.get_loads()
if loads is not None:
async_add_devices(MyGekkoSwitch(coordinator, load) for load in loads)


class MyGekkoSwitch(MyGekkoEntity, SwitchEntity):
"""mygekko Switch class."""

def __init__(self, coordinator, switch: Switch):
super().__init__(coordinator, switch, SWITCH)
self._switch = switch
def __init__(self, coordinator, load: Load):
super().__init__(coordinator, load, SWITCH)
self._load = load

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

@property
def is_on(self) -> bool | None:
return self._switch.state == SwitchState.ON_PERMANENT
return (
self._load.state == LoadState.ON_PERMANENT
or self._load.state == LoadState.ON_IMPULSE
)

async def async_turn_off(self, **kwargs):
await self._switch.set_state(SwitchState.OFF)
await self._load.set_state(LoadState.OFF)

async def async_turn_on(self, **kwargs):
await self._switch.set_state(SwitchState.ON_PERMANENT)
await self._load.set_state(LoadState.ON_PERMANENT)
1 change: 1 addition & 0 deletions custom_components/mygekko/translations/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
"light": "Light enabled",
"climate": "Climate enabled",
"switch": "Switch enabled",
"scene": "Scene enabled",
"water_heater": "Water Heater enabled",
"demo_mode": "Demo Mode"
}
Expand Down
1 change: 1 addition & 0 deletions custom_components/mygekko/translations/fr.json
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
"light": "Lumière activée",
"climate": "Climat activé",
"switch": "Interrupteur activé",
"scene": "Scène activée",
"water_heater": "Chauffe-eau activé",
"demo_mode": "Mode démo"
},
Expand Down
1 change: 1 addition & 0 deletions custom_components/mygekko/translations/nb.json
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
"light": "Licht aktivert",
"climate": "Klimaat aktivert",
"switch": "Bryter aktivert",
"scene": "Scène aktivert",
"water_heater": "Waterverwarming aktivert",
"demo_mode": "Demomodus"
},
Expand Down
51 changes: 27 additions & 24 deletions custom_components/mygekko/water_heater.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,9 @@
from homeassistant.const import STATE_ON
from homeassistant.const import UnitOfTemperature
from homeassistant.core import callback
from PyMyGekko.resources.WaterHeaters import WaterHeater
from PyMyGekko.resources.WaterHeaters import WaterHeaterFeature
from PyMyGekko.resources.WaterHeaters import WaterHeaterState
from PyMyGekko.resources.HotWaterSystems import HotWaterSystem
from PyMyGekko.resources.HotWaterSystems import HotWaterSystemFeature
from PyMyGekko.resources.HotWaterSystems import HotWaterSystemState

from .const import DOMAIN
from .const import WATER_HEATER
Expand All @@ -24,10 +24,11 @@
async def async_setup_entry(hass, entry, async_add_devices):
"""Setup light platform."""
coordinator = hass.data[DOMAIN][entry.entry_id]
waterHeaters = coordinator.api.get_water_heaters()
if waterHeaters is not None:
hotwater_systems = coordinator.api.get_hot_water_systems()
if hotwater_systems is not None:
async_add_devices(
MyGekkoWaterHeater(coordinator, waterHeater) for waterHeater in waterHeaters
MyGekkoWaterHeater(coordinator, hotwater_system)
for hotwater_system in hotwater_systems
)


Expand All @@ -36,17 +37,17 @@ class MyGekkoWaterHeater(MyGekkoEntity, WaterHeaterEntity):

_attr_temperature_unit = UnitOfTemperature.CELSIUS

def __init__(self, coordinator, water_heater: WaterHeater):
super().__init__(coordinator, water_heater, WATER_HEATER)
self._water_heater = water_heater
def __init__(self, coordinator, hotwater_system: HotWaterSystem):
super().__init__(coordinator, hotwater_system, WATER_HEATER)
self._hotwater_system = hotwater_system

supported_features = self._water_heater.supported_features
supported_features = self._hotwater_system.supported_features
self._attr_supported_features = 0

if WaterHeaterFeature.ON_OFF in supported_features:
if HotWaterSystemFeature.ON_OFF in supported_features:
self._attr_supported_features |= WaterHeaterEntityFeature.ON_OFF

if WaterHeaterFeature.TARGET_TEMPERATURE in supported_features:
if HotWaterSystemFeature.TARGET_TEMPERATURE in supported_features:
self._attr_supported_features |= WaterHeaterEntityFeature.TARGET_TEMPERATURE

@callback
Expand All @@ -55,43 +56,45 @@ def _handle_coordinator_update(self) -> None:
self.async_write_ha_state()

async def async_turn_off(self, **kwargs):
_LOGGER.debug("Switch off water heater %s", self._water_heater.name)
await self._water_heater.set_state(WaterHeaterState.OFF)
_LOGGER.debug("Switch off water heater %s", self._hotwater_system.name)
await self._hotwater_system.set_state(HotWaterSystemState.OFF)

async def async_turn_on(self, **kwargs):
_LOGGER.debug("Switch on water heater %s", self._water_heater.name)
await self._water_heater.set_state(WaterHeaterState.ON)
_LOGGER.debug("Switch on water heater %s", self._hotwater_system.name)
await self._hotwater_system.set_state(HotWaterSystemState.ON)

@property
def target_temperature(self) -> float | None:
"""Return the target temperature of the water heater."""
_LOGGER.debug(
"The water heaters %s current target temperature is %s",
self._water_heater.name,
self._water_heater.target_temperature,
self._hotwater_system.name,
self._hotwater_system.target_temperature,
)

return self._water_heater.target_temperature
return self._hotwater_system.target_temperature

async def async_set_temperature(self, **kwargs: Any) -> None:
"""Set new target temperature."""
await self._water_heater.set_target_temperature(float(kwargs[ATTR_TEMPERATURE]))
await self._hotwater_system.set_target_temperature(
float(kwargs[ATTR_TEMPERATURE])
)

@property
def current_temperature(self) -> float | None:
"""Return the top temperature of the water heater."""
_LOGGER.debug(
"The water heaters %s current top temperature is %s",
self._water_heater.name,
self._water_heater.current_temperature_top,
self._hotwater_system.name,
self._hotwater_system.current_temperature_top,
)

return self._water_heater.current_temperature_top
return self._hotwater_system.current_temperature_top

@property
def current_operation(self) -> str | None:
"""Return current operation ie. eco, electric, performance, ..."""
if self._water_heater.state == WaterHeaterState.OFF:
if self._hotwater_system.state == HotWaterSystemState.OFF:
return STATE_OFF
else:
return STATE_ON
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.76
PyMyGekko==0.0.5rc4
PyMyGekko==0.0.5rc5

0 comments on commit 3cd9f67

Please sign in to comment.