Skip to content

Commit

Permalink
test migrate_helpers
Browse files Browse the repository at this point in the history
  • Loading branch information
OStrama committed Nov 30, 2024
1 parent 93dd833 commit 7b09482
Show file tree
Hide file tree
Showing 3 changed files with 67 additions and 78 deletions.
23 changes: 11 additions & 12 deletions custom_components/weishaupt_modbus/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -62,17 +62,17 @@ async def async_setup_entry(hass: HomeAssistant, entry: MyConfigEntry) -> bool:
await mbapi.connect()
entry.runtime_data = MyData(mbapi, hass.config.config_dir, hass)

migrate_entities(entry, MODBUS_SYS_ITEMS, DEVICENAMES.SYS)
migrate_entities(entry, MODBUS_HZ_ITEMS, DEVICENAMES.HZ)
migrate_entities(entry, MODBUS_HZ2_ITEMS, DEVICENAMES.HZ2)
migrate_entities(entry, MODBUS_HZ3_ITEMS, DEVICENAMES.HZ3)
migrate_entities(entry, MODBUS_HZ4_ITEMS, DEVICENAMES.HZ4)
migrate_entities(entry, MODBUS_HZ5_ITEMS, DEVICENAMES.HZ5)
migrate_entities(entry, MODBUS_WP_ITEMS, DEVICENAMES.WP)
migrate_entities(entry, MODBUS_WW_ITEMS, DEVICENAMES.WW)
migrate_entities(entry, MODBUS_W2_ITEMS, DEVICENAMES.W2)
migrate_entities(entry, MODBUS_IO_ITEMS, DEVICENAMES.IO)
migrate_entities(entry, MODBUS_ST_ITEMS, DEVICENAMES.ST)
hass.add_job(migrate_entities, entry, MODBUS_SYS_ITEMS, DEVICENAMES.SYS)
hass.add_job(migrate_entities, entry, MODBUS_HZ_ITEMS, DEVICENAMES.HZ)
hass.add_job(migrate_entities, entry, MODBUS_HZ2_ITEMS, DEVICENAMES.HZ2)
hass.add_job(migrate_entities, entry, MODBUS_HZ3_ITEMS, DEVICENAMES.HZ3)
hass.add_job(migrate_entities, entry, MODBUS_HZ4_ITEMS, DEVICENAMES.HZ4)
hass.add_job(migrate_entities, entry, MODBUS_HZ5_ITEMS, DEVICENAMES.HZ5)
hass.add_job(migrate_entities, entry, MODBUS_WP_ITEMS, DEVICENAMES.WP)
hass.add_job(migrate_entities, entry, MODBUS_WW_ITEMS, DEVICENAMES.WW)
hass.add_job(migrate_entities, entry, MODBUS_W2_ITEMS, DEVICENAMES.W2)
hass.add_job(migrate_entities, entry, MODBUS_IO_ITEMS, DEVICENAMES.IO)
hass.add_job(migrate_entities, entry, MODBUS_ST_ITEMS, DEVICENAMES.ST)

# see https://community.home-assistant.io/t/config-flow-how-to-update-an-existing-entity/522442/8
entry.async_on_unload(entry.add_update_listener(update_listener))
Expand Down Expand Up @@ -133,7 +133,6 @@ async def async_migrate_entry(hass: HomeAssistant, config_entry: MyConfigEntry):
hass.config_entries.async_update_entry(
config_entry, data=new_data, minor_version=1, version=6
)

return True


Expand Down
43 changes: 14 additions & 29 deletions custom_components/weishaupt_modbus/migrate_helpers.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
from homeassistant.util import slugify
from homeassistant.helpers import entity_registry as er
from homeassistant.const import CONF_PREFIX
from homeassistant.core import callback

