Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[boschshc] Add support for Relay - 'MICROMODULE_RELAY' #16590

Closed
mike-bike opened this issue Mar 28, 2024 · 70 comments · Fixed by #17026 or #17160
Closed

[boschshc] Add support for Relay - 'MICROMODULE_RELAY' #16590

mike-bike opened this issue Mar 28, 2024 · 70 comments · Fixed by #17026 or #17160
Assignees
Labels
enhancement An enhancement or new feature for an existing add-on

Comments

@mike-bike
Copy link

mike-bike commented Mar 28, 2024

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.

2024-03-28 [DEBUG] [rnal.discovery.ThingDiscoveryService] - Found device: name=Relais Test id=hdm:ZigBee:30XXXXXXXXXXXXXX
2024-03-28 [DEBUG] [rnal.discovery.ThingDiscoveryService] - .... service: CommunicationQuality
2024-03-28 [DEBUG] [rnal.discovery.ThingDiscoveryService] - .... service: PowerSwitch
2024-03-28 [DEBUG] [rnal.discovery.ThingDiscoveryService] - .... service: ChildProtection
2024-03-28 [DEBUG] [rnal.discovery.ThingDiscoveryService] - .... service: PowerSwitchProgram
2024-03-28 [DEBUG] [rnal.discovery.ThingDiscoveryService] - .... service: ElectricalFaults
2024-03-28 [DEBUG] [rnal.discovery.ThingDiscoveryService] - .... service: SwitchConfiguration
2024-03-28 [DEBUG] [rnal.discovery.ThingDiscoveryService] - .... service: Linking
{"@type":"device","rootDeviceId":"64-da-a0-10-83-a7","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":["LIGHT","GENERIC","HEATING_RCC"]}

Please let me know if I'd need to provide further details or can support testing.

Happy Easter!

Regards,
Michael

@mike-bike mike-bike added the enhancement An enhancement or new feature for an existing add-on label Mar 28, 2024
@david-pace
Copy link
Member

Thanks for the enhancement request. Assuming you can help with testing again we can start coding as soon as someone finds some spare time 👍

@mike-bike
Copy link
Author

mike-bike commented Mar 31, 2024 via email

@david-pace
Copy link
Member

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 tschamm/boschshc-hass#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?

@mike-bike
Copy link
Author

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:

  1. The BOSCH Relais is fully configurable via the app.
  2. There are 4 different "modes" as you could configure the device. These modes define further options (I'd assume these to be PowerSwitchProgram)
  • Generic mode: if nothing else fits better
  • Light mode: connected devices will be treated as a "light" in the app, e.g. switched on with "room light" or used in alarm system and motion sensors
  • Elektro heating: require assigned room thermostat to turn off relay when temp matches
  • Boiler: similar to Electro but slightly different timing to turn off relay
  1. Available switch configuration (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 change
  2. I do not have any clue about ElectricalFaults 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

@mike-bike
Copy link
Author

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:

  • If configured as a light, it will be part of the app's room light switch and could also be used for alarm etc.
  • if configured as electrical heating / boiler it needs to be tied to a room thermostat, so that the bridge could turn it off after reaching the temperature threshold.
  • if configured as "generic" it will neither depend on any temperature and also not tied to room light

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.

@mike-bike
Copy link
Author

mike-bike commented Apr 7, 2024

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"]}

@david-pace
Copy link
Member

Thank you for the information, @mike-bike 👍 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.

@david-pace david-pace self-assigned this Apr 9, 2024
@mike-bike
Copy link
Author

mike-bike commented Apr 9, 2024 via email

@david-pace
Copy link
Member

david-pace commented Apr 12, 2024

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 👍 I'm excited to hear what already works and what does not work 😉

@mike-bike
Copy link
Author

mike-bike commented Apr 12, 2024

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:

  1. Binding loads and seem to continue supporting the previous devices
  2. Relay has been discovered into in-box
  3. Implemented Thing and created/linked items
  4. Test results below
  5. no obvious issues reported in the log (even with TRACE)

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!

@david-pace
Copy link
Member

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.

@mike-bike
Copy link
Author

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}

@david-pace
Copy link
Member

Thanks for looking into the log files 👍

First, a few general explanations:

  • The 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)
  • My understanding was that if a toggle switch is needed, the 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:

  • My 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:

  • Did I understand correctly that when the Bosch -> openHAB communication fails, the other direction (openHAB -> Bosch) still works?
  • 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.

