New Automation: Pulse Width Modulation (PWM)

This introduces a Pulse Width Modulation module for openHAB.

PWM can be used to control actuators continuously from 0 to 100% that only support ON/OFF commands. E.g. valves or heating burners. It accomplishes that by switching the actuator on and off with a fixed interval. The higher the control percentage (duty cycle), the longer the ON phase.

The module can be used via Rules:

EDIT: The automation module is part of the official release, now. It can be installed in the MainUI under Settings/Add-ons/Automation.

The documentation is available here.

6 Likes

Great, thanks for this.

Hi,

I am trying to configure PWM automation. When I set up a rule and I do select “PWM trigger”.

But in “Then” part I do not have a choice of “callculate PWM output”, in fact nothing like PWM.

Please advise on the details of configuration.

The linked documentation and the screenshots in the thread were outdated. The module is part of the official release, now. You need to add an “Item Action” instead. I updated the screenshot and the link to the documentation in the original post.

To configure a rule, you need to add a Trigger (“PWM triggers”) and an Action (“Item Action”). Select the Item you like to control in the “Item Action” and leave the command empty.

1 Like

Thanks Fabian,

It worked. The problem that tricked me was this - when a corrected rule is saved, one needs to update DutyCycleItem value in order the process to restart.

Thanks for help.

1 Like

Thanks for this, I can definitely see its uses! I’m looking at this for my heating system,where if I need 20% duty on two outputs, and 30% on a 3rd, I’d like them to all start their cycle at the same point in time, so the first 20% of the interval is shared with all 3 of them on, then two switch off, and 10% later the final one switches off, and they’re all then off together.

If I have multiple PWM rules, with a common interval, can I get them to sync up? Or will they naturally do this?

Cheers!

If they are started at the same time (e.g. when OH is started), they should run synchronized and diverge very very slowly. I guess I can change the code to eliminate the slow diverging, but I first want to hear your experience.

1 Like

Thank you for the prompt reply! I’ll investigate swapping over a couple of rooms to use this (plus the recently added PID control) and will let you know! :slight_smile:

When trying the PWM Automation, it appears that the first trigger fired before the rule was fully ready.

09:23:57.630 [TRACE] [.automation.internal.RuleEventFactory] - creating ruleEvent of type: RuleAddedEvent
09:23:57.636 [DEBUG] [re.automation.internal.RuleEngineImpl] - The trigger '97f8ad3d-0097-48cc-9215-e27f72e6f5c9' of rule 'dcc9dec1-cf3b-4b61-94a0-3b322c7cd3a6' is triggered.
09:23:57.640 [ERROR] [re.automation.internal.RuleEngineImpl] - Failed to execute rule ‘dcc9dec1-cf3b-4b61-94a0-3b322c7cd3a6' with status 'INITIALIZING'
09:23:57.643 [TRACE] [.automation.internal.RuleEventFactory] - creating ruleEvent of type: RuleStatusInfoEvent
09:23:57.648 [TRACE] [.automation.internal.RuleEventFactory] - creating ruleEvent of type: RuleStatusInfoEvent
09:23:57.658 [TRACE] [.automation.internal.RuleEventFactory] - creating ruleEvent of type: RuleStatusInfoEvent
09:23:57.665 [DEBUG] [ort.internal.loader.ScriptFileWatcher] - Script loaded: /Users/jimmy/Projects/openhab-jruby/tmp/openhab/conf/automation/jsr223/ruby/personal/cucumber_test20211122-20576-1q077gu.rb

Subsequent triggers were fine.

Just a question.

Is it possible to run over a group of PWM-sources?

Lets say I’ve got 13 floor heating items (0
100%) and need to control 13 valves, do I need to setup 13 PWM triggeres (one for each item) or can I use groups ( and handle value item names within scripts).

I have everything in the same naming:
floor1_temperature
floor1_setpoint
floor1_pwm
floor1_value

floor1_temperature is firing my rules now, in the rule script i’m matching item points using:
var = event.itemName.replace(’_temperature’, ‘_setpoint’);
var = event.itemName.replace(’_temperature’, ‘_pwm’);
var = event.itemName.replace(’_temperature’, ‘_value’);