from .const import (
CONF_DEVICE_POSTFIX,
Expand All @@ -21,23 +22,6 @@
log = logging.getLogger(__name__)


def create_old_id(config_entry: MyConfigEntry, modbus_item: ModbusItem):
"""created an entity ID according to old style"""
if config_entry.data[CONF_NAME_DEVICE_PREFIX]:
name_device_prefix = config_entry.data[CONF_PREFIX] + "_"
else:
name_device_prefix = ""

if config_entry.data[CONF_NAME_TOPIC_PREFIX]:
name_topic_prefix = reverse_device_list[modbus_item.device] + "_"
else:
name_topic_prefix = ""

entity_name = name_topic_prefix + name_device_prefix + modbus_item.name

return slugify(entity_name)


def create_new_entity_id(
config_entry: MyConfigEntry, modbus_item: ModbusItem, platform: str, device: str
):
Expand All @@ -46,7 +30,6 @@ def create_new_entity_id(
if dev_postfix == "_":
dev_postfix = ""

# device_name = modbus_item.device + dev_postfix
device_name = device + dev_postfix

if config_entry.data[CONF_NAME_DEVICE_PREFIX]:
Expand Down Expand Up @@ -74,37 +57,41 @@ def create_unique_id(config_entry: MyConfigEntry, modbus_item: ModbusItem):
return str(config_entry.data[CONF_PREFIX] + modbus_item.name + dev_postfix)


def migrate_entities(config_entry: MyConfigEntry, modbusitems: ModbusItem, device: str):
@callback
def migrate_entities(
config_entry: MyConfigEntry,
modbusitems: ModbusItem,
device: str,
):
"""Build entity list.
function builds a list of entities that can be used as parameter by async_setup_entry()
type of list is defined by the ModbusItem's type flag
so the app only holds one list of entities that is build from a list of ModbusItem
stored in hpconst.py so far, will be provided by an external file in future
"""
# return

entity_registry = er.async_get(config_entry.runtime_data.hass)

for _useless, item in enumerate(modbusitems):
platform = ""
match item.type:
# here the entities are created with the parameters provided
# by the ModbusItem object
case TYPES.SENSOR | TYPES.NUMBER_RO | TYPES.SENSOR_CALC:
platform = "sensor"
case TYPES.SELECT:
platform = "select"
case TYPES.NUMBER:
platform = "number"

old_id = create_old_id(config_entry, item)
old_uid = create_unique_id(config_entry, item)
new_entity_id = create_new_entity_id(config_entry, item, platform, device)
old_entity_id = entity_registry.async_get_entity_id(
platform, CONST.DOMAIN, old_uid
)

if new_entity_id == old_entity_id:
log.info("already migrated")
log.info("already migrated %s", old_entity_id)
return

if old_entity_id is not None:
Expand All @@ -115,20 +102,18 @@ def migrate_entities(config_entry: MyConfigEntry, modbusitems: ModbusItem, devic
)

log.info(
"Init UID:%s, platform:%s old ID:%s --> %s new ID:%s",
"Init UID:%s, platform:%s old ID:%s new ID:%s",
old_uid,
platform,
old_id,
old_entity_id,
new_entity_id,
)
except:
except KeyError as key:
log.warning(
"Already existing UID:%s, platform:%s old ID:%s --> %s new ID:%s",
"Exception %s old UID:%s, platform:%s old ID:%s new ID:%s",
str(key),
old_uid,
platform,
old_id,
old_entity_id,
new_entity_id,
)

79 changes: 42 additions & 37 deletions custom_components/weishaupt_modbus/modbusobject.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
A Modbus object that contains a Modbus item and communicates with the Modbus.
It contains a ModbusClient for setting and getting Modbus register values
"""

import asyncio
import logging

Expand All @@ -18,11 +19,13 @@
logging.basicConfig()
log = logging.getLogger(__name__)


class ModbusAPI:
"""
ModbusAPI class that provides a connection to the modbus,
which is used by the ModbusItems.
"""

def __init__(self, config_entry: MyConfigEntry) -> None:
"""Construct ModbusAPI.
Expand Down Expand Up @@ -73,6 +76,7 @@ class ModbusObject:
A Modbus object that contains a Modbus item and communicates with the Modbus.
It contains a ModbusClient for setting and getting Modbus register values
"""

def __init__(self, modbus_api: ModbusAPI, modbus_item: ModbusItem) -> None:
"""Construct ModbusObject.
Expand All @@ -84,7 +88,7 @@ def __init__(self, modbus_api: ModbusAPI, modbus_item: ModbusItem) -> None:
self._modbus_item = modbus_item
self._modbus_client = modbus_api.get_device()

def check_valid(self, val) -> int:
def check_valid_result(self, val) -> int:
"""Check if item is available and valid."""
match self._modbus_item.format:
case FORMATS.TEMPERATUR:
Expand All @@ -98,7 +102,7 @@ def check_valid(self, val) -> int:
return val

def check_temperature(self, val) -> int:
"""Check availability of temperature item and translate
"""Check availability of temperature item and translate
return value to valid int
:param val: The value from the modbus
Expand All @@ -124,7 +128,7 @@ def check_temperature(self, val) -> int:
return val

def check_percentage(self, val) -> int:
"""Check availability of percentage item and translate
"""Check availability of percentage item and translate
return value to valid int
:param val: The value from the modbus
Expand All @@ -141,6 +145,16 @@ def check_status(self, val) -> int:
self._modbus_item.is_invalid = False
return val

def check_valid_response(self, val) -> int:
"""Check if item is valid to write."""
match self._modbus_item.format:
case FORMATS.TEMPERATUR:
if val < 0:
val = val + 65536
return val
case _:
return val

def validate_modbus_answer(self, mbr) -> int:
"""Check if there's a valid answer from modbus and
translate it to a valid int depending from type
Expand All @@ -153,28 +167,26 @@ def validate_modbus_answer(self, mbr) -> int:
self._modbus_item.is_invalid = True
else:
log.warning(
"Received Modbus library error: "
+ str(mbr)
+ "in item: "
+ str(self._modbus_item.name)
"Received Modbus library error: %s in item: %s",
str(mbr),
str(self._modbus_item.name),
)
return None
if isinstance(mbr, ExceptionResponse):
log.warning(
"Received ModbusException: "
+ str(mbr)
+ " from library in item: "
+ str(self._modbus_item.name)
"Received ModbusException: %s from library in item: %s",
str(mbr),
str(self._modbus_item.name),
)
return None
# THIS IS NOT A PYTHON EXCEPTION, but a valid modbus message
if len(mbr.registers) > 0:
val = self.check_valid(mbr.registers[0])
val = self.check_valid_result(mbr.registers[0])
log.debug(
"Item %s val=%d and invalid = %s",
self._modbus_item.name,
val,
self._modbus_item.is_invalid,
"Item %s val=%d and invalid = %s",
self._modbus_item.name,
val,
self._modbus_item.is_invalid,
)
return val

Expand All @@ -184,7 +196,6 @@ async def value(self):
if self._modbus_client is None:
return None

val = None
if not self._modbus_item.is_invalid:
try:
match self._modbus_item.type:
Expand All @@ -202,20 +213,17 @@ async def value(self):
)
return self.validate_modbus_answer(mbr)
case _:
val = None
log.warning(
"Unknown Sensor type: "
+ str(self._modbus_item.type)
+ "in "
+ str(self._modbus_item.name)
"Unknown Sensor type: %s in %s",
str(self._modbus_item.type),
str(self._modbus_item.name),
)
return None
except ModbusException as exc:
log.warning(
"ModbusException: Reading "
+ str(exc)
+ "in item: "
+ str(self._modbus_item.name)
+ " failed"
"ModbusException: Reading %s in item: %s failed",
str(exc),
str(self._modbus_item.name),
)
return None

Expand All @@ -233,19 +241,16 @@ async def setvalue(self, value) -> None:
# Sensor entities are read-only
return
case _:
if self._modbus_item.format == FORMATS.TEMPERATUR:
if value < 0:
value=value+65536
await self._modbus_client.write_register(
self._modbus_item.address, int(value), slave=1
self._modbus_item.address,
self.check_valid_response(value),
slave=1,
)
except ModbusException:
log.warning(
"ModbusException: Writing "
+ str(value)
+ " to "
+ str(self._modbus_item.name)
+ " ("
+ str(self._modbus_item.address + ")" + " failed")
"ModbusException: Writing %s to %s (%s) failed",
str(value),
str(self._modbus_item.name),
str(self._modbus_item.address),
)
return None

0 comments on commit 7b09482

Please sign in to comment.