@mike-bike
Copy link
Author

mike-bike commented Apr 13, 2024 via email

@mike-bike
Copy link
Author

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.

@david-pace
Copy link
Member

david-pace commented Apr 14, 2024

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:

  • Removed the power-switch-program channel and the corresponding service completely
  • impulse-switch is now a write-only channel and will (hopefully) not fail (do nothing) when the state should be read
  • impulse-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 tschamm/boschshc-hass#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.

@mike-bike
Copy link
Author

mike-bike commented Apr 14, 2024

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:

  1. PowerSwitch - keeps open or closed state until changed, or
  2. ImpulseSwitch - closes the relay for a pre-configured time and then automatically opens it again

You 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

@david-pace
Copy link
Member

david-pace commented Apr 15, 2024

Thank you for this analysis 👍 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 #16590 (comment) 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.

@mike-bike
Copy link
Author

mike-bike commented Apr 15, 2024

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:  '

@david-pace
Copy link
Member

Thank you for the detailed update ❤️

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?

@mike-bike
Copy link
Author

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.

@mike-bike
Copy link
Author

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.

@david-pace
Copy link
Member

Hi @mike-bike, I uploaded a new version of the JAR. Please unlink the channels and delete the thing before updating it.

Changes:

  • Discovery now checks the exposed services and adds a mode property to the thing (possible values: PowerSwitch or ImpulseSwitch)
  • Thing only configures the appropriate channels
  • Fixed type name of impulse switch states
  • 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.
  • New read-only channel instant-of-last-impulse with the timestamp of the last impulse

Excited to hear whether it works better now 😎

@mike-bike
Copy link
Author

Hi @david-pace, I have downloaded new JAR, unlinked all items and deleted the thing. Then updated binding with new JAR.

PowerSwitch Mode:

  1. Thing discovered in inbox
  2. Added Thing with relay in PowerSwitch mode
  3. Thing came online and property mode=PowerSwitch
  4. Thing exposes signal-strength, child-protection and power-switch but also impulse-switch, impulse-lengthand instant-of-last-impulse which were not expected.
  5. Linked and checked channels: 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:

  1. Scan for new devices -> Relais came up, created thing
  2. Thing came online and property mode=ImpulseSwitch
  3. Thing exposes 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.
  4. Linked all channels except power-switch
  5. child-protection working as expected
  6. signal-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
  1. impulse-switch working in both directions. Switch in openHAB stays on until relay switches off again. GREAT!
  2. impulse-length was updated with 20 (2s) according to Bosch app. Value also gets updated with change in Bosch app.
  3. instant-of-last-impulse is updated with last event

Overall, great progress. I am going to test setting impulse-length from openHAB later today and provide a summary.

Regards,
Michael

@mike-bike
Copy link
Author

mike-bike commented Apr 20, 2024

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:

  1. Please review channels to be presented pending on configuration: with mode=PowerSwitch none of the impulse- should be available, and with Impulse-Switch the PowerSwitch channel does not make sense.
  2. I'd suggest some minor updates to the translations / wording: currently there is a mixture of english and german names suggested in the channels
  3. Default channel Unit in 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

@david-pace
Copy link
Member

Thanks for the detailed tests ❤️

When you are back from your vacation, you can test the new JAR I uploaded.

Fixes:

  • default unit for impulse-length should now be ds
  • when a numeric command is received in the impulse-length channel, the new value is logged on DEBUG level
  • 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 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:

  • I have to ask other developers whether it is possible to hide channels from the UI completely, depending on the 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.
  • 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.

@david-pace
Copy link
Member

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 👍

@david-pace
Copy link
Member

