Skip to content

Commit

Permalink
Merge pull request #8 from Crisicus/dev
Browse files Browse the repository at this point in the history
  • Loading branch information
Crisicus authored Feb 3, 2023
2 parents e3d52c6 + f951d3a commit ee8fad9
Show file tree
Hide file tree
Showing 6 changed files with 200 additions and 41 deletions.
2 changes: 1 addition & 1 deletion custom_components/maestro_mcz/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
from .const import DOMAIN
from .maestro import MaestroController, MaestroStove

PLATFORMS: list[Platform] = [Platform.CLIMATE, Platform.SENSOR]
PLATFORMS: list[Platform] = [Platform.CLIMATE, Platform.SENSOR, Platform.FAN]
_LOGGER = logging.getLogger(__name__)


Expand Down
6 changes: 4 additions & 2 deletions custom_components/maestro_mcz/climate.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@ async def async_setup_entry(hass, entry, async_add_entities):
async_add_entities(MczEntity(stove) for stove in stoveList)

class MczEntity(CoordinatorEntity, ClimateEntity):
_attr_has_entity_name = True

def __init__(self, coordinator:MczCoordinator):
super().__init__(coordinator)
self.coordinator:MczCoordinator = coordinator
Expand All @@ -31,9 +33,9 @@ def __init__(self, coordinator:MczCoordinator):
self._attr_preset_modes = ["manual", "auto", "overnight", "comfort", "turbo"]
self._attr_min_temp = 5
self._attr_max_temp = 40
self._attr_name = self.coordinator._maestroapi.Name
self._attr_name = None
self._attr_temperature_unit = UnitOfTemperature.CELSIUS
self._attr_unique_id = f"{self.coordinator._maestroapi.Status.sm_sn}_climate"
self._attr_unique_id = f"{self.coordinator._maestroapi.Status.sm_sn}"
self._attr_icon = "mdi:stove"