Am I able to use the PWM rule to walk through the 15 group members '_pwm", and then using something like above scripting to set corresponding ‘_valve’ items?

Best regards

Sure, you can set up one PWM module and feed all your Items with the PWM output via a rule/script. To build a regulation, you might want to use the PID Controller module. But in general, this is more a question on rules, than PWM-specific.

is it possible to use this module from a text rule definition openhab/rules/xxx.rules insted of GUI configuration ?

Here is an example using the PID controller with JavaScript. Should be very similar for the PWM module. New Automation: PID Controller - #23 by hilbrand

Thank you i managed to do it. The only problem is that GUI is not showing the rule config like it does when you created it via gui :frowning:

@fwolter one more question - how the interval should be set, my use case is :
heating valve actuator NC with 180 second needed to fully open the valve after switching it on
PID conntroller → PWM → Relay. Should this interval time by somehow synced with PID controller timings?
I am not sure if i understood the readme:)

The interval doesn’t need to be synced with the PID controller, if the loop time of the PID controller is much faster than the interval of the PWM (maybe 10 times). Doesn’t hurt to decrease the interval of the PID controller, anyway.

If your valves need 180s to open, I’d start with an PWM interval of maybe factor 5, i.e. 15min in your case.

1 Like

hi @fwolter, thank you! it’s working well. One interesting behaviour during some testing / jss scripting.
If i want to disable PWM rule from .js - “vacation setting”

rules.setEnabled(`Termostat_1_PWM_rule`,false) i get: 

 Failed to execute rule 'Termostat_1_modes_management': Fail to execute action: 1
2022-06-08 19:38:44.367 [ERROR] [tomation.script.file.rulesCreator.js] - Failed to execute rule Termostat_7_modes_management: java.util.concurrent.RejectedExecutionException: Task java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask@65e27b99[Not completed, task = java.util.concurrent.Executors$RunnableAdapter@132d2e1d[Wrapped task = org.openhab.core.automation.internal.TriggerHandlerCallbackImpl$TriggerData@562fa21c]] rejected from java.util.concurrent.ScheduledThreadPoolExecutor@6733b492[Terminated, pool size = 0, active threads = 0, queued tasks = 0, completed tasks = 1]
2022-06-08 19:38:44.373 [ERROR] [e.automation.internal.RuleEngineImpl] - Failed to execute rule 'Termostat_7_modes_management': Fail to execute action: 1

rules |modes_management" are only a proxy for setting right work mode, but the issue is when this rules executes disabling the PWM rule. i can without errors disable other rules even the PID controller automation, but with PWM i get this :frowning:
not crucial i can set deadmanswitch and disable PID controller rule only, but maybe it;s possible to fix it

p.s.
what is interesting i can disable /enable the rule when i use GUI and put only a single line in a script
rules.setEnabled(Termostat_1_PWM_rule,false) or true but log is showing:


2022-06-08 19:48:07.812 [WARN ] [.internal.OpenhabGraalJSScriptEngine] - Failed to retrieve script script dependency listener from engine bindings. Script dependency tracking will be disabled.
2022-06-08 19:48:48.565 [WARN ] [.internal.OpenhabGraalJSScriptEngine] - Failed to retrieve script script dependency listener from engine bindings. Script dependency tracking will be disabled.
2022-06-08 19:48:55.475 [WARN ] [.internal.OpenhabGraalJSScriptEngine] - Failed to retrieve script script dependency listener from engine bindings. Script dependency tracking will be disabled.

Hi,
i am using PID and PWM on few hosts. Have one problem with the PWM module, which randomly (cant find out exact behavior) stops sending ON/OFF command to an action item even if the dutycycle item is 0 or 100 . Don’t know the exact reason and how to reproduce it.

when i change manually relay to ON and OFF again

