Create a rule for play/pause MPD using a Hue dimmer switch

,
  • Platform information:
    • OS: Ubuntu-Server 22.04.2
    • Java Runtime Environment: build 11.0.18+10-post-Ubuntu-0ubuntu122.04
    • openHAB version: 3.4.2

*Issue of the topic:
I need help creating a rule for sending a play command to MPD when I press the first button of my hue dimmer switch (setting up a second one for stop should be easy once this works).
I created this rule using a blockly script for the action:

configuration: {}
triggers:
  - id: "1"
    configuration:
      event: "1000.0"
      channelUID: hue:xxxx:xxxxxxxxxxxxxxxx:xx:dimmer_switch_event
    type: core.ChannelEventTrigger
conditions: []
actions:
  - inputs: {}
    id: "2"
    configuration:
      blockSource: <xml xmlns="https://developers.google.com/blockly/xml"><block
        type="controls_if" id="?$?mq$h29E@K[5~b-d2-" x="156" y="124"><value
        name="IF0"><block type="logic_compare" id="L5|y%T^l$2ga^g{M~}vy"><field
        name="OP">EQ</field><value name="A"><block type="oh_getthing_state"
        id="*D+]ejP=A:7aCei9$rYc"><value name="thingUid"><shadow type="oh_thing"
        id="RbM%^7?q8`X|vc++#Ukf"><field
        name="thingUid">hue:0820:ecb5fafffe216c4a:37</field></shadow></value></block></value><value
        name="B"><block type="text" id="uz!?H-7|cE+NEbkcon4q"><field
        name="TEXT">1000.0</field></block></value></block></value><statement
        name="DO0"><block type="oh_event" id="q[N$KYLvnWP^@7wPKO:("><field
        name="eventType">sendCommand</field><value name="value"><shadow
        type="text" id="-z!{!v1cc%JQ`eUZs$ut"><field
        name="TEXT">play</field></shadow></value><value name="itemName"><shadow
        type="oh_item" id="7|8e_P01LEm{kTFrFk%W"><field
        name="itemName">Mopidy_MPD_server_on_jujuserver_Fernbedienung</field></shadow></value></block></statement></block></xml>
      type: application/javascript
      script: >
        var things = Java.type("org.openhab.core.model.script.actions.Things")



        if (things.getThingStatusInfo('hue:xxxx:xxxxxxxxxxxxxxxx:xx').getStatus() == '1000.0') {
          events.sendCommand('Mopidy_MPD_server_on_jujuserver_Fernbedienung', 'play');
        }
    type: script.ScriptAction

It probably has some errors since i don´t really understand how to write a rule using the binding descriptions:

Could you tell me how I can fix the Code or how the configuration of items and things has to be set up?

Thank you in advance!

A Thing will never have a status of “1000.0”. It will be ONLINE, OFFLINE, ERROR, INITIALIZING, etc.

Do you mean to check the event that triggered the rule to see if it’s “1000.0”?

It occurs to me that I don’t know how to do that in Blockly. In Rules DSL event will have the value from the channel trigger event that caused the rule to run. In other languages it would be event.event or something like that.

Thanks for your reply.

Yes, I wanted to check for the event “1000.0”.

I had a look at Rules DSL and i guess i have a script that can work (with the help of ChatGPT).
I tested the dimmer switch and the MPD-remote separately. The switch works but the MPD-remote does only work in the GUI:

My problem is the command that has to be send to the remote-player: ChatGPT told me to use “mpc play” or “play”. In the documentation they use

actions.sendCommand("play");

the first part probably due to java. I didn’t manage to use one of them. So how to use the remote?
For simplicity I also tested using the “coding-GUI”. Setting the volume worked.

The rule written by ChatGPT(you don´t have to check it, if it doesn't work I will write my own)
import org.eclipse.xtext.xbase.lib.Functions

val Functions$Function1<HueDimmerSwitch, Boolean> heldLongEnough = [ switch |
    val longPressDuration = 1000
    val buttonPressedSince = switch.lastButtonPressTime - now
    buttonPressedSince >= longPressDuration
]

val Functions$Function1<HueDimmerSwitch, Boolean> wasDimUp = [ switch |
    switch.getEvent().getDirection() == "INCREASE"
]

val Functions$Function1<HueDimmerSwitch, Boolean> wasDimDown = [ switch |
    switch.getEvent().getDirection() == "DECREASE"
]

rule "MPD player control with Philips Hue Dimmer Switch"
when
    Channel "hue:0406:00112233:2:dimmer_switch#buttonevent" triggered
then
    val dimmerSwitch = HueDimmerSwitch.lastEvent
    if (wasDimUp.apply(dimmerSwitch) && heldLongEnough.apply(dimmerSwitch)) {
        logInfo("MPD Control", "Starting MPD player")
        executeCommandLine("mpc play", 1000)
    } else if (wasDimDown.apply(dimmerSwitch) && heldLongEnough.apply(dimmerSwitch)) {
        logInfo("MPD Control", "Stopping MPD player")
        executeCommandLine("mpc stop", 1000)
    }
end

I’ve yet to see ChatGPT produce a working openHAB rule. Always review every line of code against the docs.

Beyond being way more complicated than necessary, the code it generated isn’t sending a command to an Item, it’s using executeCommandLine to call an external program called mpc. I’t also probably a problem to use the reserved word “switch” as a variable name. There’s no such thing as “lastEvent” and if there were, it wouldn’t be a “dimmerSwitch”.

While this rule is less bogus than most, it does not break ChatGPT’s perfect zero when it comes to generating working openHAB rules. You’d have to know enough about coding OH rules to correct this code as you would need to write it in the first place without ChatGPT.

What you need is ultra simple though. First, please please please don’t skip the Getting Started Tutorial and the docs. Please do refer to the many thousands of example rules here on the forum.

Keep your original rule with it’s trigger. Remove the Script Action and replace it with a new one. Your choice. The contents will be very simple:

  1. If you want to stick with Blockly, use an Inline Script block with the following:
if(event.event.intValue == 1000) events.sendCommand('Mopidy_MPD_server_on_jujuserver_Fernbedienung', 'play');

This is pretty much bypassing Blockly almost entirely so you could also…

  1. Choose ECMAScript 5.1 and add the above line of code as the sole line of code

  2. Install and choose JS Scripting (ECMAScript 2021) which is way newer and more future proof with this one liner

if(event.event.intValue == 1000) items.getItem('Mopidy_MPD_server_on_jujuserver_Fernbedienung').sendCommand('play');
  1. Choose Rules DSL as the language with this one liner
if(event.intValue == 1000) Mopidy_MPD_server_on_jujuserver_Fernbedienung
  1. Break it up. Add a Script Condition and choose a language of choice. In this case it’s just going to be the part inside the if statement:
event.event.intValue == 1000

Then you can use a simple Item Action to send the command to the Item, no code required.