_attr_supported_features = (
Expand Down
88 changes: 88 additions & 0 deletions custom_components/maestro_mcz/fan.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
"""Platform for Sensor integration."""
import logging
from typing import Optional
from . import MczCoordinator, models

from homeassistant.components.fan import (
FanEntity,
FanEntityFeature
)
from homeassistant.core import callback
from homeassistant.helpers.entity import DeviceInfo
from homeassistant.helpers.update_coordinator import CoordinatorEntity
from homeassistant.util.percentage import ordered_list_item_to_percentage, percentage_to_ordered_list_item


from .const import DOMAIN
ENTITY = "fan"
_LOGGER = logging.getLogger(__name__)

async def async_setup_entry(hass, entry, async_add_entities):
stoveList = hass.data[DOMAIN][entry.entry_id]
entities = []
for stove in stoveList:
stove:MczCoordinator = stove
model = stove.maestroapi.State.nome_banca_dati_sel
for (prop, attrs) in models.models[model][ENTITY].items():
entities.append(MczEntity(stove, prop, attrs))

async_add_entities(entities)


class MczEntity(CoordinatorEntity, FanEntity):
_attr_has_entity_name = True

_attr_supported_features = (
FanEntityFeature.PRESET_MODE
)

def __init__(self, coordinator, prop, attrs):
super().__init__(coordinator)
[name, icon, presets, fannum, function, enabled_by_default, category] = attrs
self.coordinator:MczCoordinator = coordinator
self._attr_name = name
self._attr_unique_id = f"{self.coordinator._maestroapi.Status.sm_sn}-{prop}"
self._attr_icon = icon
self._prop = prop
self._enabled_default = enabled_by_default
self._category = category
self._presets = sorted(list(presets))
self._attr_preset_modes = sorted(list(presets))

@property
def device_info(self) -> DeviceInfo:
return DeviceInfo(
identifiers={(DOMAIN, self.coordinator._maestroapi.Status.sm_sn)},
name=self.coordinator._maestroapi.Name,
manufacturer="MCZ",
model=self.coordinator._maestroapi.Status.nome_banca_dati_sel,
sw_version=self.coordinator._maestroapi.Status.mc_vs_app,
)

@property
def is_on(self) -> bool:
if (self.coordinator._maestroapi.State.state == "on"):
return True
else:
return False

@property
def preset_mode(self) -> str:
return str(getattr(self.coordinator._maestroapi.Status, "set_vent_v1"))

@property
def entity_registry_enabled_default(self) -> bool:
"""Return if the entity should be enabled when first added to the entity registry."""
return self._enabled_default

@property
def entity_category(self):
return self._category

async def async_set_preset_mode(self, preset_mode: str) -> None:
"""Set the preset mode of the fan."""
await self.coordinator._maestroapi.Fan(int(preset_mode))

@callback
def _handle_coordinator_update(self) -> None:
self.async_write_ha_state()
52 changes: 27 additions & 25 deletions custom_components/maestro_mcz/maestro/__init__.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import json
import aiohttp
import asyncio
import async_timeout

from .responses.status import Status
from .responses.state import State
Expand Down Expand Up @@ -39,31 +40,32 @@ def Stoves(self):
return self._stoves

async def MakeRequest(self, method, url, headers={}, body=None):
headers["auth-token"] = self._token

try:
async with aiohttp.ClientSession() as session:
if method == "GET":
async with session.get(url, headers=headers) as resp:
response = await resp.json()
elif method == "POST":
headers["content-type"] = "application/json"
jbody = json.dumps(body, ensure_ascii=False)
async with session.post(url, headers=headers, data=jbody) as resp:
response = await resp.json()
if resp.status == 200:
return response
else:
await self.Login()
return await self.MakeRequest(
method=method, url=url, headers=headers, body=body
)
except:
print("Error making request. Attempting to relogin")
await self.Login()
return await self.MakeRequest(
method=method, url=url, headers=headers, body=body
)
async with async_timeout.timeout(15):
headers["auth-token"] = self._token

try:
async with aiohttp.ClientSession() as session:
if method == "GET":
async with session.get(url, headers=headers) as resp:
response = await resp.json()
elif method == "POST":
headers["content-type"] = "application/json"
jbody = json.dumps(body, ensure_ascii=False)
async with session.post(url, headers=headers, data=jbody) as resp:
response = await resp.json()
if resp.status == 200:
return response
else:
await self.Login()
return await self.MakeRequest(
method=method, url=url, headers=headers, body=body
)
except:
print("Error making request. Attempting to relogin")
await self.Login()
return await self.MakeRequest(
method=method, url=url, headers=headers, body=body
)

async def Login(self):
LOGIN_BODY = {"username": self.Username, "password": self.Password}
Expand Down
47 changes: 47 additions & 0 deletions custom_components/maestro_mcz/models.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
from homeassistant.components.sensor import (
SensorDeviceClass,
SensorStateClass,
)

from homeassistant.helpers.entity import EntityCategory
from homeassistant.const import TEMP_CELSIUS

GENERIC_SENSORS = {
"state": ["Current State", None, "mdi:power", None, None, True, EntityCategory.DIAGNOSTIC],
"temp_amb_install": ["Temperature", TEMP_CELSIUS, "mdi:thermometer", SensorDeviceClass.TEMPERATURE, SensorStateClass.MEASUREMENT, True, None],
"mode": ["Current Mode", None, "mdi:calendar-multiselect", None, None, True, EntityCategory.DIAGNOSTIC],
"temp_fumi": ["Exhaust Temperature", TEMP_CELSIUS, "mdi:thermometer", SensorDeviceClass.TEMPERATURE, SensorStateClass.MEASUREMENT, True, EntityCategory.DIAGNOSTIC],
"temp_scheda": ["Board Temperature", TEMP_CELSIUS, "mdi:thermometer", SensorDeviceClass.TEMPERATURE, SensorStateClass.MEASUREMENT, True, EntityCategory.DIAGNOSTIC],
"mode": ["Current Mode", None, "mdi:calendar-multiselect", None, None, True, EntityCategory.DIAGNOSTIC],
"vel_real_ventola_fumi": ["Exhaust Fan Speed", "rpm", "mdi:fan-chevron-up", None, SensorStateClass.MEASUREMENT, True, EntityCategory.DIAGNOSTIC],
"vel_real_coclea": ["Transport Screw Speed", "rpm", "mdi:screw-lag", None, None, SensorStateClass.MEASUREMENT, EntityCategory.DIAGNOSTIC],
}

GENERIC_FANS = {
"set_vent_v1": ["Fan 1", "mdi:fan", {"0", "1", "2", "3", "4", "5", "6"}, 1, "Fan", True, EntityCategory.CONFIG]
}

models = {
"CUTHDE08": {
"sensor": {
**GENERIC_SENSORS,
**{
# "temp_amb_install": ["Temperature", TEMP_CELSIUS, "mdi:thermometer", SensorDeviceClass.TEMPERATURE, SensorStateClass.MEASUREMENT, True, None],
}
},
"fan": {
**GENERIC_FANS,
**{
# "set_vent_v1": ["Fan 1", ["0", "1", "2", "3", "4", "5", "6"], 1, "Fan"]
}
}
},
"SC12": {
"sensor": {
**GENERIC_SENSORS,
},
"fan": {
**GENERIC_FANS,
}
},
}
46 changes: 33 additions & 13 deletions custom_components/maestro_mcz/sensor.py
Original file line number Diff line number Diff line change
@@ -1,34 +1,46 @@
"""Platform for Sensor integration."""
from . import MczCoordinator
from . import MczCoordinator, models

from homeassistant.components.sensor import (
SensorDeviceClass,
SensorEntity,
SensorStateClass,
)
from homeassistant.core import callback
from homeassistant.const import TEMP_CELSIUS
from homeassistant.helpers.entity import DeviceInfo
from homeassistant.helpers.update_coordinator import CoordinatorEntity

from .const import DOMAIN
ENTITY = "sensor"


async def async_setup_entry(hass, entry, async_add_entities):
stoveList = hass.data[DOMAIN][entry.entry_id]
async_add_entities(MczEntity(stove) for stove in stoveList)
entities = []
for stove in stoveList:
stove:MczCoordinator = stove
model = stove.maestroapi.State.nome_banca_dati_sel
for (prop, attrs) in models.models[model][ENTITY].items():
entities.append(MczEntity(stove, prop, attrs))

async_add_entities(entities)


class MczEntity(CoordinatorEntity, SensorEntity):
def __init__(self, coordinator):

_attr_has_entity_name = True

def __init__(self, coordinator, prop, attrs):
super().__init__(coordinator)
[name, unit, icon, device_class, state_class, enabled_by_default, category] = attrs
self.coordinator:MczCoordinator = coordinator
self._attr_name = "Temperature"
self._attr_native_unit_of_measurement = TEMP_CELSIUS
self._attr_device_class = SensorDeviceClass.TEMPERATURE
self._attr_state_class = SensorStateClass.MEASUREMENT
self._attr_unique_id = f"{self.coordinator._maestroapi.Status.sm_sn}_sensor"
self._attr_icon = "mdi:thermometer"
self._attr_name = name
self._attr_native_unit_of_measurement = unit
self._attr_device_class = device_class
self._attr_state_class = state_class
self._attr_unique_id = f"{self.coordinator._maestroapi.Status.sm_sn}-{prop}"
self._attr_icon = icon
self._prop = prop
self._enabled_default = enabled_by_default
self._category = category

@property
def device_info(self) -> DeviceInfo:
Expand All @@ -38,8 +50,16 @@ def device_info(self) -> DeviceInfo:

@property
def native_value(self):
return self.coordinator._maestroapi.State.temp_amb_install
return getattr(self.coordinator._maestroapi.State, self._prop)

@property
def entity_registry_enabled_default(self) -> bool:
"""Return if the entity should be enabled when first added to the entity registry."""
return self._enabled_default

@property
def entity_category(self):
return self._category
@callback
def _handle_coordinator_update(self) -> None:
self.async_write_ha_state()

0 comments on commit ee8fad9

Please sign in to comment.