2022-11-07 21:07:24.093 [INFO ] [openhab.event.ItemCommandEvent ] - Item ‘RadiatorAC5_PWM_dutycycleItem’ received command 100.0
2022-11-07 21:07:33.701 [INFO ] [openhab.event.ItemCommandEvent ] - Item ‘RadiatorAC5_PWM_Relay’ received command ON
2022-11-07 21:07:33.720 [INFO ] [penhab.event.ItemStatePredictedEvent] - Item ‘RadiatorAC5_PWM_Relay’ predicted to become ON
2022-11-07 21:07:33.746 [INFO ] [openhab.event.ItemStateChangedEvent ] - Item ‘RadiatorAC5_PWM_Relay’ changed from OFF to ON
2022-11-07 21:07:38.900 [INFO ] [openhab.event.ItemCommandEvent ] - Item ‘RadiatorAC5_PWM_Relay’ received command OFF
2022-11-07 21:07:38.909 [INFO ] [penhab.event.ItemStatePredictedEvent] - Item ‘RadiatorAC5_PWM_Relay’ predicted to become OFF
2022-11-07 21:07:38.929 [INFO ] [openhab.event.ItemStateChangedEvent ] - Item ‘RadiatorAC5_PWM_Relay’ changed from ON to OFF
2022-11-07 21:07:54.090 [INFO ] [openhab.event.ItemStateChangedEvent ] - Item ‘RadiatorAC5_PID_iInspector’ changed from 0.92525552 to 1.3480696133333332
2022-11-07 21:07:54.098 [INFO ] [openhab.event.ItemCommandEvent ] - Item ‘RadiatorAC5_PWM_dutycycleItem’ received command 100.0

but still no ON command after that

Logs:

2022-11-07 20:52:24.056 [INFO ] [openhab.event.ItemCommandEvent      ] - Item 'RadiatorAC5_PWM_dutycycleItem' received command 100.0
2022-11-07 20:52:54.055 [INFO ] [openhab.event.ItemStateChangedEvent ] - Item 'RadiatorAC5_PID_iInspector' changed from 83.28955768000003 to 83.85237644000003
2022-11-07 20:52:54.058 [INFO ] [openhab.event.ItemCommandEvent      ] - Item 'RadiatorAC5_PWM_dutycycleItem' received command 100.0
2022-11-07 20:53:24.066 [INFO ] [openhab.event.ItemCommandEvent      ] - Item 'RadiatorAC5_PWM_dutycycleItem' received command 100.0
2022-11-07 20:53:24.076 [INFO ] [openhab.event.ItemStateChangedEvent ] - Item 'RadiatorAC5_PID_iInspector' changed from 83.85237644000003 to 84.41519520000003
2022-11-07 20:53:54.058 [INFO ] [openhab.event.ItemStateChangedEvent ] - Item 'RadiatorAC5_PID_iInspector' changed from 84.41519520000003 to 84.97801396000003
2022-11-07 20:53:54.060 [INFO ] [openhab.event.ItemCommandEvent      ] - Item 'RadiatorAC5_PWM_dutycycleItem' received command 100.0
2022-11-07 20:54:24.058 [INFO ] [openhab.event.ItemStateChangedEvent ] - Item 'RadiatorAC5_PID_iInspector' changed from 84.97801396000003 to 85.54083272000003
2022-11-07 20:54:24.060 [INFO ] [openhab.event.ItemCommandEvent      ] - Item 'RadiatorAC5_PWM_dutycycleItem' received command 100.0
2022-11-07 20:54:54.059 [INFO ] [openhab.event.ItemStateChangedEvent ] - Item 'RadiatorAC5_PID_iInspector' changed from 85.54083272000003 to 86.10365148000002
2022-11-07 20:54:54.064 [INFO ] [openhab.event.ItemCommandEvent      ] - Item 'RadiatorAC5_PWM_dutycycleItem' received command 100.0
2022-11-07 20:55:11.993 [INFO ] [openhab.event.ItemCommandEvent      ] - Item 'RadiatorAC5_PID_commandItem' received command RESET
2022-11-07 20:55:11.997 [INFO ] [openhab.event.ItemStateChangedEvent ] - Item 'RadiatorAC5_PID_commandItem' changed from NULL to RESET
2022-11-07 20:55:12.001 [INFO ] [openhab.event.ItemStateChangedEvent ] - Item 'RadiatorAC5_PID_commandItem' changed from RESET to NULL
2022-11-07 20:55:24.065 [INFO ] [openhab.event.ItemCommandEvent      ] - Item 'RadiatorAC5_PWM_dutycycleItem' received command 100.0
2022-11-07 20:55:24.071 [INFO ] [openhab.event.ItemStateChangedEvent ] - Item 'RadiatorAC5_PID_iInspector' changed from 86.10365148000002 to 0.56281876
2022-11-07 20:55:54.067 [INFO ] [openhab.event.ItemStateChangedEvent ] - Item 'RadiatorAC5_PID_iInspector' changed from 0.56281876 to 1.12563752
2022-11-07 20:55:54.069 [INFO ] [openhab.event.ItemCommandEvent      ] - Item 'RadiatorAC5_PWM_dutycycleItem' received command 100.0
2022-11-07 20:56:24.065 [INFO ] [openhab.event.ItemCommandEvent      ] - Item 'RadiatorAC5_PWM_dutycycleItem' received command 100.0
2022-11-07 20:56:24.069 [INFO ] [openhab.event.ItemStateChangedEvent ] - Item 'RadiatorAC5_PID_iInspector' changed from 1.12563752 to 1.68845628
2022-11-07 20:56:54.067 [INFO ] [openhab.event.ItemCommandEvent      ] - Item 'RadiatorAC5_PWM_dutycycleItem' received command 100.0
2022-11-07 20:56:54.072 [INFO ] [openhab.event.ItemStateChangedEvent ] - Item 'RadiatorAC5_PID_iInspector' changed from 1.68845628 to 2.25127504