Hi @mike-bike, yes please do test everything again. I think the pull request was closed too soon. If there are any issues I will address them in additional pull requests.

@mike-bike
Copy link
Author

mike-bike commented Jul 23, 2024

Status: relay configured in impulse mode

  1. Unlink items and delete existing relay thing
  2. Install new version
openhab> bundle:update 257 file:///home/openhabian/addons/org.openhab.binding.boschshc-4.3.0-SNAPSHOT-relay-3.jar
openhab> bundle:list | grep Bosch
257 │ Active │  80 │ 4.3.0.202407220547    │ openHAB Add-ons :: Bundles :: Bosch Smart Home Binding
  1. Relay thing added from Inbox
  2. Channels: Signal strength, Child Protection, Impulse Switch, Impulse Length, Instant of Last Impulse
  3. Linked channels to previous items
  4. All changes and switch button in Bosch App are correctly reflected in item states
  5. Impulse switch in item triggers event / switch state correctly changes on-->off
  6. Child protection switch in item working correctly
  7. What I was not able to test is a change to Impuls Length. I'd appreciate some guidance how to correctly configure the item to increment between 0.5, 1, 2, ... 20 seconds

Part 2: reconfigure relay as on/off switch

  1. Leave OpenHAB as is - thing configured and active
  2. Delete device in Bosch App
  3. Added same relay as new device in Bosch App - select ON/OFF switch and standard configuration
  4. Disabled thing in OpenHAB and enabled again
  5. 3 Channels available: Signal Strength and Child Protection still linked to previous item. Betrieb as new channel (ON/OFF)
  6. Link existing switch item to channel
  7. Child Protection and Switch item change state in relay and Bosch App
  8. BUT: changes in Bosch App are now longer picked up by the items --> same as before! Channel link of newly added switch item shows "?"
Bildschirmfoto 2024-07-23 um 20 08 50

Any thoughts?

I will restart OpenHAB and check if this changes anything later...

@lsiepel lsiepel reopened this Jul 23, 2024
@mike-bike
Copy link
Author

mike-bike commented Jul 23, 2024

Stopped OpenHAB and cleared cache.
After reloading the new JAR in Karaf, channels picked up working again.
However, the strange link to the switch persist:
Bildschirmfoto 2024-07-23 um 22 09 08

I have missed to check explicitly other Bosch things, but I assume that long poll stopped working until reloading. At least I have not recognized any updates in the log.

I cannot assess the effort required to fix the thing, but I now feel unsure about the chosen design and would like to propose an alternative approach:

The relay device requires deletion and adding a new device in the Bosch App. With that, it could be considered as a different device with unique characteristics serving a different purpose. What if the current configuration (Impulse Mode or Switch Mode) will be stored in a thing property during first initialization. Whenever the thing needs to be reloaded it could compare the active device mode against the stored property. If both are the same, everything is ok. If it differs, the switch changes into Error state and displays an appropriate message. The user can then decide to delete and recreate the thing or change the configuration of the device back to the previous state.
This will provide a similar user experience as the Bosch App. It will also effectively prevent wrong channels / orphaned links.
For me, this would be perfectly acceptable. What do you think?

@david-pace
Copy link
Member

I agree that we should at least try this alternative approach. It seems like the effort getting the dynamic channel creation to work is not worth what we get in terms of user experience - we already discussed that changing the device configuration happens rarely (i.e. when the device is re-purposed), and then it is acceptable to re-create the thing. Even with the dynamic channel creation working the user would still have to do some manual steps, in this case triggering a re-initialization somehow.

I will implement the simplified approach, and even add another simplification: we don't need to store the current configuration in a thing property. I think we already discussed that this would not work in certain scenarios. Also the channel configuration already tells us in which mode the thing currently is, so we don't need to store it explicitly.

I will provide a JAR soon, stay tuned 😎

@mike-bike
Copy link
Author

Hi @david-pace, after thinking about the proposal I am even in more favor of it. Assuming the dynamic channel creation works, the user needs to action anyhow as orphaned items could be used in rules, triggers, graphs etc.

