iMicknl / ha-tahoma

Custom component for Home Assistant to interact with smart devices via Somfy TaHoma or other OverKiz based API's.
MIT License
152 stars 30 forks source link

Double decoding from pyOverkiz and ha-tahome #709

Closed egguy closed 2 years ago

egguy commented 2 years ago

Did you read the instructions?

The problem

The problem is present when there's an EnventState which happen with a DataType.JSON_OBJECT.

From what I've understood there's a double decoding, the first if from py-overkiz 1.1.0 (and 1.1.1) (models.py:300) and the function _get_state.

When an Event happen with a JSON type data, it's decoded in the overkiz API and then decoded again in the tahoma integration. It's working OK when an int is cast to an int, but json.loads don't like it.

I've wrapped the line 140 from the coordinator.py

device.states[state.name].value = self._get_state(state)

With a try except to prevent this from crashing the integration

                    try:
                        device.states[state.name].value = self._get_state(state)
                    except TypeError as e:
                        _LOGGER.error("Error while converting state: %s value: %s for device %s", state.name, state, device, exc_info=True)

(I know this combo of lib version is not normal. Sorry if it's generating noise for you.)

What version of this integration (ha-tahoma) has the issue?

climate/SomfyHeatingTemperatureInterface

What version of Home Assistant Core has the issue?

core-2021.12.9

Which gateway / hub do you use?

Rexel Energeasy

Device model

<unknown>

Home Assistant log

Logs ``` 2022-01-15 01:22:44 DEBUG (MainThread) [custom_components.tahoma.coordinator] Event(timestamp=1642206159815, name=, setupoid=_CountingAttr(counter=318, _default=None, repr=, eq=True, order=True, hash=None, init=True, on_setattr=None, metadata={}), owner_key=None, type=None, sub_type=None, time_to_next_state=None, failed_commands=None, failure_type_code=None, failure_type=None, condition_groupoid=None, place_oid=None, label=None, metadata=None, camera_id=None, deleted_raw_devices_count=None, protocol_type=None, gateway_id=None, exec_id=None, device_url=io://****-****-0891/9923380#1, device_states=[EventState(name='io:OperatingModeCapabilitiesState', type=, value={'relaunch': 1, 'absence': 1, 'rateManagement': 0, 'energyDemandStatus': 0})], old_state=None, new_state=None) 2022-01-15 01:22:44 ERROR (MainThread) [custom_components.tahoma.coordinator] Error while converting state: io:OperatingModeCapabilitiesState value: EventState(name='io:OperatingModeCapabilitiesState', type=, value={'relaunch': 1, 'absence': 1, 'rateManagement': 0, 'energyDemandStatus': 0}) for device Device(attributes=States(_states=[State(name='core:FirmwareRevision', type=, value='I722802'), State(name='core:Manufacturer', type=, value='Atlantic Group')]), available=True, enabled=True, label='Chauffe-eaux SDB', device_url=io://****-****-0891/9923380#1, controllable_name='io:AtlanticDomesticHotWaterProductionV2_AEX_IOComponent', definition=Definition(commands=CommandDefinitions(_commands=[CommandDefinition(command_name='advancedRefresh', nparams=1), CommandDefinition(command_name='delayedStopIdentify', nparams=1), CommandDefinition(command_name='getName', nparams=0), CommandDefinition(command_name='identify', nparams=0), CommandDefinition(command_name='refreshManufacturerName', nparams=0), CommandDefinition(command_name='refreshTargetTemperature', nparams=0), CommandDefinition(command_name='refreshWaterConsumption', nparams=0), CommandDefinition(command_name='setComfortTargetTemperature', nparams=1), CommandDefinition(command_name='setEcoTargetTemperature', nparams=1), CommandDefinition(command_name='setFrostProtectionTargetTemperature', nparams=1), CommandDefinition(command_name='setName', nparams=1), CommandDefinition(command_name='setTargetTemperature', nparams=1), CommandDefinition(command_name='startIdentify', nparams=0), CommandDefinition(command_name='stopIdentify', nparams=0), CommandDefinition(command_name='wink', nparams=1), CommandDefinition(command_name='pairOneWayController', nparams=2), CommandDefinition(command_name='refreshAwayModeDuration', nparams=0), CommandDefinition(command_name='refreshBoostModeDuration', nparams=0), CommandDefinition(command_name='refreshCurrentOperatingMode', nparams=0), CommandDefinition(command_name='refreshDHWCapacity', nparams=0), CommandDefinition(command_name='refreshDHWMode', nparams=0), CommandDefinition(command_name='refreshOperatingModeCapabilities', nparams=0), CommandDefinition(command_name='refreshRateManagement', nparams=0), CommandDefinition(command_name='setAwayModeDuration', nparams=1), CommandDefinition(command_name='setBoostModeDuration', nparams=1), CommandDefinition(command_name='setCurrentOperatingMode', nparams=1), CommandDefinition(command_name='setDHWMode', nparams=1), CommandDefinition(command_name='setHaltedTargetTemperature', nparams=1), CommandDefinition(command_name='setRateManagement', nparams=1), CommandDefinition(command_name='unpairAllOneWayControllers', nparams=0), CommandDefinition(command_name='unpairOneWayController', nparams=2)]), states=[StateDefinition(qualified_name='core:BoostModeDurationState', type='ContinuousState', values=None), StateDefinition(qualified_name='core:ComfortTargetTemperatureState', type='ContinuousState', values=None), StateDefinition(qualified_name='core:DHWPSoftwareVersionState', type='ContinuousState', values=None), StateDefinition(qualified_name='core:DiscreteRSSILevelState', type='DiscreteState', values=['good', 'low', 'normal', 'verylow']), StateDefinition(qualified_name='core:EcoTargetTemperatureState', type='ContinuousState', values=None), StateDefinition(qualified_name='core:FrostProtectionTargetTemperatureState', type='ContinuousState', values=None), StateDefinition(qualified_name='core:HaltedTargetTemperatureState', type='ContinuousState', values=None), StateDefinition(qualified_name='core:ManufacturerNameState', type='DataState', values=None), StateDefinition(qualified_name='core:MaximalShowerManualModeState', type='ContinuousState', values=None), StateDefinition(qualified_name='core:MaximalTemperatureManualModeState', type='ContinuousState', values=None), StateDefinition(qualified_name='core:MinimalShowerManualModeState', type='ContinuousState', values=None), StateDefinition(qualified_name='core:MinimalTemperatureManualModeState', type='ContinuousState', values=None), StateDefinition(qualified_name='core:NameState', type='DataState', values=None), StateDefinition(qualified_name='core:OperatingModeState', type='DiscreteState', values=['antifreeze', 'auto', 'away', 'eco', 'frostprotection', 'manual', 'max', 'normal', 'off', 'on', 'prog', 'program', 'boost']), StateDefinition(qualified_name='core:PriorityLockTimerState', type='ContinuousState', values=None), StateDefinition(qualified_name='core:RSSILevelState', type='ContinuousState', values=None), StateDefinition(qualified_name='core:SecuredPositionTemperatureState', type='ContinuousState', values=None), StateDefinition(qualified_name='core:StatusState', type='DiscreteState', values=['available', 'unavailable']), StateDefinition(qualified_name='core:TargetTemperatureState', type='ContinuousState', values=None), StateDefinition(qualified_name='core:TemperatureState', type='ContinuousState', values=None), StateDefinition(qualified_name='core:VersionState', type='ContinuousState', values=None), StateDefinition(qualified_name='core:WaterConsumptionState', type='ContinuousState', values=None), StateDefinition(qualified_name='io:AwayModeDurationState', type='ContinuousState', values=None), StateDefinition(qualified_name='io:DHWCapacityState', type='ContinuousState', values=None), StateDefinition(qualified_name='io:DHWModeState', type='DiscreteState', values=['autoMode', 'manualEcoActive', 'manualEcoInactive']), StateDefinition(qualified_name='io:OperatingModeCapabilitiesState', type='DataState', values=None), StateDefinition(qualified_name='io:PriorityLockLevelState', type='DiscreteState', values=['comfortLevel1', 'comfortLevel2', 'comfortLevel3', 'comfortLevel4', 'environmentProtection', 'humanProtection', 'userLevel1', 'userLevel2']), StateDefinition(qualified_name='io:PriorityLockOriginatorState', type='DiscreteState', values=['LSC', 'SAAC', 'SFC', 'UPS', 'externalGateway', 'localUser', 'myself', 'rain', 'security', 'temperature', 'timer', 'user', 'wind']), StateDefinition(qualified_name='io:RateManagementState', type='DiscreteState', values=['forbidden', 'no', 'recommended', 'unsuitable', 'wanted'])], widget_name='DomesticHotWaterProduction', ui_class='WaterHeatingSystem', qualified_name='io:AtlanticDomesticHotWaterProductionV2_AEX_IOComponent'), data_properties=None, widget=, ui_class=, states=States(_states=[State(name='core:NameState', type=, value='DHWP Actuator'), State(name='core:VersionState', type=, value='49373232383032202020'), State(name='core:PriorityLockTimerState', type=, value=0), State(name='core:StatusState', type=, value='available'), State(name='core:DiscreteRSSILevelState', type=, value='good'), State(name='core:RSSILevelState', type=, value=100.0), State(name='io:RateManagementState', type=, value='?'), State(name='io:OperatingModeCapabilitiesState', type=, value={'relaunch': 1, 'absence': 1, 'rate_management': 0, 'energy_demand_status': 1}), State(name='core:OperatingModeState', type=, value={'relaunch': 'off', 'absence': 'off'}), State(name='io:DHWModeState', type=, value='autoMode'), State(name='core:TemperatureState', type=, value=50.0), State(name='core:TargetTemperatureState', type=, value=50.0), State(name='core:BoostModeDurationState', type=, value=0), State(name='io:AwayModeDurationState', type=, value='0'), State(name='core:ManufacturerNameState', type=, value='Atlantic'), State(name='io:DHWCapacityState', type=, value=200)]), type=, place_oid='fa6c4710-b8c8-4d31-aaf1-26f6f3e6f9ba') Traceback (most recent call last): File "/config/custom_components/tahoma/coordinator.py", line 141, in _async_update_data device.states[state.name].value = self._get_state(state) File "/config/custom_components/tahoma/coordinator.py", line 187, in _get_state return caster(state.value) File "/usr/local/lib/python3.9/json/__init__.py", line 339, in loads raise TypeError(f'the JSON object must be str, bytes or bytearray, ' TypeError: the JSON object must be str, bytes or bytearray, not dict ```

Additional information

No response

iMicknl commented 2 years ago

Good catch. Our (breaking) update to pyoverkiz indeed requires changes to ha-tahoma, however we didn't have time to port it back yet.

See https://github.com/home-assistant/core/blob/dev/homeassistant/components/overkiz/coordinator.py. We already made them in core.