ok i got it
 Disabling and Enabling the rule again fix the problem but don’t know for how long:


2022-11-07 21:10:34.183 [INFO ] [openhab.event.ItemCommandEvent      ] - Item 'RadiatorAC5_PWM_Relay' received command OFF
2022-11-07 21:10:34.196 [INFO ] [penhab.event.ItemStatePredictedEvent] - Item 'RadiatorAC5_PWM_Relay' predicted to become OFF
2022-11-07 21:10:54.138 [INFO ] [openhab.event.ItemCommandEvent      ] - Item 'RadiatorAC5_PWM_dutycycleItem' received command 100.0
2022-11-07 21:10:54.144 [INFO ] [openhab.event.ItemStateChangedEvent ] - Item 'RadiatorAC5_PID_iInspector' changed from 3.457061346666667 to 3.874275253333334
2022-11-07 21:10:54.159 [INFO ] [openhab.event.ItemCommandEvent      ] - Item 'RadiatorAC5_PWM_Relay' received command ON
2022-11-07 21:10:54.164 [INFO ] [penhab.event.ItemStatePredictedEvent] - Item 'RadiatorAC5_PWM_Relay' predicted to become ON
2022-11-07 21:10:54.174 [INFO ] [openhab.event.ItemStateChangedEvent ] - Item 'RadiatorAC5_PWM_Relay' changed from OFF to ON
2022-11-07 21:11:24.139 [INFO ] [openhab.event.ItemCommandEvent      ] - Item 'RadiatorAC5_PWM_dutycycleItem' received command 100.0
2022-11-07 21:11:24.145 [INFO ] [openhab.event.ItemStateChangedEvent ] - Item 'RadiatorAC5_PID_iInspector' changed from 3.874275253333334 to 4.291503066666667

but still it seems like an error to me. I can add that i am using some enable/disable rules which are triggered by IOS app - when i turn off thermostat i disable the PID and PWM rule, and then enabling them again if you choose different mode.

OK PID controller produces the dutycycleitem and PWM has it’s own cycle which is a bit slower. Can somebody confirm that on every PWM cycle relay items should get ON / OFF command even if the relay item already has correct ON/OFF state ?

The PWM module sends a command always, regardless of the state of the target Item.

If you still encounter problems you can enable the logging for org.openhab.automation.pwm at TRACE level. This will show the state changes of the PWM module internal state machine.

1 Like

thank you - is there a way to see which PWM rule is reporting to the logs in case i have more than one? i am not able to do it in trace level

19:21:38.305 [WARN ] [wm.internal.handler.PWMTriggerHandler] - Dead-man switch activated. Disabling output
19:21:38.310 [TRACE] [tion.pwm.internal.handler.state.State] - AlwaysOffState → AlwaysOffState