Not sure what you mean by "storing the configuration as a property". My proposal was to store the instantiated mode as a fixed string in a property. Like "Location" in sample image below; e.g. Mode: Impulse or Mode: Switch.
You could also chose two different Thing Types Relay (Impulse) or Relay (Switch) respectively if this would be more consistent with the design.

I do see the benefit in being fully transparent to the user. In case the thing identifies a configuration change (i.e. different to what was instantiated) it should switch into Error with an appropriate message saying, that device config detected does not match. Certainly you could achieve the same by checking the configured channels vs the newly detected, but I personally do find a property more descriptive.

Anyway, I am looking forward to testing the new JAR. :-)

Bildschirmfoto 2024-07-26 um 16 10 30

@david-pace
Copy link
Member

Hi @mike-bike, maybe my wording was ambiguous. With current configuration I indeed meant the current mode (Switch / Impulse).

If you remember I already implemented this in a previous version, but @jlaur mentioned that this does not work, at least not if the property is set during discovery (see #16590 (comment)). I have to think about it whether it would work if the property is set during the first initialization. @jlaur do you have any input on that?

@mike-bike
Copy link
Author

Now that you mention it... I vaguely recall. I think I already had proposed a similar solution ( #16590 (comment))
Though I think the use of the property was slightly different then. I am not suggesting it to use it for the configuration. @jlaur recommended not to make code dependent on the property for some reasons.
My proposal is to set that property during first initialization with the configured mode. I'd assume that by that time the property is unset or NULL. The you could check that property on any initialization request (where you were trying to reconfigure the channels) if it still matches the actual discovery result. If it does not match because the device has been reconfigured throw an error. Hope that makes sense. Though I do not know the technical details of the implementation, but the previous state is certainly persisted somewhere... If you can't use it during initialization and require a different process to determine if new config matches previous, just set the property for user info...

@jlaur
Copy link
Contributor

jlaur commented Jul 26, 2024

If you remember I already implemented this in a previous version, but @jlaur mentioned that this does not work, at least not if the property is set during discovery (see #16590 (comment)). I have to think about it whether it would work if the property is set during the first initialization. @jlaur do you have any input on that?

If a property can be set on first initialization, what prevents it from being determined on each initialization?

@david-pace
Copy link
Member

david-pace commented Jul 27, 2024

I just uploaded a new JAR implementing the new approach 👍

EDIT: @mike-bike you asked about how to set the impulse length. The unit of the duration is deciseconds, i.e. tenth seconds. For instance, to set a delay of 1.5 seconds you would set 15 deciseconds. But please let me know if you observe any issues or errors when you try to set an invalid value with fraction digits.

@mike-bike
Copy link
Author

mike-bike commented Jul 27, 2024

Testing it. Deleted old thing and updated bundle...

Relay device configured as Power Switch - recognized correctly - Property set ok:
Bildschirmfoto 2024-07-27 um 17 21 06

Testing functionality

  1. correct 3 channels offered: Signalstrength, Child Protection, Betrieb (why is this in German and the rest in English?)
  2. Both switches working correctly in both directions, signal strength directly display (this is pretty much useless, as it does not traverse cascaded links identifying the weakest connection... Bosch App does not update it dynamically either - nice to have - anyway it shows correct value)

Now reconfiguring device into Impulse Mode

  1. Delete device in Bosch App ...
  2. and add it as new Relay with Impulse Mode ...
  3. As I have not touched OpenHAB, relay thing still believes it is in Switch Mode which is fine
  4. Toggle "Betrieb" switch creates record in log but does not change state - fine as well
  5. Disable thing and re-enable - this shows for a sub-second an Error with a message (good!) but then switches to ONLINE (Ups!). mode property (please change first letter to Uppercase: Mode) has changed to "ImpulseSwitch" which is correct mode, but channels are unchanged - which is expected!
Bildschirmfoto 2024-07-27 um 17 54 31 7. Disabling the Bridge and re-enabling it again, generates the same

==> It seems that configuration change is identified correctly, but Error condition does not prevent initialization (fall-through IF-condition?)

Manually deleted thing and manually added again (re-scan correctly identifies Impulse Switch)

  1. All Impulse Switch channels created
  2. Linking items...
  3. All channels working correctly in both ways
  4. still too dumb to set Impuls length from OpenHAB - would appreciate your guidance

Summary
Functionality is as expected. Only bug is that Thing does not remain in error state when re-configuration is detected. Property Mode should not change and Thing should remain in error. I'd would expect to continue with correct behavior if I reconfigure it back to previous state in Bosch App.

Cheers
Michael

@david-pace
Copy link
Member

david-pace commented Jul 28, 2024

Thanks for testing ❤️ We're nearly there 👍 I just uploaded a new JAR that should fix the ERROR / ONLINE switching issue. Can you please test again?

Regarding the impulse length issue: did you read my EDIT here explaining that the impulse length is set in tenth seconds? Also, I added logging in DEBUG mode, so you should see in the log what the new setting is and whether it could be sent to the controller.

Question to @jlaur and @lsiepel regarding the properties: please refer to the screenshots @mike-bike provided in #16590 (comment). We have an existing property Location starts with upper case. I looked at existing properties in my Zigbee things and noticed that they are lower case delimited by underscores, like zigbee_powersource. And in the Coding Guidelines I found that they should be camelCase. I am now unsure which convention I should use, and whether the new property should be named mode or Mode, and whether we should rename Location to location.

Same question for the property values. I now just used the Bosch service identifiers (which are PowerSwitch and ImpulseSwitch) as values, but we could also use any other identifiers such as power-switch, powerSwitch or power_switch. Is there any preference or even guideline for the values as well?

@jlaur
Copy link
Contributor

jlaur commented Jul 28, 2024

We have an existing property Location starts with upper case. I looked at existing properties in my Zigbee things and noticed that they are lower case delimited by underscores, like zigbee_powersource. And in the Coding Guidelines I found that they should be camelCase. I am now unsure which convention I should use, and whether the new property should be named mode or Mode, and whether we should rename Location to location.

camelCase is indeed the correct convention, which is also used by system-defined properties (like vendor or thingTypeVersion). It should be okay to rename Location, at least I can't imagine how this could break anything.

Same question for the property values.

There is no convention for values, but generally they start with capital letters when it makes sense to do so (for example vendor: Bosch). Values can also contain spaces (for example vendor: Signify Netherlands B.V.).

@mike-bike
Copy link
Author

mike-bike commented Jul 28, 2024

Hi @david-pace, I do not have much time for extensive testing. However, I have checked functionality with last Impulse configuration working fine. Then reconfigured device into PowerSwitch mode and received error state as expected:
Bildschirmfoto 2024-07-28 um 19 59 19

The changed device config into Impulse again and stopped/started Thing. It went to online immediately and channels picked up current values (e.g. had changed Impulse length during config in Bosch App).

Functionality looks good. You may want to adjust the strings according to the advice given by the others. I am personally fine with the code...

All seems to be working fine. However, I do not see changes in OpenHAB to Impulse Length coming through. I have created dummy Blocky script to change duration:
Bildschirmfoto 2024-07-28 um 20 04 54

Item value got updated, no info in log (even on Trace) and Bosch App shows old value.
I already told you that I am too dumb to change the length ...

Bildschirmfoto 2024-07-28 um 20 07 15

PS: What state of the Bosch binding is delivered with the 4.2.x release? I do see connection loss to Bosch (long poll stops) after few hours again. Have now loaded current 4.3 Bosch binding and it seems to be stable again. I thought the connection issues had been fixed long ago and that code should have been merged...

@david-pace
Copy link
Member

Great that the thing status update now works properly 👍

According to the useful advice provided by @jlaur I will keep the property name lower case as specified in the coding guideline. The location property name will be changed in #16599.

Regarding the impulse length update: it looks like you're sending a string command, but the channel only accepts numbers. Maybe it works when you send an integer number to the item? @jlaur what is the best practice here? Should the numeric channel also accept string commands, and then try to parse the string as a number?

@mike-bike
Copy link
Author

@david-pace, I think commands only works on strings anyway. The state of the item itself is changed correctly but I cannot see any evidence in the log, that the change is sent to the device. I will do some further testing tonight.

@jlaur
Copy link
Contributor

jlaur commented Jul 29, 2024

Regarding the impulse length update: it looks like you're sending a string command, but the channel only accepts numbers. Maybe it works when you send an integer number to the item? @jlaur what is the best practice here? Should the numeric channel also accept string commands, and then try to parse the string as a number?

I don't think so, or at least I think that should work automatically. Do you have an example? I tried this without any issues:

openhab> openhab:send Signe_Gradient_Floor_Color 50
Command has been sent successfully.
openhab> openhab:send Signe_Gradient_Floor_Color "10"
Command has been sent successfully.
openhab> openhab:send Signe_Gradient_Floor_Color "0"
Command has been sent successfully.

I believe the reason it works is that in all three cases the binding receives as PercentType:

if (command instanceof PercentType) {
PercentType brightness = (PercentType) command;

@mike-bike
Copy link
Author

mike-bike commented Jul 29, 2024

I have tried the same from Karaf as @jlaur.

openhab> openhab:send Relais_Impuls_Test_Impulse_Length 50
Command has been sent successfully.

It does not make any difference: Item status is immediately updated in openHAB showing 50 ds. But there is nothing in the logs that the change has been sent to the Bosch Device.
When I then trigger the Impulse Switch item in openHAB, I do see the previous impulse length of 40 ds in the log and the item's state is also reset to 40 ds again.

2024-07-29 19:44:07.116 [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,"impulseLength":40,"instantOfLastImpulse":"2024-07-29T17:44:07.112656220Z","stateType":"ImpulseSwitchState","@type":"ImpulseSwitchState"}
2024-07-29 19:44:07.382 [DEBUG] [.internal.devices.bridge.LongPolling] - Long poll response: {"result":[{"path":"/devices/hdm:ZigBee:30fb10fffe46d732/services/ImpulseSwitch","operations":["sendImpulse"],"@type":"DeviceServiceData","id":"ImpulseSwitch","state":{"impulseLength":40,"instantOfLastImpulse":"2024-07-29T17:43:48.720135Z","@type":"ImpulseSwitchState","impulseState":true},"deviceId":"hdm:ZigBee:30fb10fffe46d732"}],"jsonrpc":"2.0"}
2024-07-29 19:44:07.385 [DEBUG] [nternal.devices.bridge.BridgeHandler] - Got update for service ImpulseSwitch of type DeviceServiceData: {"impulseLength":40,"instantOfLastImpulse":"2024-07-29T17:43:48.720135Z","@type":"ImpulseSwitchState","impulseState":true}
2024-07-29 19:44:07.402 [DEBUG] [nternal.devices.bridge.BridgeHandler] - Found handler org.openhab.binding.boschshc.internal.devices.relay.RelayHandler@beb0a2, calling processUpdate() for service ImpulseSwitch with state {"impulseLength":40,"instantOfLastImpulse":"2024-07-29T17:43:48.720135Z","@type":"ImpulseSwitchState","impulseState":true}
2024-07-29 19:44:07.523 [DEBUG] [.internal.devices.bridge.LongPolling] - Long poll response: {"result":[{"path":"/devices/hdm:ZigBee:30fb10fffe46d732/services/ImpulseSwitch","operations":["sendImpulse"],"@type":"DeviceServiceData","id":"ImpulseSwitch","state":{"impulseLength":40,"instantOfLastImpulse":"2024-07-29T17:44:07.337333Z","@type":"ImpulseSwitchState","impulseState":true},"deviceId":"hdm:ZigBee:30fb10fffe46d732"}],"jsonrpc":"2.0"}
2024-07-29 19:44:07.526 [DEBUG] [nternal.devices.bridge.BridgeHandler] - Got update for service ImpulseSwitch of type DeviceServiceData: {"impulseLength":40,"instantOfLastImpulse":"2024-07-29T17:44:07.337333Z","@type":"ImpulseSwitchState","impulseState":true}
2024-07-29 19:44:07.542 [DEBUG] [nternal.devices.bridge.BridgeHandler] - Found handler org.openhab.binding.boschshc.internal.devices.relay.RelayHandler@beb0a2, calling processUpdate() for service ImpulseSwitch with state {"impulseLength":40,"instantOfLastImpulse":"2024-07-29T17:44:07.337333Z","@type":"ImpulseSwitchState","impulseState":true}
2024-07-29 19:44:11.597 [DEBUG] [.internal.devices.bridge.LongPolling] - Long poll response: {"result":[{"path":"/devices/hdm:ZigBee:30fb10fffe46d732/services/ImpulseSwitch","operations":["sendImpulse"],"@type":"DeviceServiceData","id":"ImpulseSwitch","state":{"impulseLength":40,"instantOfLastImpulse":"2024-07-29T17:44:07.337333Z","@type":"ImpulseSwitchState","impulseState":false},"deviceId":"hdm:ZigBee:30fb10fffe46d732"}],"jsonrpc":"2.0"}
2024-07-29 19:44:11.600 [DEBUG] [nternal.devices.bridge.BridgeHandler] - Got update for service ImpulseSwitch of type DeviceServiceData: {"impulseLength":40,"instantOfLastImpulse":"2024-07-29T17:44:07.337333Z","@type":"ImpulseSwitchState","impulseState":false}
2024-07-29 19:44:11.616 [DEBUG] [nternal.devices.bridge.BridgeHandler] - Found handler org.openhab.binding.boschshc.internal.devices.relay.RelayHandler@beb0a2, calling processUpdate() for service ImpulseSwitch with state {"impulseLength":40,"instantOfLastImpulse":"2024-07-29T17:44:07.337333Z","@type":"ImpulseSwitchState","impulseState":false}

Please note, that I do see same when I trigger the button in the Bosch App...

When I change the impulse length (here to 90 ds) in the Bosch App, I do see the following lines in the log and the item is updated.

2024-07-29 19:48:56.522 [DEBUG] [.internal.devices.bridge.LongPolling] - Long poll response: {"result":[{"path":"/devices/hdm:ZigBee:30fb10fffe46d732/services/ImpulseSwitch","operations":["sendImpulse"],"@type":"DeviceServiceData","id":"ImpulseSwitch","state":{"impulseLength":90,"instantOfLastImpulse":"2024-07-29T17:46:24.916050Z","@type":"ImpulseSwitchState","impulseState":false},"deviceId":"hdm:ZigBee:30fb10fffe46d732"}],"jsonrpc":"2.0"}
2024-07-29 19:48:56.525 [DEBUG] [nternal.devices.bridge.BridgeHandler] - Got update for service ImpulseSwitch of type DeviceServiceData: {"impulseLength":90,"instantOfLastImpulse":"2024-07-29T17:46:24.916050Z","@type":"ImpulseSwitchState","impulseState":false}
2024-07-29 19:48:56.541 [DEBUG] [nternal.devices.bridge.BridgeHandler] - Found handler org.openhab.binding.boschshc.internal.devices.relay.RelayHandler@beb0a2, calling processUpdate() for service ImpulseSwitch with state {"impulseLength":90,"instantOfLastImpulse":"2024-07-29T17:46:24.916050Z","@type":"ImpulseSwitchState","impulseState":false}

@jlaur
Copy link
Contributor

jlaur commented Jul 29, 2024

50 ds

Oh, it's Number:Time. @david-pace, you probably need to handle it as QuantityType in handleCommand.

@david-pace
Copy link
Member

Ah ok, not a DecimalType? Very good to know 😉

@mike-bike
Copy link
Author

mike-bike commented Jul 29, 2024

This seems to be the issue. I have added another item without any dimension and changes to that are shown in the log and also reflected in the Bosch App

2024-07-29 21:18:12.365 [DEBUG] [.internal.devices.relay.RelayHandler] - New impulse length setting for relay: 100 deciseconds
2024-07-29 21:18:12.370 [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,"impulseLength":100,"instantOfLastImpulse":"2024-07-29T17:51:24.178488Z","stateType":"ImpulseSwitchState","@type":"ImpulseSwitchState"}
2024-07-29 21:18:12.562 [DEBUG] [.internal.devices.relay.RelayHandler] - Successfully sent state with new impulse length to controller.
2024-07-29 21:18:12.622 [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-07-29T17:51:24.178488Z","@type":"ImpulseSwitchState","impulseState":false},"deviceId":"hdm:ZigBee:30fb10fffe46d732"}],"jsonrpc":"2.0"}
2024-07-29 21:18:12.624 [DEBUG] [nternal.devices.bridge.BridgeHandler] - Got update for service ImpulseSwitch of type DeviceServiceData: {"impulseLength":100,"instantOfLastImpulse":"2024-07-29T17:51:24.178488Z","@type":"ImpulseSwitchState","impulseState":false}
2024-07-29 21:18:12.642 [DEBUG] [nternal.devices.bridge.BridgeHandler] - Found handler org.openhab.binding.boschshc.internal.devices.relay.RelayHandler@beb0a2, calling processUpdate() for service ImpulseSwitch with state {"impulseLength":100,"instantOfLastImpulse":"2024-07-29T17:51:24.178488Z","@type":"ImpulseSwitchState","impulseState":false}

Though the handling in the channel needs to be adjusted, as the channel itself suggest a quantity type time (which is correct).
Bildschirmfoto 2024-07-29 um 21 20 42

Interestingly using the quantity type does not show any error in the log. The command is silently ignored.

Thanks @jlaur for the hint!

@mike-bike
Copy link
Author

mike-bike commented Jul 29, 2024

Btw: Sending other values, than selectable in Bosch App seems to be accepted; e.g. 23 is shown as 2.3 Sec in Bosch App. Even 500 or 5000 seems to be accepted.
At least 500 works - the Relay stayed closed for 50seconds.

2024-07-29 21:25:24.130 [DEBUG] [nternal.devices.bridge.BridgeHandler] - Found handler org.openhab.binding.boschshc.internal.devices.relay.RelayHandler@beb0a2, calling processUpdate() for service ImpulseSwitch with state {"impulseLength":500,"instantOfLastImpulse":"2024-07-29T19:25:23.967418Z","@type":"ImpulseSwitchState","impulseState":true}
2024-07-29 21:26:14.024 [DEBUG] [.internal.devices.bridge.LongPolling] - Long poll response: {"result":[{"path":"/devices/hdm:ZigBee:30fb10fffe46d732/services/ImpulseSwitch","operations":["sendImpulse"],"@type":"DeviceServiceData","id":"ImpulseSwitch","state":{"impulseLength":500,"instantOfLastImpulse":"2024-07-29T19:25:23.967418Z","@type":"ImpulseSwitchState","impulseState":false},"deviceId":"hdm:ZigBee:30fb10fffe46d732"}],"jsonrpc":"2.0"}

Very short durations of 1 (0.1s) and 2 (0.2s) also working.

@david-pace
Copy link
Member

ok, the JAR is updated 👍 Thanks for the hint with the QuantityType @jlaur 🙂

The channel now accepts both DecimalType commands and QuantityType commands. So you could also specify the impulse length in any other time unit than deciseconds, and the time would automatically be converted internally. This could be the final version 😎

@mike-bike
Copy link
Author

Looking good! I have tested with 20, 20 ds, and 1 min. Responses in log and changes to Bosch App were as expected. 1 min got correctly translated into 600 in log and is shown as 60 seconds in Bosch App. Updates to 2nd item with decimal type (no quantity) also working.

Thumbs up!

Do you want me to do full regression?

@david-pace
Copy link
Member

Cool 😎 Now we should have everything covered. I will open the pull request for code reviews.

Normally everything else should still work because I have unit tests in place, but of course it's always better to have a confirmation by testing all channels with the real hardware again, if you find time for it.

Thank you for your continuing and valuable testing support ❤️

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement An enhancement or new feature for an existing add-on
Projects
None yet
4 participants