Skip to content

Commit

Permalink
Fix update_from_dict
Browse files Browse the repository at this point in the history
Fix EventHandler
  • Loading branch information
hahn-th committed May 10, 2024
1 parent c274024 commit efd7360
Show file tree
Hide file tree
Showing 4 changed files with 77 additions and 22 deletions.
12 changes: 9 additions & 3 deletions src/homematicip/events/hmip_event_handler.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
from homematicip.events.event_types import EventType
from homematicip.model.client import Client
from homematicip.model.devices import Device
from homematicip.model.group import Group
from homematicip.model.model import Model

LOGGER = logging.getLogger(__name__)
Expand All @@ -26,7 +27,7 @@ async def process_event_async(self, event_json):
event_type = EventType[event['pushEventType']]
if event_type == EventType.CLIENT_ADDED:
data = event['client']
client:Client = Client.model_validate_json(data, strict=False)
client: Client = Client.model_validate(data, strict=False)
self._model.clients[data['id']] = client
await self._event_manager.publish(ModelUpdateEvent.ITEM_CREATED, client)

Expand All @@ -47,7 +48,7 @@ async def process_event_async(self, event_json):
elif event_type == EventType.DEVICE_ADDED:
data = event['device']
if data['id'] not in self._model.devices:
device:Device = Device.model_validate_json(data, strict=False)
device: Device = Device.model_validate(data, strict=False)
self._model.devices[data['id']] = device
await self._event_manager.publish(ModelUpdateEvent.ITEM_CREATED, device)

Expand All @@ -66,7 +67,12 @@ async def process_event_async(self, event_json):
await self._event_manager.publish(ModelUpdateEvent.ITEM_REMOVED, device)

elif event_type == EventType.GROUP_ADDED:
pass
data = event['group']
if data['id'] not in self._model.groups:
group: Group = Group.model_validate(data, strict=False)
self._model.groups[data['id']] = group
await self._event_manager.publish(ModelUpdateEvent.ITEM_CREATED, group)

elif event_type == EventType.GROUP_CHANGED:
data = event['group']
if data['id'] in self._model.groups:
Expand Down
57 changes: 40 additions & 17 deletions src/homematicip/model/hmip_base.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
from pydantic import BaseModel, ConfigDict
from pydantic import BaseModel, ConfigDict, Field


class HmipBaseModel(BaseModel):
Expand All @@ -8,23 +8,46 @@ class HmipBaseModel(BaseModel):
)

def update_from_dict(self, data_dict):
for field_name, value in data_dict.items():
target_field = getattr(self, field_name)

if target_field is None:
continue
model_fields = self.model_fields
new_item = type(self).model_validate(data_dict, strict=False)

if isinstance(target_field, HmipBaseModel):
target_field.update_from_dict(value)
for field_name in model_fields.keys():

if hasattr(new_item, field_name):
new_value = getattr(new_item, field_name)
else:
setattr(self, field_name, value)
#
# if isinstance(value, dict) and issubclass(field.outer_type_, BaseModel):
# field_value = getattr(self, field_name, None)
# if isinstance(field_value, BaseModel):
# field_value.update_from_dict(value)
# else:
# setattr(self, field_name, field.outer_type_(**value))
# else:
# setattr(self, field_name, value)
new_value = None

setattr(self, field_name, new_value)



# if isinstance(value, dict):
# for key_dict, value_value in value.items():
# if key_dict in target_field_value:
# target_field_value[key_dict] = value_value
# else:
# setattr(self, field_name, value)
#
# # Keys durchlaufen
# # Key in target_field_value suchen
# # Wenn gefunden, dann update_from_dict(value)

# if isinstance(target_field_value, dict[str, HmipBaseModel]):
# target_field_value.update_from_dict(value)
#
# if isinstance(target_field_value, HmipBaseModel):
# target_field_value.update_from_dict(value)
#
# else:
# setattr(self, field_name, value)
# #
# # if isinstance(value, dict) and issubclass(field.outer_type_, BaseModel):
# # field_value = getattr(self, field_name, None)
# # if isinstance(field_value, BaseModel):
# # field_value.update_from_dict(value)
# # else:
# # setattr(self, field_name, field.outer_type_(**value))
# # else:
# # setattr(self, field_name, value)
15 changes: 13 additions & 2 deletions tests/events/test_hmip_event_handler.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,20 @@ def test_device_removed(sample_data_complete):
assert True


