Closed oskari closed 1 year ago
@oskari, you observe that COMP_STATUS_ITEC is 19. This value is a binary number: 19 = 16 + 2 + 1, which means that:
1: COMP_VALUE_COMPR is on, i.e. the compressor is running. 2: COMP_VALUE_RADIATORPUMP is on, i.e. the radiator pump is running 16: COMP_VALUE_HEATING is on, i.e. the compressor is used for heating
So, this looks like normal behaviour.
But I don't think this library is currently reading it as so? I was expecting Compressor status
to be something else than None
? Am I missing something here or understood this wrong?
@oskari Seems that your heat pump has a different compressor status register name than others, which is why the compressor status for you is None
. The same with REG_PID
, it was not present for others, so I have not implemented it for others.
Thanks for the heads up, I will add support for your heat pump with the next release.
@klejejs Great, thanks! Is there anything else I could provide? Do you want the full debug.txt for this unit? It's an 2017 Thermia iTec
@oskari No, thanks! This is enough data for me unless there are any other values that you don't see and want to have in the API.
I believe this is the same for mine, which is an Atlas 18, even though im not sure if this is available. I dont believe i can see the data OP screenshoted, fx if the compressor is running in the dashboard.
Although i do see the Operational Status (Heating) which is why i guess its the same?
Using the genesis api:
Operational status
Operational status: None
Available operational statuses: None
Available operational statuses map: None
Auxiliary heater 3KW: None
Auxiliary heater 6KW: None
Auxiliary heater 9KW: None
Auxiliary heater 12KW: None
Auxiliary heater 15KW: None
Compressor status: None
Brine pump status: None
Radiator pump status: None
Cooling status: None
Hot water status: None
Heating status: None
Integral: None
Group REG_GROUP_OPERATIONAL_STATUS:
[
{
"canBeShownInGraph": false,
"canBeShownInHistory": true,
"collapsible": false,
"disabledByLink": false,
"falseText": null,
"graphRegisterIndex": 33663,
"groupId": 2,
"groupItemId": 39,
"groupItemOrder": 10000,
"groupName": "REG_GROUP_OPERATIONAL_STATUS",
"groupOrder": 10010,
"groupParentId": null,
"isComputedRegister": false,
"isInvisible": false,
"isReadOnly": true,
"maxValue": null,
"minValue": null,
"modifier": 0,
"precision": null,
"presentation": "Enumeration",
"registerId": 33663,
"registerIndex": 151,
"registerName": "REG_OPERATIONMODE",
"registerValue": 3,
"step": 1,
"stringRegisterValue": null,
"timeStamp": "2022-12-30T05:46:32.607Z",
"trueText": null,
"unit": "NotSpecified",
"valueNames": [
{
"confirmation": null,
"isReadonly": true,
"name": "REG_VALUE_OPERATION_MODE_OFF",
"value": 1,
"visible": true
},
{
"confirmation": "UI_OPERATION_MODE_AUX_HEATER_ONLY_WARNING",
"isReadonly": false,
"name": "REG_VALUE_OPERATION_MODE_SERVICE",
"value": 2,
"visible": false
},
{
"confirmation": "UI_OPERATION_MODE_AUX_HEATER_ONLY_WARNING",
"isReadonly": false,
"name": "REG_VALUE_OPERATION_MODE_AUX_HEATER_ONLY",
"value": 2,
"visible": true
},
{
"confirmation": null,
"isReadonly": false,
"name": "REG_VALUE_OPERATION_MODE_AUTO",
"value": 3,
"visible": true
}
]
},
{
"canBeShownInGraph": false,
"canBeShownInHistory": true,
"collapsible": false,
"disabledByLink": false,
"falseText": null,
"graphRegisterIndex": 33668,
"groupId": 2,
"groupItemId": 14584,
"groupItemOrder": 10002,
"groupName": "REG_GROUP_OPERATIONAL_STATUS",
"groupOrder": 10010,
"groupParentId": null,
"isComputedRegister": false,
"isInvisible": false,
"isReadOnly": true,
"maxValue": null,
"minValue": null,
"modifier": 0,
"precision": null,
"presentation": "MultipleStatusFlags",
"registerId": 33668,
"registerIndex": 1987,
"registerName": "REG_OPERATIONAL_STATUS_PRIORITY_BITMASK",
"registerValue": 8,
"step": 1,
"stringRegisterValue": null,
"timeStamp": "2022-12-30T07:56:32.388Z",
"trueText": null,
"unit": "NotSpecified",
"valueNames": [
{
"confirmation": null,
"isReadonly": false,
"name": "REG_VALUE_STATUS_MANUAL",
"value": 1,
"visible": true
},
{
"confirmation": null,
"isReadonly": false,
"name": "REG_VALUE_STATUS_DEFROST",
"value": 2,
"visible": false
},
{
"confirmation": null,
"isReadonly": false,
"name": "REG_VALUE_STATUS_HOTWATER",
"value": 4,
"visible": true
},
{
"confirmation": null,
"isReadonly": false,
"name": "REG_VALUE_STATUS_HEAT",
"value": 8,
"visible": true
},
{
"confirmation": null,
"isReadonly": false,
"name": "REG_VALUE_STATUS_COOL",
"value": 16,
"visible": true
},
{
"confirmation": null,
"isReadonly": false,
"name": "REG_VALUE_STATUS_POOL",
"value": 32,
"visible": true
},
{
"confirmation": null,
"isReadonly": false,
"name": "REG_VALUE_STATUS_LEGIONELLA",
"value": 64,
"visible": true
},
{
"confirmation": null,
"isReadonly": false,
"name": "REG_VALUE_STATUS_PASSIVE_COOL",
"value": 128,
"visible": true
},
{
"confirmation": null,
"isReadonly": false,
"name": "REG_VALUE_STATUS_STANDBY",
"value": 512,
"visible": true
},
{
"confirmation": null,
"isReadonly": false,
"name": "REG_VALUE_STATUS_NO_DEMAND",
"value": 1024,
"visible": true
},
{
"confirmation": null,
"isReadonly": false,
"name": "REG_VALUE_OPERATION_MODE_OFF",
"value": 2048,
"visible": true
}
]
}
]
@Gjorret I assume you already see this data in available_operation_modes
property, is that correct?
[
{
"confirmation": null,
"isReadonly": true,
"name": "REG_VALUE_OPERATION_MODE_OFF",
"value": 1,
"visible": true
},
{
"confirmation": "UI_OPERATION_MODE_AUX_HEATER_ONLY_WARNING",
"isReadonly": false,
"name": "REG_VALUE_OPERATION_MODE_SERVICE",
"value": 2,
"visible": false
},
{
"confirmation": "UI_OPERATION_MODE_AUX_HEATER_ONLY_WARNING",
"isReadonly": false,
"name": "REG_VALUE_OPERATION_MODE_AUX_HEATER_ONLY",
"value": 2,
"visible": true
},
{
"confirmation": null,
"isReadonly": false,
"name": "REG_VALUE_OPERATION_MODE_AUTO",
"value": 3,
"visible": true
}
]
The latest 3.7
version should include operational modes for your heat pumps and PID property for the ITec heat pump.
Running example.py
results in:
Operational status
Operational status: None
Traceback (most recent call last):
File "xxx/python-thermia-online-api/example.py", line 55, in <module>
"Available operational statuses: " + str(heat_pump.available_operational_statuses)
File "xxx/python-thermia-online-api/ThermiaOnlineAPI/model/HeatPump.py", line 572, in available_operational_statuses
data = self.__get_all_operational_statuses_from_operational_status()
File "xxx/python-thermia-online-api/ThermiaOnlineAPI/model/HeatPump.py", line 396, in __get_all_operational_statuses_from_operational_status
operation_modes_list = list(operation_modes_map)
File "xxx/python-thermia-online-api/ThermiaOnlineAPI/model/HeatPump.py", line 389, in <lambda>
values.get("value"): values.get("name").split(data["valueNamePrefix"])[
IndexError: list index out of range
@Gjorret I assume you already see this data in
available_operation_modes
property, is that correct?[ { "confirmation": null, "isReadonly": true, "name": "REG_VALUE_OPERATION_MODE_OFF", "value": 1, "visible": true }, { "confirmation": "UI_OPERATION_MODE_AUX_HEATER_ONLY_WARNING", "isReadonly": false, "name": "REG_VALUE_OPERATION_MODE_SERVICE", "value": 2, "visible": false }, { "confirmation": "UI_OPERATION_MODE_AUX_HEATER_ONLY_WARNING", "isReadonly": false, "name": "REG_VALUE_OPERATION_MODE_AUX_HEATER_ONLY", "value": 2, "visible": true }, { "confirmation": null, "isReadonly": false, "name": "REG_VALUE_OPERATION_MODE_AUTO", "value": 3, "visible": true } ]
Yes @klejejs, i believe so. Debug.txt attached. debug.txt
@Gjorret Do you see available operational statuses with the new version?
@oskari Sorry I made a mapping mistake. The new 3.8
version should fix the issue. Please try it out and report back 😉
Updated to 3.8
:
Operational status
Operational status: None
Available operational statuses: ValuesView(ChainMap({1: 'COMPR'}, {8: 'HOT_WATER'}, {16: 'HEATING'}, {32: 'DEFROST'}, {128: 'COOLING'}))
Available operational statuses map: ChainMap({1: 'COMPR'}, {8: 'HOT_WATER'}, {16: 'HEATING'}, {32: 'DEFROST'}, {128: 'COOLING'})
Auxiliary heater 3KW: None
Auxiliary heater 6KW: None
Auxiliary heater 9KW: None
Auxiliary heater 12KW: None
Auxiliary heater 15KW: None
Compressor status: None
Brine pump status: None
Radiator pump status: None
Cooling status: None
Hot water status: None
Heating status: None
Integral: None
@klejejs If there's any debug or api data I can provide, just let me know!
@oskari Thanks for the debug file. It is hard for me to test something that I personally do not see, so excuse me for many iterations. Can you please try version 3.9
and see if it fixes the issue?
@klejejs It's okay, that's why I'm asking if you need anything more :) If you want, I can get you the json api responses from thermia online if it helps?
example.py
in 3.9
:
Operational status
Traceback (most recent call last):
File "example.py", line 53, in <module>
print("Operational status: " + str(heat_pump.operational_status))
File "/home/oskarik/projektit/python-thermia-online-api/ThermiaOnlineAPI/model/HeatPump.py", line 573, in operational_status
data = self.__get_all_operational_statuses_from_operational_status()
File "/home/oskarik/projektit/python-thermia-online-api/ThermiaOnlineAPI/model/HeatPump.py", line 393, in __get_all_operational_statuses_from_operational_status
filter(lambda value: value.get("visible"), data["registerValues"])
KeyError: 'registerValues'
@oskari Thanks, I think I have everything, it's just that with these functions that I cannot test, I start making stupid mistakes. I should find time and write unit tests to ensure everything works correctly.
In any case, the new 3.10
version should hopefully now work :).
@klejejs
Traceback (most recent call last):
File "example.py", line 53, in <module>
print("Operational status: " + str(heat_pump.operational_status))
File "/home/oskarik/projektit/python-thermia-online-api/ThermiaOnlineAPI/model/HeatPump.py", line 573, in operational_status
data = self.__get_all_operational_statuses_from_operational_status()
File "/home/oskarik/projektit/python-thermia-online-api/ThermiaOnlineAPI/model/HeatPump.py", line 405, in __get_all_operational_statuses_from_operational_status
operation_modes_list = list(operation_modes_map)
File "/home/oskarik/projektit/python-thermia-online-api/ThermiaOnlineAPI/model/HeatPump.py", line 398, in <lambda>
values.get("value"): values.get("name").split(data["valueNamePrefix"])[
KeyError: 'valueNamePrefix'
I finally inderstand what @wouterse meant by status being a binary number :). Thanks for the tip @wouterse, I would have never figured that out. I will have to investigate how to properly implement that logic and return multiple statuses.
@oskari Version 3.11
is released. I think (hope :)) I figured it out. You should be seeing a list of active statuses now.
Great! Looks a lot more better now:
Operational status
Operational status: ['HEATING', 'RADIATORPUMP', 'COMPR']
Available operational statuses: ValuesView(ChainMap({1: 'COMPR'}, {2: 'RADIATORPUMP'}, {8: 'HOT_WATER'}, {16: 'HEATING'}, {32: 'DEFROST'}, {64: 'POOL'}, {128: 'COOLING'}))
Available operational statuses map: ChainMap({1: 'COMPR'}, {2: 'RADIATORPUMP'}, {8: 'HOT_WATER'}, {16: 'HEATING'}, {32: 'DEFROST'}, {64: 'POOL'}, {128: 'COOLING'})
Auxiliary heater 3KW: None
Auxiliary heater 6KW: None
Auxiliary heater 9KW: None
Auxiliary heater 12KW: None
Auxiliary heater 15KW: None
Compressor status: None
Brine pump status: None
Radiator pump status: None
Cooling status: None
Hot water status: None
Heating status: None
Integral: None
Pid: 16
Many years ago every byte used in a computer was valuable so you tried to squeeze as much information in every byte as possible. I was surprised to see that this technique was still used in this interface. Sorry for the confusing explanation of the binary value.
The code that I use is:
... mode = heat_pump.get_register_data_by_register_group_and_name("REG_GROUP_OPERATIONAL_STATUS", "COMP_STATUS")["value"] mode = mode & 0b111001 if mode == 8: heat pump_mode = "cooling" elif mode == 9: heat pump_mode = "pool" elif mode == 17: heat pump_mode = "hot water" elif mode == 33: heat pump_mode = "heating" elif heat pump_mode = "off" ....
The statement "mode = mode & 0b111001" gets rid of bit numbers 1 and 2 (bit counting starts at zero), for my heat pump these refer to the radiator pump and the brine pump. I'm not particularly interested in those. If you just want to know if the compressor (bit 0, "COMPR") is running you would use: mode = mode & 0b000001.
A few things:
in my case bit 5 (value 16) refers to hot water. I sometimes observe mode is 16 and sometimes mode is 17: 17 means that the compressor is actually switched on and and water is heated; 16 means that the compressor has not been switched on yet: the brine pump needs to run for a while and once it is switched on, the state will change to 17. Same happens for heating and pool heating. the bits have different meanings in different heat pumps, In my case HOT_WATER is 16; in Oskari's case HOT_WATER is 8. Fortunately you can get this from the Available operational statuses (map). In my case bit 3 (value 8) is used for both COOLING and POOL. Mode 9 will always mean POOL, Mode 8 may mean COOLING or POOL while the compressor has not been switched on yet.
And finally, you are already exposing the multi-value operational status. I would not know how to to present it in a better way than as e.g. ['HEATING', 'RADIATORPUMP', 'COMPR'] (taken from Askari''s message): Operational status Operational status: ['HEATING', 'RADIATORPUMP', 'COMPR'] Available operational statuses: ValuesView(ChainMap({1: 'COMPR'}, {2: 'RADIATORPUMP'}, {8: 'HOT_WATER'}, {16: 'HEATING'}, {32: 'DEFROST'}, {64: 'POOL'}, {128: 'COOLING'})) Available operational statuses map: ChainMap({1: 'COMPR'}, {2: 'RADIATORPUMP'}, {8: 'HOT_WATER'}, {16: 'HEATING'}, {32: 'DEFROST'}, {64: 'POOL'}, {128: 'COOLING'}) As an aside, I use the interface to measure the energy consumption of the heat pump. Unfortunately the heat pump does not provide this information, so I installed some current sensors. Every minute I read the operational status form the Thermia_api and get the average current (and hence wattage) for that minute. This way I know how much energy goes into heating, cooling, hot water and the pool.
Op 6 jan. 2023, om 00:40 heeft Krisjanis Lejejs @.***> het volgende geschreven:
I finally inderstand what @wouterse https://github.com/wouterse meant by status being a binary number :). Thanks for the tip @wouterse https://github.com/wouterse, I would have never figured that out. I will have to investigate how to properly implement that logic and return multiple statuses.
— Reply to this email directly, view it on GitHub https://github.com/klejejs/python-thermia-online-api/issues/14#issuecomment-1372933621, or unsubscribe https://github.com/notifications/unsubscribe-auth/AY4EXTNJ6RRELCDJB3AKZXDWQ5LWRANCNFSM6AAAAAATM5UL2E. You are receiving this because you were mentioned.
@wouterse thanks for the detailed explanation on this. I recently studied bitwise operations at university, so it is interesting to see how they are used in a real-life scenario. I would have never thought though that something like this would be still used too. @oskari Good to hear everything is finally working. Closing this issue now, if there are any more problems, please feel free to create a new issue.
@Gjorret Do you see available operational statuses with the new version?
Sorry for late reply, but yes, i now see the operational status:
Operational status
Operational status: STATUS_HEAT
Available operational statuses: ValuesView(ChainMap({1: 'STATUS_MANUAL'}, {2: 'STATUS_DEFROST'}, {4: 'STATUS_HOTWATER'}, {8: 'STATUS_HEAT'}, {16: 'STATUS_COOL'}, {32: 'STATUS_POOL'}, {64: 'STATUS_LEGIONELLA'}, {128: 'STATUS_PASSIVE_COOL'}, {512: 'STATUS_STANDBY'}, {1024: 'STATUS_NO_DEMAND'}, {2048: 'OPERATION_MODE_OFF'}))
Available operational statuses map: ChainMap({1: 'STATUS_MANUAL'}, {2: 'STATUS_DEFROST'}, {4: 'STATUS_HOTWATER'}, {8: 'STATUS_HEAT'}, {16: 'STATUS_COOL'}, {32: 'STATUS_POOL'}, {64: 'STATUS_LEGIONELLA'}, {128: 'STATUS_PASSIVE_COOL'}, {512: 'STATUS_STANDBY'}, {1024: 'STATUS_NO_DEMAND'}, {2048: 'OPERATION_MODE_OFF'})
Auxiliary heater 3KW: None
Auxiliary heater 6KW: None
Auxiliary heater 9KW: None
Auxiliary heater 12KW: None
Auxiliary heater 15KW: None
Compressor status: None
Brine pump status: None
Radiator pump status: None
Cooling status: None
Hot water status: None
Heating status: None
Integral: None
Example how its shown on thermia online (classic), unfortunately I couldn't change the UI language.
Running example.py / debug lists:
I think the related entry in debug.txt is: