Hi all, I’m having trouble getting the Gain-Offset Correction profile working (at least, how I think it should work.)
I’m running openHAB 3.3.0.M6 in a docker container on Ubuntu 20.04.4 LTS (GNU/Linux 5.4.0-120-generic x86_64.) I have Clipsal PIR occupancy sensors that broadcast luminance measurements to the CBus network as a percentage of their 2550 lux range. These propagate into OH just fine, and the associated item updates.
I would like to apply a multiplier to these values to convert them from a percentage to an absolute lux value, by multiplying the value received from the channel by 25.5.
In the UI, I go to the Item screen (via Things → Channels → Linked Items.) I change the profile from Default to Gain-Offset Correction, I put 25.5 in the gain box, and click Save.
After this, it seems that no values propagate through to the item - it’s value doesn’t change. I’m not seeing any errors in the logs.
Have I got this wrong? Is there something different I need to do?
It is designed to work with raw Numbers (not having associated UoM) from the binding, and scaling/offsetting values towards the item, potentially attaching an unit to otherwise dimensionless Number. The other way works as well.
While the profile is offered by modbus binding, it is usable with other bindings as long the use case is same as above.
What is the input you use with the profile? Are they plain numbers or do they have UoM?
Is there any errors or warnings in the logs? For additional troubleshooting you can set “TRACE” logging for org.openhab.binding.modbus.internal.profiles. Share a snippet of logs when new value is parsed
EDIT: quickly checked what cbus is about. The light level seems to be of type Dimmer, updating its state as PercentType which is subclass of DecimalType (I.e . plain number). I would expect this to work with the profile.
Ah, OK, I didn’t realise that this profile is provided by the Modbus binding. That explains why it’s not covered in the profiles documentation.
I think the number coming from the channel is a raw number. In realty it’s a percentage, but I don’t think units are passed from CBus to OH.
I tries wetting the log level to TRACE as you’ve describes, and here are the results:
:34:31.387 [DEBUG] [rnal.profiles.ModbusGainOffsetProfile] - Configuring profile with pre-gain-offset parameter '0.0'
16:34:31.388 [DEBUG] [rnal.profiles.ModbusGainOffsetProfile] - Configuring profile with gain parameter '25.5'
16:34:31.389 [TRACE] [rnal.profiles.ModbusGainOffsetProfile] - State update '3' from handler, sending converted '76.5' state towards item.
16:34:31.390 [ERROR] [core.common.registry.AbstractRegistry] - Cannot inform the listener "org.openhab.core.thing.internal.ChannelLinkNotifier@c282070" about the "ADDED" event: Value must be between 0 and 100
java.lang.IllegalArgumentException: Value must be between 0 and 100
at org.openhab.core.library.types.PercentType.validateValue(PercentType.java:93) ~[?:?]
at org.openhab.core.library.types.PercentType.<init>(PercentType.java:88) ~[?:?]
at org.openhab.core.library.types.QuantityType.as(QuantityType.java:405) ~[?:?]
at org.openhab.core.internal.items.ItemStateConverterImpl.convertToAcceptedState(ItemStateConverterImpl.java:64) ~[?:?]
at org.openhab.core.thing.internal.profiles.ProfileCallbackImpl.sendUpdate(ProfileCallbackImpl.java:121) ~[?:?]
at org.openhab.binding.modbus.internal.profiles.ModbusGainOffsetProfile.onStateUpdateFromHandler(ModbusGainOffsetProfile.java:126) ~[?:?]
at org.openhab.core.thing.internal.CommunicationManager.lambda$13(CommunicationManager.java:566) ~[?:?]
at org.openhab.core.thing.internal.CommunicationManager.lambda$15(CommunicationManager.java:586) ~[?:?]
at java.lang.Iterable.forEach(Iterable.java:75) ~[?:?]
at org.openhab.core.thing.internal.CommunicationManager.handleCallFromHandler(CommunicationManager.java:582) ~[?:?]
at org.openhab.core.thing.internal.CommunicationManager.stateUpdated(CommunicationManager.java:564) ~[?:?]
at org.openhab.core.thing.internal.ThingManagerImpl$1.stateUpdated(ThingManagerImpl.java:176) ~[?:?]
at org.openhab.core.thing.binding.BaseThingHandler.updateState(BaseThingHandler.java:268) ~[?:?]
at org.openhab.binding.cbus.handler.CBusLightHandler.handleCommand(CBusLightHandler.java:61) ~[?:?]
at org.openhab.core.thing.binding.BaseThingHandler.channelLinked(BaseThingHandler.java:180) ~[?:?]
at org.openhab.core.thing.internal.ChannelLinkNotifier.lambda$3(ChannelLinkNotifier.java:72) ~[?:?]
at org.openhab.core.thing.internal.ChannelLinkNotifier.call(ChannelLinkNotifier.java:96) ~[?:?]
at org.openhab.core.thing.internal.ChannelLinkNotifier.added(ChannelLinkNotifier.java:72) ~[?:?]
at org.openhab.core.thing.internal.ChannelLinkNotifier.added(ChannelLinkNotifier.java:1) ~[?:?]
at org.openhab.core.common.registry.AbstractRegistry.notifyListeners(AbstractRegistry.java:367) ~[?:?]
at org.openhab.core.common.registry.AbstractRegistry.notifyListenersAboutAddedElement(AbstractRegistry.java:400) ~[?:?]
at org.openhab.core.thing.link.ItemChannelLinkRegistry.notifyListenersAboutAddedElement(ItemChannelLinkRegistry.java:138) ~[?:?]
at org.openhab.core.thing.link.ItemChannelLinkRegistry.notifyListenersAboutAddedElement(ItemChannelLinkRegistry.java:1) ~[?:?]
at org.openhab.core.common.registry.AbstractRegistry.added(AbstractRegistry.java:175) ~[?:?]
at org.openhab.core.common.registry.AbstractRegistry.added(AbstractRegistry.java:1) ~[?:?]
at org.openhab.core.common.registry.AbstractProvider.notifyListeners(AbstractProvider.java:60) ~[?:?]
at org.openhab.core.common.registry.AbstractProvider.notifyListeners(AbstractProvider.java:79) ~[?:?]
at org.openhab.core.common.registry.AbstractProvider.notifyListenersAboutAddedElement(AbstractProvider.java:83) ~[?:?]
at org.openhab.core.common.registry.AbstractManagedProvider.add(AbstractManagedProvider.java:67) ~[?:?]
at org.openhab.core.common.registry.AbstractRegistry.add(AbstractRegistry.java:346) ~[?:?]
at org.openhab.core.io.rest.core.internal.link.ItemChannelLinkResource.link(ItemChannelLinkResource.java:238) ~[?:?]
at jdk.internal.reflect.GeneratedMethodAccessor2307.invoke(Unknown Source) ~[?:?]
at jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[?:?]
at java.lang.reflect.Method.invoke(Method.java:566) ~[?:?]
at org.apache.cxf.service.invoker.AbstractInvoker.performInvocation(AbstractInvoker.java:179) ~[bundleFile:3.4.5]
at org.apache.cxf.service.invoker.AbstractInvoker.invoke(AbstractInvoker.java:96) ~[bundleFile:3.4.5]
at org.apache.cxf.jaxrs.JAXRSInvoker.invoke(JAXRSInvoker.java:201) ~[bundleFile:3.4.5]
at org.apache.cxf.jaxrs.JAXRSInvoker.invoke(JAXRSInvoker.java:104) ~[bundleFile:3.4.5]
at org.apache.cxf.interceptor.ServiceInvokerInterceptor$1.run(ServiceInvokerInterceptor.java:59) ~[bundleFile:3.4.5]
at org.apache.cxf.interceptor.ServiceInvokerInterceptor.handleMessage(ServiceInvokerInterceptor.java:96) ~[bundleFile:3.4.5]
at org.apache.cxf.phase.PhaseInterceptorChain.doIntercept(PhaseInterceptorChain.java:308) ~[bundleFile:3.4.5]
at org.apache.cxf.transport.ChainInitiationObserver.onMessage(ChainInitiationObserver.java:121) ~[bundleFile:3.4.5]
at org.apache.cxf.transport.http.AbstractHTTPDestination.invoke(AbstractHTTPDestination.java:265) ~[bundleFile:3.4.5]
at org.apache.cxf.transport.servlet.ServletController.invokeDestination(ServletController.java:234) ~[bundleFile:3.4.5]
at org.apache.cxf.transport.servlet.ServletController.invoke(ServletController.java:208) ~[bundleFile:3.4.5]
at org.apache.cxf.transport.servlet.ServletController.invoke(ServletController.java:160) ~[bundleFile:3.4.5]
at org.apache.cxf.transport.servlet.CXFNonSpringServlet.invoke(CXFNonSpringServlet.java:225) ~[bundleFile:3.4.5]
at org.apache.cxf.transport.servlet.AbstractHTTPServlet.handleRequest(AbstractHTTPServlet.java:298) ~[bundleFile:3.4.5]
at org.apache.cxf.transport.servlet.AbstractHTTPServlet.doPut(AbstractHTTPServlet.java:234) ~[bundleFile:3.4.5]
at javax.servlet.http.HttpServlet.service(HttpServlet.java:710) ~[bundleFile:3.1.0]
at org.apache.cxf.transport.servlet.AbstractHTTPServlet.service(AbstractHTTPServlet.java:273) ~[bundleFile:3.4.5]
at org.eclipse.jetty.servlet.ServletHolder.handle(ServletHolder.java:799) ~[bundleFile:9.4.46.v20220331]
at org.eclipse.jetty.servlet.ServletHandler.doHandle(ServletHandler.java:550) ~[bundleFile:9.4.46.v20220331]
at org.ops4j.pax.web.service.jetty.internal.HttpServiceServletHandler.doHandle(HttpServiceServletHandler.java:74) ~[bundleFile:?]
at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:143) ~[bundleFile:9.4.46.v20220331]
at org.eclipse.jetty.security.SecurityHandler.handle(SecurityHandler.java:600) ~[bundleFile:9.4.46.v20220331]
at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:127) ~[bundleFile:9.4.46.v20220331]
at org.eclipse.jetty.server.handler.ScopedHandler.nextHandle(ScopedHandler.java:235) ~[bundleFile:9.4.46.v20220331]
at org.eclipse.jetty.server.session.SessionHandler.doHandle(SessionHandler.java:1624) ~[bundleFile:9.4.46.v20220331]
at org.eclipse.jetty.server.handler.ScopedHandler.nextHandle(ScopedHandler.java:233) ~[bundleFile:9.4.46.v20220331]
at org.eclipse.jetty.server.handler.ContextHandler.doHandle(ContextHandler.java:1440) ~[bundleFile:9.4.46.v20220331]
at org.ops4j.pax.web.service.jetty.internal.HttpServiceContext.doHandle(HttpServiceContext.java:294) ~[bundleFile:?]
at org.eclipse.jetty.server.handler.ScopedHandler.nextScope(ScopedHandler.java:188) ~[bundleFile:9.4.46.v20220331]
at org.eclipse.jetty.servlet.ServletHandler.doScope(ServletHandler.java:501) ~[bundleFile:9.4.46.v20220331]
at org.eclipse.jetty.server.session.SessionHandler.doScope(SessionHandler.java:1594) ~[bundleFile:9.4.46.v20220331]
at org.eclipse.jetty.server.handler.ScopedHandler.nextScope(ScopedHandler.java:186) ~[bundleFile:9.4.46.v20220331]
at org.eclipse.jetty.server.handler.ContextHandler.doScope(ContextHandler.java:1355) ~[bundleFile:9.4.46.v20220331]
at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:141) ~[bundleFile:9.4.46.v20220331]
at org.ops4j.pax.web.service.jetty.internal.JettyServerHandlerCollection.handle(JettyServerHandlerCollection.java:90) ~[bundleFile:?]
at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:127) ~[bundleFile:9.4.46.v20220331]
at org.eclipse.jetty.server.Server.handle(Server.java:516) ~[bundleFile:9.4.46.v20220331]
at org.eclipse.jetty.server.HttpChannel.lambda$handle$1(HttpChannel.java:487) ~[bundleFile:9.4.46.v20220331]
at org.eclipse.jetty.server.HttpChannel.dispatch(HttpChannel.java:732) [bundleFile:9.4.46.v20220331]
at org.eclipse.jetty.server.HttpChannel.handle(HttpChannel.java:479) [bundleFile:9.4.46.v20220331]
at org.eclipse.jetty.server.HttpConnection.onFillable(HttpConnection.java:277) [bundleFile:9.4.46.v20220331]
at org.eclipse.jetty.io.AbstractConnection$ReadCallback.succeeded(AbstractConnection.java:311) [bundleFile:9.4.46.v20220331]
at org.eclipse.jetty.io.FillInterest.fillable(FillInterest.java:105) [bundleFile:9.4.46.v20220331]
at org.eclipse.jetty.io.ChannelEndPoint$1.run(ChannelEndPoint.java:104) [bundleFile:9.4.46.v20220331]
at org.eclipse.jetty.util.thread.strategy.EatWhatYouKill.runTask(EatWhatYouKill.java:338) [bundleFile:9.4.46.v20220331]
at org.eclipse.jetty.util.thread.strategy.EatWhatYouKill.doProduce(EatWhatYouKill.java:315) [bundleFile:9.4.46.v20220331]
at org.eclipse.jetty.util.thread.strategy.EatWhatYouKill.tryProduce(EatWhatYouKill.java:173) [bundleFile:9.4.46.v20220331]
at org.eclipse.jetty.util.thread.strategy.EatWhatYouKill.run(EatWhatYouKill.java:131) [bundleFile:9.4.46.v20220331]
at org.eclipse.jetty.util.thread.ReservedThreadExecutor$ReservedThread.run(ReservedThreadExecutor.java:409) [bundleFile:9.4.46.v20220331]
at org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:883) [bundleFile:9.4.46.v20220331]
at org.eclipse.jetty.util.thread.QueuedThreadPool$Runner.run(QueuedThreadPool.java:1034) [bundleFile:9.4.46.v20220331]
at java.lang.Thread.run(Thread.java:829) [?:?]
The light level channel is configured to be a CBUS dimmer, as there aren’t too many CBUS object types. Looking at those logs, it looks like it’s complaining about wanting a percentage value.
Curious, what was the error with Illuminance? According to docs, it should have lux as unit. Actually, LluminousFlux should have lumen as unit, not lux.
Actually, it does work using Number:Illuminance. I’ve just tried it again and it works fine. I must have done something wrong when I tried it previously, as the item value became NULL.