def test_device_added(sample_data_complete):
assert True
@pytest.mark.asyncio
async def test_device_added(sample_data_complete):
change_event_b = b'{"events":{"0":{"pushEventType":"DEVICE_ADDED","device":{"availableFirmwareVersion":"1.0.18","connectionType":"HMIP_RF","firmwareVersion":"1.0.18","firmwareVersionInteger":65554,"functionalChannels":{"0":{"busConfigMismatch":null,"coProFaulty":false,"coProRestartNeeded":false,"coProUpdateFailure":false,"configPending":false,"deviceId":"3014F71100000000000TEST","deviceOverheated":false,"deviceOverloaded":false,"devicePowerFailureDetected":false,"deviceUndervoltage":false,"dutyCycle":false,"functionalChannelType":"DEVICE_BASE","groupIndex":0,"groups":["00000000-0000-0000-0000-000000000042"],"index":0,"label":"","lowBat":null,"multicastRoutingEnabled":false,"powerShortCircuit":null,"routerModuleEnabled":false,"routerModuleSupported":false,"rssiDeviceValue":-91,"rssiPeerValue":null,"shortCircuitDataLine":null,"supportedOptionalFeatures":{"IFeatureBusConfigMismatch":false,"IFeatureDeviceCoProError":false,"IFeatureDeviceCoProRestart":false,"IFeatureDeviceCoProUpdate":false,"IFeatureDeviceIdentify":false,"IFeatureDeviceOverheated":false,"IFeatureDeviceOverloaded":false,"IFeatureDevicePowerFailure":false,"IFeatureDeviceTemperatureOutOfRange":false,"IFeatureDeviceUndervoltage":false,"IFeatureMulticastRouter":false,"IFeaturePowerShortCircuit":false,"IFeatureRssiValue":true,"IFeatureShortCircuitDataLine":false,"IOptionalFeatureDutyCycle":true,"IOptionalFeatureLowBat":false},"temperatureOutOfRange":false,"unreach":false},"1":{"deviceId":"3014F71100000000000TEST","functionalChannelType":"RAIN_DETECTION_CHANNEL","groupIndex":1,"groups":["00000000-0000-0000-0000-000000000043"],"index":1,"label":"","rainSensorSensitivity":90.0,"raining":true}},"homeId":"00000000-0000-0000-0000-000000000001","id":"3014F71100000000000TEST","label":"Regensensor","lastStatusUpdate":1610893558747,"liveUpdateState":"LIVE_UPDATE_NOT_SUPPORTED","manufacturerCode":1,"modelId":412,"modelType":"HmIP-SRD","oem":"eQ-3","permanentlyReachable":true,"serializedGlobalTradeItemNumber":"3014F71100000000000TEST","type":"RAIN_SENSOR","updateState":"UP_TO_DATE"}}}}'
change_event = json.loads(change_event_b)

event_manager = EventManager()
model = build_model_from_json(sample_data_complete)
new_device_id = "3014F71100000000000TEST"

hmip_event_handler = HmipEventHandler(event_manager=event_manager, model=model)
await hmip_event_handler.process_event_async(change_event)

assert model.devices[new_device_id] is not None
assert model.devices[new_device_id].functionalChannels["1"].rainSensorSensitivity == 90.0

@pytest.mark.asyncio
async def test_device_updated(sample_data_complete):
Expand Down
15 changes: 15 additions & 0 deletions tests/model/test_functional_channel.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import json

from homematicip.model.functional_channels import FunctionalChannel


Expand All @@ -11,3 +13,16 @@ def test_operation_lock_channel(filled_model):
assert fc.routerModuleEnabled == False
assert fc.rssiDeviceValue == -45
assert fc.rssiPeerValue == -54


def test_update_functional_channel(filled_model):
device = filled_model.devices["3014F7110000RAIN_SENSOR"]
old_channel_0 = device.functionalChannels["0"]

changed_data = b'{"availableFirmwareVersion":"1.0.18","connectionType":"HMIP_RF","firmwareVersion":"1.0.18","firmwareVersionInteger":65554,"functionalChannels":{"0":{"busConfigMismatch":null,"coProFaulty":false,"coProRestartNeeded":false,"coProUpdateFailure":false,"configPending":false,"deviceId":"3014F7110000RAIN_SENSOR","deviceOverheated":false,"deviceOverloaded":false,"devicePowerFailureDetected":false,"deviceUndervoltage":false,"dutyCycle":false,"functionalChannelType":"DEVICE_BASE","groupIndex":0,"groups":["00000000-0000-0000-0000-000000000042"],"index":0,"label":"","lowBat":null,"multicastRoutingEnabled":false,"powerShortCircuit":null,"routerModuleEnabled":false,"routerModuleSupported":false,"rssiDeviceValue":-91,"rssiPeerValue":null,"shortCircuitDataLine":null,"supportedOptionalFeatures":{"IFeatureBusConfigMismatch":false,"IFeatureDeviceCoProError":false,"IFeatureDeviceCoProRestart":false,"IFeatureDeviceCoProUpdate":false,"IFeatureDeviceIdentify":false,"IFeatureDeviceOverheated":false,"IFeatureDeviceOverloaded":false,"IFeatureDevicePowerFailure":false,"IFeatureDeviceTemperatureOutOfRange":false,"IFeatureDeviceUndervoltage":false,"IFeatureMulticastRouter":false,"IFeaturePowerShortCircuit":false,"IFeatureRssiValue":true,"IFeatureShortCircuitDataLine":false,"IOptionalFeatureDutyCycle":true,"IOptionalFeatureLowBat":false},"temperatureOutOfRange":false,"unreach":false},"1":{"deviceId":"3014F7110000RAIN_SENSOR","functionalChannelType":"RAIN_DETECTION_CHANNEL","groupIndex":1,"groups":["00000000-0000-0000-0000-000000000043"],"index":1,"label":"","rainSensorSensitivity":90.0,"raining":true}},"homeId":"00000000-0000-0000-0000-000000000001","id":"3014F7110000RAIN_SENSOR","label":"Regensensor","lastStatusUpdate":1610893558747,"liveUpdateState":"LIVE_UPDATE_NOT_SUPPORTED","manufacturerCode":1,"modelId":412,"modelType":"HmIP-SRD","oem":"eQ-3","permanentlyReachable":true,"serializedGlobalTradeItemNumber":"3014F7110000RAIN_SENSOR","type":"RAIN_SENSOR","updateState":"UP_TO_DATE"}'
rainSensorSensitivityOld = device.functionalChannels["1"].rainSensorSensitivity

device.update_from_dict(json.loads(changed_data))

assert device.functionalChannels["0"] == old_channel_0
assert device.functionalChannels["1"].rainSensorSensitivity != rainSensorSensitivityOld

0 comments on commit efd7360

Please sign in to comment.