Open mike-bike opened 3 months ago
Thanks for the enhancement request. Assuming you can help with testing again we can start coding as soon as someone finds some spare time :+1:
Absolutely! Just let me know when you have something ready to test. My PI2 test bed is always yours :-)
Happy Easter!
Kind regards Michael
Am 31.03.2024 um 15:12 schrieb David Pace @.***>:
Thanks for the enhancement request. Assuming you can help with testing again we can start coding as soon as someone finds some spare time 👍
— Reply to this email directly, view it on GitHub https://github.com/openhab/openhab-addons/issues/16590#issuecomment-2028719695, or unsubscribe https://github.com/notifications/unsubscribe-auth/AHVH7GBTL7ATBMQU3WAVTP3Y3ADTNAVCNFSM6AAAAABFM3A4SKVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMZDAMRYG4YTSNRZGU. You are receiving this because you authored the thread.
Hi @mike-bike, apparently the relay can have different configurations. I see the following supportedProfiles
in the JSON example above:
LIGHT
GENERIC
HEATING_RCC
From what I've learned in https://github.com/tschamm/boschshc-hass/issues/101, one of these modes (the "light" mode) features a "toggle" button and the impulse switch mode only has a "push" button.
Can you please check/answer the following:
Are there two or three modes that are supported?
Are the modes switched on hardware side or is this configured through the Bosch Smart Home App?
Can you confirm that the following services are advertised in "light/toggle" mode?
CommunicationQuality
PowerSwitch
ChildProtection
PowerSwitchProgram
ElectricalFaults
SwitchConfiguration
Linking
and the following services in "impulse switch" mode?
CommunicationQuality
ImpulseSwitch
ChildProtection
ElectricalFaults
If there is a third mode, can you post which services are advertised in this mode?
I'd need to check the logs to confirm the services/responses when the configuration changes. Maybe I find some time later today or tomorrow.
I am trying to answer your other questions:
PowerSwitchProgram
)
SwitchConfiguration
) are the same for all 4 modes above. I'd assume these to be the same as for the other BOSCH controller devices: It tells the device if a impulse (Taster) or on/off (Wippschalter) switch is connected to change mode - i.e. toggle state with each electric impulse or by on/off changeElectricalFaults
and could not find anything in the app. Potentially a counter or flag which indicates that the power has been interrupted and the relays is in Off-state again...?I will amend my findings after reviewing the logs
Hi @david-pace, after reviewing my previous post, I do not think you need to worry much about the relay's device configuration. I think these parameters only drives the BOSCH bridge/app internal functionality:
From thing's perspective I'd see it as just an on/off switch. The SwitchConfiguration
defines the type of physically wired switch, so that the device would switch on/off on electrical impulse (Taster) or current (Wippschalter). Neither is relevant for openHAB other than information only - though an item connected to the SwitchConfiguration
or PowerSwitchPorgram
could be used for presentation purposes - e.g. display different icons for the switch state; but at the end of the day it is ON
and OFF
only.
Though it would be nice to expose the timer
to automatically switch off. This is available in multiple BOSCH devices. With that, openHAB could change the timer based on other conditions (e.g. time of day / year, etc).
Still wondering about ElectricalFaults
and Linking
.
Unfortunately I cannot complete the testing because I do not have a Room Thermostat available to configure Electrical / Boiler modes. Again, I don't think it will differ based on my findings above.
I have tried different configuration, but the result seem to be always the same. We probably need to have a thing configured to get more details if needed:
{"@type":"device","rootDeviceId":"64-da-a0-10-83a7",
"id":"hdm:ZigBee:30fb10fffe46d732",
"deviceServiceIds["CommunicationQuality","PowerSwitch","ChildProtection","PowerSwitchProgram","ElectricalFaults","SwitchConfiguration","Linking"],
"manufacturer":"BOSCH",
"roomId":"hz_16",
"deviceModel":"MICROMODULE_RELAY",
"serial":"30FB10FFFE46D732",
"profile":"GENERIC","iconId":"ip_heat_pump",
"name":"Relais Test",
"status":"AVAILABLE",
"childDeviceIds":[],
"supportedProfiles":["HEATING_RCC","LIGHT","GENERIC"]}
Thank you for the information, @mike-bike :+1: In this case I would propose to implement a minimal set of services and then provide a test JAR. Then you can test with the hardware how the individual services react in which mode.
Sounds like a plan 😀 Regards Michael
Hi @mike-bike, good news, I have a first implementation ready that you can test 😎
Here is the link to the Test JAR.
I think you already know the testing procedure, but if you have any doubts or questions please let me know :+1: I'm excited to hear what already works and what does not work 😉
Hi @david-pace, refreshed the test-bed and loaded the new JAR.
I think, I experienced similar issues as with the first test of the Light Switch II. I recall, that you quickly have identified the root cause and provided a fix. So I am expecting nothing serious.
Good progress! Regards, Mike
Quick summary:
PowerSwitch: Switching On/Off is working in openHAB Changes in Bosch App are not reflected in openHAB
Childprotection: Setting ChildProtection in openHAB changes state in Bosch App Changes to ChildProtection in Bosch App is not reflected in openHAB
PowerSwitch Program: Not sure about the purpose. Should it be a status indicator from the Bosch device whether it is running timer controlled or manually? Changing state in openHAB does not change anything in the App or vice versa (Toggle between Manual/Automatic?) Anyway, the same service should be available for many other Bosch devices as well. So I'd suggest a consistent approach.
ImpulsSwitch is not working Honestly I do not know, how this should be reflected in openHAB. I am not aware of an Impuls Switch as a device in openHAB. Technically this should be a push-button which one can preset and it will then be automatically release to toggle a state. I’d consider a more deterministic approach more useful: opening or closing the relays, rather than toggle into an unknown state. This could be mimicked by a run if needed.
After unlinking and removing ImpulseSwitch Item, Thing turned immediately into GREEN
Error in Thing:
COMMUNICATION_ERROR
Error when trying to refresh state from service ImpulseSwitch: State request with URL https://192.168.2.61:8444/smarthome/devices/hdm:ZigBee:30fb10fffe46d732/services/ImpulseSwitch/state failed with status code 404 and error code ENTITY_NOT_FOUND
deviceID: hdm:ZigBee:30fb10fffe46d732 type: MICROMODULE_RELAY -> relay
service: CommunicationQuality -> communicationquality
service: PowerSwitch -> powerswitch
service: ChildProtection -> childprotection
service: PowerSwitchProgram -> powerswitchprogram
service: ElectricalFaults -> !UNSUPPORTED!
service: SwitchConfiguration -> !UNSUPPORTED!
service: Linking -> !UNSUPPORTED!
Thanks for the initial test 👍 Could you please look in your logs for example requests/responses for the relevant services? You can identify them by the following @type
attributes (or at least similar types, spelling might be a bit different):
"@type": "powerSwitchState"
"@type": "ChildProtectionState"
"@type": "powerSwitchProgramState"
"@type": "impulseSwitchState"
I need to know the exact spelling and a few examples of complete requests and/or responses if possible.
Not sure if that is what you are looking for. I found the binding to be reverted to the supplied one. I have stopped openHAB, clean-cache, and restarted. Then upgraded the binding again.
openhab> bundle:update 275 file:///home/openhabian/addons/org.openhab.binding.boschshc-4.2.0-SNAPSHOT-relay.jar
openhab> list | grep -i bosch
275 │ Active │ 80 │ 4.2.0.202404121436 │ openHAB Add-ons :: Bundles :: Bosch Smart Home Binding
Interestingly, during a short period Switch, Child Protection, and PowerSwitchProgram were working in both directions. Then suddenly, it stopped... Very strange - changes in Bosch App get not reflected in openHAB. There are also no traces in the log on changes in the App. Please see snippets below and let me know if I'd need to change something or investigate further.
Switching off/on in Bosch App
2024-04-12 23:03:14.279 [DEBUG] [nternal.devices.bridge.BridgeHandler] - Got update for service PowerSwitch of type DeviceServiceData: {"@type":"powerSwitchState","automaticPowerOffTime":0,"switchState":"OFF"}
2024-04-12 23:03:19.886 [DEBUG] [.internal.devices.bridge.LongPolling] - Long poll response: {"result":[{"path":"/devices/hdm:ZigBee:30fb10fffe46d732/services/PowerSwitch","@type":"DeviceServiceData","id":"PowerSwitch","state":{"@type":"powerSwitchState","automaticPowerOffTime":0,"switchState":"ON"},"deviceId":"hdm:ZigBee:30fb10fffe46d732"}],"jsonrpc":"2.0"}
2024-04-12 23:03:19.887 [DEBUG] [nternal.devices.bridge.BridgeHandler] - Got update for service PowerSwitch of type DeviceServiceData: {"@type":"powerSwitchState","automaticPowerOffTime":0,"switchState":"ON"}
Switching Manual/Automatic in Bosch App
2024-04-12 23:05:09.295 [DEBUG] [nternal.devices.bridge.BridgeHandler] - Got update for service PowerSwitchProgram of type DeviceServiceData: {"schedule":{"profiles":[{"switchPoints":[{"startTimeMinutes":0,"value":{"@type":"switchStateSwitchPointValue","switchState":"OFF"}}],"day":"MONDAY"},{"switchPoints":[{"startTimeMinutes":0,"value":{"@type":"switchStateSwitchPointValue","switchState":"OFF"}}],"day":"TUESDAY"},{"switchPoints":[{"startTimeMinutes":0,"value":{"@type":"switchStateSwitchPointValue","switchState":"OFF"}}],"day":"WEDNESDAY"},{"switchPoints":[{"startTimeMinutes":0,"value":{"@type":"switchStateSwitchPointValue","switchState":"OFF"}}],"day":"THURSDAY"},{"switchPoints":[{"startTimeMinutes":0,"value":{"@type":"switchStateSwitchPointValue","switchState":"OFF"}}],"day":"FRIDAY"},{"switchPoints":[{"startTimeMinutes":0,"value":{"@type":"switchStateSwitchPointValue","switchState":"OFF"}}],"day":"SATURDAY"},{"switchPoints":[{"startTimeMinutes":0,"value":{"@type":"switchStateSwitchPointValue","switchState":"OFF"}}],"day":"SUNDAY"}]},"operationMode":"SCHEDULE","@type":"powerSwitchProgramState"}
2024-04-12 23:05:13.046 [DEBUG] [.internal.devices.bridge.LongPolling] - Long poll response: {"result":[{"path":"/devices/hdm:ZigBee:30fb10fffe46d732/services/PowerSwitchProgram","@type":"DeviceServiceData","id":"PowerSwitchProgram","state":{"schedule":{"profiles":[{"switchPoints":[{"startTimeMinutes":0,"value":{"@type":"switchStateSwitchPointValue","switchState":"OFF"}}],"day":"MONDAY"},{"switchPoints":[{"startTimeMinutes":0,"value":{"@type":"switchStateSwitchPointValue","switchState":"OFF"}}],"day":"TUESDAY"},{"switchPoints":[{"startTimeMinutes":0,"value":{"@type":"switchStateSwitchPointValue","switchState":"OFF"}}],"day":"WEDNESDAY"},{"switchPoints":[{"startTimeMinutes":0,"value":{"@type":"switchStateSwitchPointValue","switchState":"OFF"}}],"day":"THURSDAY"},{"switchPoints":[{"startTimeMinutes":0,"value":{"@type":"switchStateSwitchPointValue","switchState":"OFF"}}],"day":"FRIDAY"},{"switchPoints":[{"startTimeMinutes":0,"value":{"@type":"switchStateSwitchPointValue","switchState":"OFF"}}],"day":"SATURDAY"},{"switchPoints":[{"startTimeMinutes":0,"value":{"@type":"switchStateSwitchPointValue","switchState":"OFF"}}],"day":"SUNDAY"}]},"operationMode":"MANUAL","@type":"powerSwitchProgramState"},"deviceId":"hdm:ZigBee:30fb10fffe46d732"}],"jsonrpc":"2.0"}
2024-04-12 23:05:13.047 [DEBUG] [nternal.devices.bridge.BridgeHandler] - Got update for service PowerSwitchProgram of type DeviceServiceData: {"schedule":{"profiles":[{"switchPoints":[{"startTimeMinutes":0,"value":{"@type":"switchStateSwitchPointValue","switchState":"OFF"}}],"day":"MONDAY"},{"switchPoints":[{"startTimeMinutes":0,"value":{"@type":"switchStateSwitchPointValue","switchState":"OFF"}}],"day":"TUESDAY"},{"switchPoints":[{"startTimeMinutes":0,"value":{"@type":"switchStateSwitchPointValue","switchState":"OFF"}}],"day":"WEDNESDAY"},{"switchPoints":[{"startTimeMinutes":0,"value":{"@type":"switchStateSwitchPointValue","switchState":"OFF"}}],"day":"THURSDAY"},{"switchPoints":[{"startTimeMinutes":0,"value":{"@type":"switchStateSwitchPointValue","switchState":"OFF"}}],"day":"FRIDAY"},{"switchPoints":[{"startTimeMinutes":0,"value":{"@type":"switchStateSwitchPointValue","switchState":"OFF"}}],"day":"SATURDAY"},{"switchPoints":[{"startTimeMinutes":0,"value":{"@type":"switchStateSwitchPointValue","switchState":"OFF"}}],"day":"SUNDAY"}]},"operationMode":"MANUAL","@type":"powerSwitchProgramState"}
Childprotection in Bosch App
2024-04-12 23:10:18.450 [DEBUG] [.internal.devices.bridge.LongPolling] - Long poll response: {"result":[{"path":"/devices/hdm:ZigBee:30fb10fffe46d732/services/ChildProtection","@type":"DeviceServiceData","id":"ChildProtection","state":{"@type":"ChildProtectionState","childLockActive":false},"deviceId":"hdm:ZigBee:30fb10fffe46d732"}],"jsonrpc":"2.0"}
2024-04-12 23:10:18.452 [DEBUG] [nternal.devices.bridge.BridgeHandler] - Got update for service ChildProtection of type DeviceServiceData: {"@type":"ChildProtectionState","childLockActive":false}
2024-04-12 23:10:18.484 [DEBUG] [nternal.devices.bridge.BridgeHandler] - Found handler org.openhab.binding.boschshc.internal.devices.relay.RelayHandler@795eb0, calling processUpdate() for service ChildProtection with state {"@type":"ChildProtectionState","childLockActive":false}
Thanks for looking into the log files :+1:
First, a few general explanations:
PowerSwitchProgram
service was indeed meant to switch from manual operation mode to scheduled mode. But probably we should not implement this for now (see below)power-switch
channel can be used and if there is an impulse switch configuration the impulse-switch
channel is used, only accepting ON
commands. Is this sufficient or do you have a better idea maybye?So far I have identified 2 issues:
PowerSwitchProgram
service assumes the wrong values for the operationMode
. I assumed MANUAL
and AUTOMATIC
(my source was https://github.com/tschamm/boschshcpy/blob/master/boschshcpy/services_impl.py#L350), but it seems to be MANUAL
and SCHEDULE
. In any case, this service is not documented by Bosch and the request/response content seems to be much more complex, containing the whole schedule data. I don't know if we mess the schedules up if we don't send them. In this case I would say we skip this service for now and think of a better solution later, as you suggested.ImpulseSwitch
needs to be write-only, but my generic service implementation supports read and write operations. If you unlink and re-link a channel, openHAB triggers a REFRESH
command which will actively fetch the current state. This needs to be prevented in case of the impulse-switch
channel.I will provide a new JAR with fixes for these issues as soon as I find some time.
And I have two questions:
long poll failure
, long poll cancelled
etc. entries.You are right. All Updates from Bosch are broken. Will check this afternoon Gruß Michael
I do not think PowerSwitchProgram
is really needed. Though, it would be cool changing the schedules from openHAB. But I agree it is probably not worth the effort. Any UI would be complex, but it might be an interesting option pushing sets of predefined schedules to thermostats, switches, etc...
I'd assume ImpulseSwitch
is not required. In my opinion it is showing the type of the wired switch with 3 options: No switch, Switch (Schalter), ImpulseSwitch (Taste). It just drives the behavior of the relay. Does it change state with each Impuls, or does it stay on as long there is current on the switch input. Similar configuration is available for Light/Rollershutter II module.
Did I understand correctly that when the Bosch -> openHAB communication fails, the other direction (openHAB -> Bosch) still works?
Yes, this is correct understanding. On/Off Switch item is working, but does not show changes from Bosch app.
If this happens, do you still get updates for all your other devices? If not, I suppose that the long poll fails for some reason. You could check your log for any long poll failure, long poll cancelled etc. entries.
Last Long Poll response was PowerSwitchProgram
response and then no more. There is no poll error message even with TRACE on.
Thing switches into error when linking item to ImpulsSwitch channel:
COMMUNICATION_ERROR
Error when trying to refresh state from service ImpulseSwitch: State request with URL https://192.168.2.61:8444/smarthome/devices/hdm:ZigBee:30fb10fffe46d732/services/ImpulseSwitch/state failed with status code 404 and error code ENTITY_NOT_FOUND
I am going to stay away from these dangerous items... A bundle:restart
on the console brought long poll
back to life and Power-Switch
and Child-Protection
are working again in both ways.
I just uploaded a new JAR with a few enhancements and fixes (under the same link). Please delete your channels and the relay thing before you download the new JAR.
Changes:
power-switch-program
channel and the corresponding service completelyimpulse-switch
is now a write-only channel and will (hopefully) not fail (do nothing) when the state should be readimpulse-switch
state is now sent to Smart Home Controller with a POST
request instead of PUT
impulse-switch
state can be set to true
with an ON
command and to false
with an OFF
command (does that make sense from your perspective? ON
= press, OFF
= release?)I have a theory about the impulse switch service, maybe you can help me verify whether it's correct: In my opinion we need the impulse switch channel and service, because I don't think Bosch would advertise a service that is completely useless. This is also indicated in https://github.com/tschamm/boschshc-hass/issues/101.
So my theory is that the relay can be operated with the ImpulseSwitch
service when configured in impulse switch mode, and otherwise with the PowerSwitch
service. Could you please change the configuration of your relay and check how it behaves when you send commands to both of the services, respectively?
I'm excited to learn whether if it works better with the new version and if I was able to mitigate the long poll issues.
Ok, now I slowly understand. I was confused because the relay need to be configured differently during the initial training in the Bosch app. My bad - I did not realized that. During first initialization in the Bosch App, you need to define the "mode" of the relay:
PowerSwitch
- keeps open or closed state until changed, orImpulseSwitch
- closes the relay for a pre-configured time and then automatically opens it againYou cannot switch between both modes in the Bosch app. I had to remove the device and reconfigure. Now the app does no longer provide On/Off toggles but only a pushbutton. When I press it, the relay close for the 1 sec (configured time between 0.5 and 20secs) and then opens again.
I tested the binding with the relay in PowerSwitch
configuration. Signal-Strength recognized the correct value. On/Off and Child-Protection switches were correctly working in both ways.
Then I deleted the device from the app and re-connected it selecting "Impulse Mode" during setup. I have unlinked the items and deleted the thing. Triggered rediscovery, added thing and relinked items: that messed up the long-poll and I could not get anything working with the items (Child-Protection was working at the beginning). Need to re-do in a more structured approach.
boschshc deviceInfo | less
might give a bit more insights:
deviceID: hdm:ZigBee:30fb10fffe46d732
type: MICROMODULE_RELAY -> relay
service: CommunicationQuality -> communicationquality
service: ImpulseSwitch -> impulseswitch
service: ChildProtection -> childprotection
service: ElectricalFaults -> !UNSUPPORTED!
In that configuration there is no PowerSwitch
service. Which makes sense: PowerSwitch
and ImpulseSwitch
are mutually exclusive. That needs to be reflected in the thing. Pending on the configuration, I think you would either need to expose one or the other channel. PowerSwitch
could become a read/only status item, during the period the relay is closed.
In current configuration, the ImpulsSwitch
triggers on ON
2024-04-14 17:47:34.477 [TRACE] [ernal.devices.bridge.BoschHttpClient] - create request for https://192.168.2.61:8444/smarthome/devices/hdm:ZigBee:30fb10fffe46d732/services/ImpulseSwitch/state and content {"impulseState":true,"stateType":"impulseSwitchState","@type":"impulseSwitchState"}
and on OFF
2024-04-14 17:47:38.342 [TRACE] [ernal.devices.bridge.BoschHttpClient] - create request for https://192.168.2.61:8444/smarthome/devices/hdm:ZigBee:30fb10fffe46d732/services/ImpulseSwitch/state and content {"impulseState":false,"stateType":"impulseSwitchState","@type":"impulseSwitchState"}
but the relay does not switch at all. When I press the push button in the app the following is visible in the log:
2024-04-14 17:52:23.633 [DEBUG] [.internal.devices.bridge.LongPolling] - Long poll response: {"result":[{"path":"/devices/hdm:ZigBee:30fb10fffe46d732/services/ImpulseSwitch","operations":["sendImpulse"],"@type":"DeviceServiceData","id":"ImpulseSwitch","state":{"impulseLength":100,"instantOfLastImpulse":"2024-04-14T15:52:31.677366Z","@type":"ImpulseSwitchState","impulseState":true},"deviceId":"hdm:ZigBee:30fb10fffe46d732"}],"jsonrpc":"2.0"}
2024-04-14 17:52:23.635 [DEBUG] [nternal.devices.bridge.BridgeHandler] - Got update for service ImpulseSwitch of type DeviceServiceData: {"impulseLength":100,"instantOfLastImpulse":"2024-04-14T15:52:31.677366Z","@type":"ImpulseSwitchState","impulseState":true}
2024-04-14 17:52:23.665 [DEBUG] [nternal.devices.bridge.BridgeHandler] - Found handler org.openhab.binding.boschshc.internal.devices.relay.RelayHandler@c6bfd2, calling processUpdate() for service ImpulseSwitch with state {"impulseLength":100,"instantOfLastImpulse":"2024-04-14T15:52:31.677366Z","@type":"ImpulseSwitchState","impulseState":true}
2024-04-14 17:52:23.761 [DEBUG] [.internal.devices.bridge.LongPolling] - Long poll response: {"result":[{"path":"/devices/hdm:ZigBee:30fb10fffe46d732/services/ImpulseSwitch","operations":["sendImpulse"],"@type":"DeviceServiceData","id":"ImpulseSwitch","state":{"impulseLength":100,"instantOfLastImpulse":"2024-04-14T15:52:49.882144Z","@type":"ImpulseSwitchState","impulseState":true},"deviceId":"hdm:ZigBee:30fb10fffe46d732"}],"jsonrpc":"2.0"}
2024-04-14 17:52:23.763 [DEBUG] [nternal.devices.bridge.BridgeHandler] - Got update for service ImpulseSwitch of type DeviceServiceData: {"impulseLength":100,"instantOfLastImpulse":"2024-04-14T15:52:49.882144Z","@type":"ImpulseSwitchState","impulseState":true}
2024-04-14 17:52:23.778 [DEBUG] [nternal.devices.bridge.BridgeHandler] - Found handler org.openhab.binding.boschshc.internal.devices.relay.RelayHandler@c6bfd2, calling processUpdate() for service ImpulseSwitch with state {"impulseLength":100,"instantOfLastImpulse":"2024-04-14T15:52:49.882144Z","@type":"ImpulseSwitchState","impulseState":true}
and after the defined duration (here 10 seconds - the config seems to use 0.1th seconds i.e. 100) the relay turns off:
2024-04-14 17:52:33.502 [DEBUG] [.internal.devices.bridge.LongPolling] - Long poll response: {"result":[{"path":"/devices/hdm:ZigBee:30fb10fffe46d732/services/ImpulseSwitch","operations":["sendImpulse"],"@type":"DeviceServiceData","id":"ImpulseSwitch","state":{"impulseLength":100,"instantOfLastImpulse":"2024-04-14T15:52:49.882144Z","@type":"ImpulseSwitchState","impulseState":false},"deviceId":"hdm:ZigBee:30fb10fffe46d732"}],"jsonrpc":"2.0"}
2024-04-14 17:52:33.503 [DEBUG] [nternal.devices.bridge.BridgeHandler] - Got update for service ImpulseSwitch of type DeviceServiceData: {"impulseLength":100,"instantOfLastImpulse":"2024-04-14T15:52:49.882144Z","@type":"ImpulseSwitchState","impulseState":false}
2024-04-14 17:52:33.534 [DEBUG] [nternal.devices.bridge.BridgeHandler] - Found handler org.openhab.binding.boschshc.internal.devices.relay.RelayHandler@c6bfd2, calling processUpdate() for service ImpulseSwitch with state {"impulseLength":100,"instantOfLastImpulse":"2024-04-14T15:52:49.882144Z","@type":"ImpulseSwitchState","impulseState":false}
It seems that the push-button requires a more complex command to fire... Getting it to work will still leave the same questions as discussed in the HA article.
May I propose the following:
PowerSwitch configuration
Only expose PowerSwitch
, Child-Protection
and SignalStrength
as channels. The thing may have a property mode=PowerSwitch
ImpulseSwitch configuration:
Thing property mode=Impulse
.
Expose ImpulseSwitchState
(point), pulseLength
(set-point), instantOfLastImpulse
(point), Child-Protection
(switch) and SignalStrength
(point) as channels. There also needs to be a channel to fire the button with (a user defined) duration.
ImpulseSwitchState
changes to ON
and waits for the update on the long poll, when the relay turns off.
We could then configure a switch-item in the UI and sync it with ImpulseSwitchState
in an event-rule.
Regards, Michael
Thank you for this analysis :+1: So my theory that only one of the services is available/used was correct. But the impulse switch is more complex than I thought.
I will think about how we can configure the channels automatically based on the configured mode/profile. Could you please help me determine all the possible identifiers for the profile
property? According to https://github.com/openhab/openhab-addons/issues/16590#issue-2213324792 there are 3 different profiles (LIGHT
, GENERIC
, HEATING_RCC
). But are there also three modes that you can choose during the setup of the device, or only two? I need to know all possible profile
identifiers and whether they work with the ImpulseSwitch
or the PowerSwitch
service.
Thanks to your log output I can now properly send and receive messages for the ImpulseService
. I will implement the property and the channels as proposed. I have an idea how this could be implemented without the need for an additional event rule. We can experiment with the solution and you can tell me what you think as soon as I find some time to write the code and upload a new JAR.
Hi @david-pace, I am happy to help. I'd consider the two modes PowerSwitch
and ImpulsSwitch
as two different devices pending on the configuration (Similar to the Lightswitch/Rollershutter II device). As they serve two different purposes, we could assume the chosen configuration to be fairly static. May I suggest you to store the mode as Thing property and use that in the code to void / disable the inappropriate channels if not generating two separate versions as with the Light/Shutter II devices?
I think you have summarized the variations correctly in your post above
PowerSwitch Mode:
The profiles LIGHT
, GENERIC
, and HEATING_RCC
do only exist in PowerSwitch
mode. Actually the App offers 4 choices: Standard
, Leuchte
, Elektroheizung
, and Boiler
. Unfortunately I cannot configure Elektroheizung
or Boiler
as it requires a room-thermostat which I do not have. According to the text in the app, the only difference between both is the delay to turn off the relay. Elektroheizung
has a 5 minute interval and Boiler
has 10 minute interval to automatically switch off the relay after reaching the temp limit (from the thermostat).
Please note, that the PlugCompact (Zwischenstecker Kompakt) also supports the same three profiles, but with only three options in the app: choices: Standard
, Leuchte
, Elektroheizung
. The 4th option Boiler
is missing. I am going to check later if the config would allow to set heating
without a thermostat... Need to unplug the device.
From openHAB perspective all 4 profiles should work the same: an On/Off switch turns the relay on and off.
Profile LIGHT
would appear as room-light in the Bosch app and scenes and will switch with the virtual Raumlicht
button. Profile GENERIC
does not show up as a room light and does not change the state when Raumlicht
is selected.
In addition the app allow to set a time limit between 0 and 60 minutes to automatically turn off again:
getState(): Request complete: [{"@type":"powerSwitchState","switchState":"ON","automaticPowerOffTime":0}]
I do not know how the heating modes will be displayed. It could be, that they are linked to a Climate Control. I will ask around if I could borrow a room-thermostat.
ImpulsSwitch Mode:
In that mode, the app only offers a stateless push-button which turns the relay on. After a predefined interval, the relay automatically turns off again. There are no profiles to chose from - aka only GENERIC
2024-04-15 19:15:31.227 [TRACE] [rnal.discovery.ThingDiscoveryService] - - got thingUID 'boschshc:relay:bshc01:hdm_ZigBee_30fb10fffe46d732' for device: 'Type device; RootDeviceId: 64-da-a0-10-83-a7;
Id: hdm:ZigBee:30fb10fffe46d732;
Device Service Ids: CommunicationQuality, ImpulseSwitch, ChildProtection, ElectricalFaults;
Manufacturer: BOSCH; Room Id: hz_16; Device Model: MICROMODULE_RELAY;
Serial: 30FB10FFFE46D732;
Profile: GENERIC; Name: Relais Impuls Test; Status: AVAILABLE; Child Device Ids: '
Thank you for the detailed update :heart:
I think we should go for the property-based approach. I was trying to figure out a criteria to detect whether the relay is configured as regular power switch or impulse switch.
My idea was to check the profile value, but now I understood that my idea does not work. I thought we always have the same list of available profiles, but these also change depending on the configuration.
My new approach would be to check the list of device services. If ImpulseSwitch
is in the list, we know that the device was configured as impulse switch, otherwise as a regular PowerSwitch
. Or do you have a better idea for detection criteria?
Hi David, looking for the device services shall be the right method. Pending on the configuration it should either offer service: PowerSwitch
or service: ImpulseSwitch
.
Hi David, not sure if it is really related, but I feel that calling inappropriate service kills the long-poll process. I just found the updates from Bosch binding missing since yesterday 23:13. I had the thing configured as ImpulseSwitch and in the late evening changed the configuration of the relay back to PowerSwitch. I have missed to unlink the items and re-creation f the thing...
2024-04-16 23:13:35.369 [DEBUG] [.internal.devices.bridge.LongPolling] - Long poll response: {"result":[{"deleted":true,"@type":"Dev
iceServiceData","id":"CommunicationQuality","deviceId":"hdm:ZigBee:30fb10fffe46d732"}],"jsonrpc":"2.0"}
2024-04-16 23:13:35.371 [WARN ] [mmon.WrappedScheduledExecutorService] - Scheduled runnable ended with an exception:
java.lang.NullPointerException: Cannot invoke "com.google.gson.JsonElement.getAsString()" because the return value of "com.google.gs
on.JsonObject.get(String)" is null
at org.openhab.binding.boschshc.internal.serialization.BoschServiceDataDeserializer.deserialize(BoschServiceDataDeserializer
.java:51) ~[?:?]
It seems that the code is sensitive to the long poll responses and cannot recover from an error or unexpected result. Note: The device needed to be deleted in the Bosch app and then added again.
Hi @mike-bike, I uploaded a new version of the JAR. Please unlink the channels and delete the thing before updating it.
Changes:
mode
property to the thing (possible values: PowerSwitch
or ImpulseSwitch
)impulse-length
that configures the impulse length in deciseconds as specified. This will also directly trigger an impulse switch. Let me know if you would prefer that this only sets the length internally, so that the user has to trigger the impulse-switch
manually.instant-of-last-impulse
with the timestamp of the last impulseExcited to hear whether it works better now 😎
Hi @david-pace, I have downloaded new JAR, unlinked all items and deleted the thing. Then updated binding with new JAR.
PowerSwitch Mode:
mode=PowerSwitch
signal-strength
, child-protection
and power-switch
but also impulse-switch
, impulse-length
and instant-of-last-impulse
which were not expected.signal-strength
shows correct value, child-protection
and power-switch
working in both directions. I have not touched the 3 impulse channels.Then unlink items and deleted thing in openHAB and device in Bosch app. Reconfigured relais in
ImpulseSwitch Mode:
mode=ImpulseSwitch
signal-strength
, child-protection
, power-switch
, impulse-switch
, impulse-length
and instant-of-last-impulse
. I would not have expected power-switch
in impulse mode.power-switch
child-protection
working as expectedsignal-strength
seems to behave a bit odd. I was expecting good
(3) but item sticked to excellent
as previous value. Event log shows correct value. Translation?
2024-04-20 13:18:43.052 [INFO ] [openhab.event.ItemStateChangedEvent ] - Item 'BSHC_RS03_Signalstarke' changed from 0 to 3
impulse-switch
working in both directions. Switch in openHAB stays on until relay switches off again. GREAT!impulse-length
was updated with 20 (2s) according to Bosch app. Value also gets updated with change in Bosch app.instant-of-last-impulse
is updated with last eventOverall, great progress. I am going to test setting impulse-length
from openHAB later today and provide a summary.
Regards, Michael
Hi @david-pace, I tried to test with impulse-length
. Neither assignment (update) or command does change the value in Bosch app or triggers on/off cycle. Though updates from Bosch app gets reflected.
New channel
impulse-length
that configures the impulse length in deciseconds as specified. This will also directly trigger an impulse switch. Let me know if you would prefer that this only sets the length internally, so that the user has to trigger the impulse-switch manually.
The way impulse-switch
is working, is absolutely fine for me. I'd prefer updating impulse-length
and fire the cycle with the switch. It will also have the advantage, that you could change the duration without triggering the event; this is same experience in the App.
However, I was not able to update the duration to become visible in the App. Tried both: update and send-command. Changes in the App gets reflected in the item immediately!
In summary:
mode=PowerSwitch
none of the impulse-
should be available, and with Impulse-Switch
the PowerSwitch
channel does not make sense.impulse-length
should be ds
rather than s
- if it is working as expected it should default to setpoint
rather than point
- actually I have not seen that working correctly before on any other channel. Might be an UI or code/framework issue with openHAB. Following my comment above I'd prefer not to trigger the event. On/Off works with impulse-switch
perfectly fine.Many thanks for the great work. In summary it would be working for me. However, invalid channels could confuse the user. Please advise, how I should update the impulse-length
to become reflected into the app. I have quickly trie via a rule to update / send-command with both failed.
I will be on vacation starting on Monday and returning on May-1st. Please expect my delayed response on further testing.
Regards, Michael
Thanks for the detailed tests ❤️
When you are back from your vacation, you can test the new JAR I uploaded.
Fixes:
impulse-length
should now be ds
impulse-length
channel, the new value is logged on DEBUG
levelimpulse-length
commands should now be sent to the Bosch SHC and should be reflected in the app. But since there is no documentation from Bosch yet, we might have to experiment with the payload. For now I send the new impulseLength
and impulseState: false
to the controller (and omit the instantOfLastImpulse
field), but we have to test whether the controller accepts this.TODOs not yet fixed / to be discussed:
mode
property. At my current state of knowledge this is not possible, but I will investigate. However, the unused channels should be deactivated internally, so if you try to send something to the unused channels no error should occur. Maybe you could verify this for me.Hi @jlaur and @lsiepel, we have a technical question: we have a relay device that can be one of two modes: Power switch mode (ON
and OFF
is controlled manually in both directions), or impulse switch (only an ON
command can be sent, and the relay automatically switches off after a predefined time).
Depending on the mode, the device exposes different services. In Particular, in power switch mode there is a PowerSwitch
service linked to one openHAB channel, and in impulse switch mode there is a ImpulseSwitch
service linked to 3 openHAB channels. The mode is automatically determined during discovery and stored in a thing property.
I managed to deactivate the corresponding channels based on the thing property internally. So if commands are sent to inactive services, the implementation simply ignores these commands (not ignoring them would lead to errors when sent to the controller). But @mike-bike, who was so kind to test my code with real hardware, mentioned that from the user's perspective it would be even better if the irrelevant channels were not even visible in the UI.
So the question is: do you know if there is a way to completely hide certain channels from the UI depending on a thing property? Thanks in advance for your support :+1:
[...] The mode is automatically determined during discovery and stored in a thing property. [...] So the question is: do you know if there is a way to completely hide certain channels from the UI depending on a thing property?
First, you should probably not rely on a property set by discovery, since this would break manual configuration (UI or file-based).
There are multiple strategies for hiding/removing channels. Do you need to be able to dynamically add those channels again, or should they be forever removed once the mode is determined? In this case they could be declared statically by XML as usual, and simply removed by code:
Set<String> supportedChannelIdSet = new HashSet<>();
List<Channel> unusedChannels = thing.getChannels().stream().filter(channel -> !supportedChannelIdSet.contains(channel.getUID().getId())).toList();
updateThing(editThing().withoutChannels(unusedChannels).build());
When you are back from your vacation, you can test the new JAR I uploaded.
Had some spare time running a quick test...
- default unit for
impulse-length
should now beds
add points to model
shows ds
as unit. Ok.
- when a numeric command is received in the
impulse-length
channel, the new value is logged onDEBUG
level
I do not see any debug statements in the log (I am on TRACE). I have used the quick rule below and would expect setting the delay in the Bosch app to 90 ds or 9 seconds.
console.log("Impulse Length pre: ", items.BSHC_SW03_Impulse_Length.state);
items.BSHC_SW03_Impulse_Length.sendCommand(90);
console.log("Impulse Length post: ", items.BSHC_SW03_Impulse_Length.state);
impulse-length
commands should now be sent to the Bosch SHC and should be reflected in the app. But since there is no documentation from Bosch yet, we might have to experiment with the payload. For now I send the newimpulseLength
andimpulseState: false
to the controller (and omit theinstantOfLastImpulse
field), but we have to test whether the controller accepts this.
Sending above command does not trigger anything. Value in Bosch app remains the same. However, changes in Bosch gets reflected in the Item.
TODOs not yet fixed / to be discussed:
- I didn't have time to add German translations so far and might do this later, or leave it up to the community to add the translations via CrowdIn.
No worries, just wanted to share my observations. Happy to help with the translations, but do not know how to do it.
Thank you for your hints, @jlaur 👍 I will change the code in such a way that the mode is determined during startup and not via the property.
If we remove the channels this will work until the mode is changed again (which is quite unlinkely, but can still happen). It this case we could advise the users in the documentation that the thing has to be deleted and added again. This would be acceptable in my opinion.
We could also go for the most convenient approach, which would mean that we dynamically add and remove channels during startup. But I wonder what implications this has if the channels to be removed are still used/linked somewhere. Do you know if the system would handle this gracefully?
We could also go for the most convenient approach, which would mean that we dynamically add and remove channels during startup. But I wonder what implications this has if the channels to be removed are still used/linked somewhere. Do you know if the system would handle this gracefully?
What changes the mode? If the mode can actually change, you might want to reconsider, since, as you mention, the user might need to get the channel back. In this case you could dynamically create the channel by code (and remove the channel accordingly). There are plenty of bindings creating channels dynamically, if you need a reference I can find one tomorrow.
If the mode is not really static, but rather can change back and forth, I'm not sure adding/removing channels gives the best user experience.
The system can handle the channel being removed, it will just leave a broken link.
Just wanted to share my thoughts: Mode change could only happen during initial device configuration in the Bosch app when the user need to decide on the usage of the device. Mode change would only happen if the device is repurposed - potentially moved to different place / wiring. I‘d assume this to be rare. In that case, I‘d find manual intervention in openHAB to reassign channels absolutely acceptable. Cheers Michael
PS: using wrong channels caused some issues in the binding. However. Unlinking items and relinking them after reconf worked fine. I have done that many times during testing. Michael
Hi @mike-bike, I hope you had a great vacation 😎
I'm still thinking about the best solution regarding adding/removing channels dynamically. @jlaur, do you have any new thoughts on this after @mike-bike 's description two posts earlier? Implementation-wise, I think we could achieve any of these three alternatives:
BTW @mike-bike, I think I added some checks so that using irrelevant channels should not crash the device anymore, but correct me if I'm wrong.
In the mean time, I thought about a more systematic approach to get the impulse-length
synchronization working. Can you check if you see anything in the log when you change the impulse length in the Bosch App (but not trigger an impulse)? The JSON messages should give us some hint about what we are supposed to send in order to get the other direction working.
Thank you both for your support 👍
Hi David, yes, it was a great time. Thanks for asking. I will check the behaviour tonight. Do I need to refresh the binding with a newer version? From the 3 options below, I‘d not recommend the first as it would not be visible to the user which channels actually are active or to be ignored. I‘d be fine with manual user interaction whenever the device has been reconfigured rather then doing the change automatically behind the scenes. What if the thing goes into error state when thing config no longer matches the device? That would avoid faulty behaviour and forces the user to react? Maybe a error message is shown in the thing as a reason. Similar to other bindings when they loose connection or require re-authentication? Cheers, Michael
Hi @mike-bike, I did not update the JAR since I last announced it (April 21st), so you should still have the latest version 👍
And yes, if we go for alternative 2, we should communicate to the user via the thing state that the thing configuration does not match the hardware configuration anymore.
Hi @david-pace,
changing impulse-length
in the Bosch app is immediately reflected in the thing. Please find below change (from 10s) to 7s
tail -f openhab.log | grep -i impuls
2024-05-02 18:00:07.619 [DEBUG] [.internal.devices.bridge.LongPolling] - Long poll response: {"result":[{"path":"/devices/hdm:ZigBee:30fb10fffe46d732/services/ImpulseSwitch","operations":["sendImpulse"],"@type":"DeviceServiceData","id":"ImpulseSwitch","state":{"impulseLength":70,"instantOfLastImpulse":"2024-05-02T16:00:19.389292Z","@type":"ImpulseSwitchState","impulseState":false},"deviceId":"hdm:ZigBee:30fb10fffe46d732"}],"jsonrpc":"2.0"}
2024-05-02 18:00:07.622 [DEBUG] [nternal.devices.bridge.BridgeHandler] - Got update for service ImpulseSwitch of type DeviceServiceData: {"impulseLength":70,"instantOfLastImpulse":"2024-05-02T16:00:19.389292Z","@type":"ImpulseSwitchState","impulseState":false}
2024-05-02 18:00:07.664 [DEBUG] [nternal.devices.bridge.BridgeHandler] - Found handler org.openhab.binding.boschshc.internal.devices.relay.RelayHandler@363cae, calling processUpdate() for service ImpulseSwitch with state {"impulseLength":70,"instantOfLastImpulse":"2024-05-02T16:00:19.389292Z","@type":"ImpulseSwitchState","impulseState":false}
Channing the impulse-length
in the item does change the items state, but does not change the value in the Bosch app. I have tried below code in a rule:
console.log("Impulse Length pre: ", items.BSHC_SW03_Impulse_Length.state);
items.BSHC_SW03_Impulse_Length.sendCommand(90);
console.log("Impulse Length post: ", items.BSHC_SW03_Impulse_Length.state);
That results into the update of the state:
2024-05-02 18:03:00.503 [INFO ] [nhab.automation.script.ui.9a905cf07a] - Impulse Length pre: 70 ds
2024-05-02 18:03:00.533 [INFO ] [nhab.automation.script.ui.9a905cf07a] - Impulse Length post: 90 ds
Same result with postUpdate
rather than sendCommand
items.BSHC_SW03_Impulse_Length.postUpdate("90");
But the Bosch app still has the old value. When I trigger the impulse switch in openHAB, the item is updated with the correct Bosch value (here 70ds) immediately.
Hope that helps. Let me know if I should use a different method.
Regards, Michael
@jlaur, do you have any new thoughts on this after @mike-bike 's description two posts earlier? Implementation-wise, I think we could achieve any of these three alternatives:
- all channels are always visible, but depending on the mode some channels simply do nothing
- irrelevant channels are deleted upon the first initialization of the device. If the mode changes, the user has to re-add the thing
- channels are configured fully dynamically upon each initialization of the device
First solution is the only one where recreating of Thing and relinking of items is not needed. But as you stated, the use case is rare, so this solution suffers from the UI issue of having too many irrelevant channels.
The other two solutions are similar, and they make the UI less complex for the user. In first of the two, the Thing has to be readded upon repurposing a device, and in the last this it not needed. In both cases relinking items will be needed. It is slightly more complex to dynamically create the channels as it has to be done in code rather than XML. Dynamically removing channels suffers from a very small UI glitch: If you are quickly jumping to the channel tab after creating the Thing, you might see all channels initially, before they are removed by the first initialization. This is a quite minor glitch though.
I think that covers more or less everything. I agree it's acceptable to have to recreate the Thing and relink channels when repurposing a device, so it's really up to you what solution you prefer.
Hi @jlaur, I'm currently trying to implement the fully dynamic solution, which involves adding channels again (at least potentially). But I'm struggling to create channels by code. You mentioned that there is also a strategy to hide/show channels. Could you please give a hint how this can be accomplished? Thanks 🙂
I found out how to create channels from scratch using ChannelBuilder
. However, I would like to load the channels as they are defined in thing-types.xml
to avoid duplicating metadata. Do you know how to do that @jlaur or do you maybe know even better mechanisms?
This request is to add support for another Bosch Smart Home device, namely Relay:
From openhab.log:
Unknown deviceModel 'MICROMODULE_RELAY'! Please create a support request issue for this unknown device model.
Please let me know if I'd need to provide further details or can support testing.
Happy Easter!
Regards, Michael