Heating and window contact - a (simple?) rule [SOLVED]

Hi all,

I am starting to implement rules to trigger heating on/off when a window will be closed/opened.

The window contact (ESP8266 based, self designed/programmed :slightly_smiling_face:) works through MQTT protocol

Switch  Studio_Window_StudWinESP8266reed_DoorSensor   "Studio Window Status [MAP(reed.map):%s]"   <door>        (GuestRoom, gOpenItems)   ["ReedSensor"]      {channel="mqtt:homie300:efd6615c:studwinesp8266reed:studWinESP8266reed#doorSensor"}

with reed.map

OFF=closed
ON=open
NULL=unknown

The corresponding thermovalve (Spirit Z-wave) has an item to control the heat mode

Number Studio_ZWaveThermoValve_ThermostatMode "Guest Room Thermovalve Mode [%.1f]"                    <temperature>      (GuestRoom, gThermoValveMode)    ["Thermovalve Mode"]   {channel="zwave:device:f3ae20de:node2:thermostat_mode"}

Both the status of the door sensor and the manual setting of the thermovalve work perfectly.

Now the rule (far from being elegant, but I want a first working set before going for bells and whistles - suggestions welcome!)

rule "A door sensor has been triggered"
when
    Member of gOpenItems changed
then
    val String ruleIdentifier = "Setting Thermovalve"

    val window = triggeringItem

    logInfo(ruleIdentifier, "{} has triggered the event!", window.name)

    val roomName = window.name.split("_").get(0)
    val thermoValveName = roomName+"_ZWaveThermoValve_ThermostatMode"

    val windowState = if(window.state == ON) "open" else "close"
    val setValue = if(window.state == ON) 0 else 1

    logInfo(ruleIdentifier, "{} has just {}! Setting {} to {}", roomName, windowState, thermoValveName, setValue)

    thermoValveName.sendCommand(setValue)
end

The rule does not work, and the error message is

2020-03-20 23:46:32.737 [INFO ] [ome.model.script.Setting Thermovalve] - Studio_Window_StudWinESP8266reed_DoorSensor has triggered the event!
2020-03-20 23:46:32.750 [INFO ] [ome.model.script.Setting Thermovalve] - Studio has just open! Setting Studio_ZWaveThermoValve_ThermostatMode to 0
2020-03-20 23:46:32.753 [ERROR] [ntime.internal.engine.RuleEngineImpl] - Rule 'A door sensor has been triggered': An error occurred during the script execution: Could not invoke method: org.eclipse.smarthome.model.script.actions.BusEvent.sendCommand(java.lang.String,java.lang.String) on instance: null

If I replace the line

thermoValveName.sendCommand(setValue)

with the explicit Item name (I have only one thermovalve for testing purposes)

Studio_ZWaveThermoValve_ThermostatMode.sendCommand(setValue)

everything works

2020-03-20 23:50:32.291 [INFO ] [ome.model.script.Setting Thermovalve] - Studio_Window_StudWinESP8266reed_DoorSensor has triggered the event!
2020-03-20 23:50:32.302 [INFO ] [ome.model.script.Setting Thermovalve] - Studio has just close! Setting Studio_ZWaveThermoValve_ThermostatMode to 1
2020-03-20 23:50:32.336 [ome.event.ItemCommandEvent] - Item 'Studio_ZWaveThermoValve_ThermostatMode' received command 1
2020-03-20 23:50:32.340 [nt.ItemStatePredictedEvent] - Studio_ZWaveThermoValve_ThermostatMode predicted to become 1

Could you help me with this? And generally, where is there any comprehensive doc (other than this) to understand how to write rules? I have past experience in more “conventional” programming languages (C, C++, Python), is Jython perhaps a valid alternative?

Thanks!
Max

Your variable thermoValveName is just a string. It happens to look like one your Item’s names, but is just string, same as “banana”. So it doesn’t have a .sendCommand method, it’s not an actual Item.

You are in luck though, the sendCommand() action actually wants to be given an Item name as a string, and will search for it for you.
Beware, the command must be a string too.

sendCommand(thermoValveName, setValue.toString)

For more advanced get-an-Item-from-string-name methods, see

The general approach you are using is covered here

which includes more than one approach to grabbing an Item by name

Thanks @rossko57!

Using the ScriptServiceUtil is nice and works (whole rule below), but reading the comment about resources I will perhaps implement the associated item solution, with the FindFirst function (surely another post will appear here around :wink:)

import org.eclipse.smarthome.model.script.ScriptServiceUtil

rule "A door sensor has been triggered"
when
     Member of gOpenItems changed
then
     val String ruleIdentifier = "Setting Thermovalve"
     
     val window = triggeringItem
     
     logInfo(ruleIdentifier, "{} has triggered the event!", window.name)

     val roomName = window.name.split("_").get(0)

     val thermoValveName = roomName+"_ZWaveThermoValve_ThermostatMode"

     var thermoValveItem

     if (ScriptServiceUtil.getItemRegistry.getItem(thermoValveName) == newArrayList) {
          logInfo(ruleIdentifier, "{} does not have an associated thermovalve with name {}", roomName, thermoValveName)
          return;
     }
     else
          thermoValveItem = ScriptServiceUtil.getItemRegistry.getItem(thermoValveName)

     val windowState = if(window.state == ON) "open" else "close"
     val setValue = if(window.state == ON) 0 else 1

     logInfo(ruleIdentifier, "{} got to status {}! Setting {} to {}", roomName, windowState, thermoValveName, setValue)

     thermoValveItem.sendCommand(setValue)

end