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.


Great, thanks for this.


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?


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

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.