1) Introduction
I’m a beginner so I found some problem to understand Exec Binding. In my opinion the guide isn’t clear for this addon. I think there should be in exec binding one command to execute an external program, the response of the program and optional another external command to check the “state” of the thing.
Please sorry for my english
2) Purpose of tutorial
This is a step by step tutorial to change a GPIO value in a remote raspberry pi with openhab using Exec binding 2.x. The binding will run a bash script in OpenHab linux server that change gpio value in another raspberry pi. I have openhabian in a raspberry pi 4. In my example GPIO pin 21,22,23,25 command a 4 channel-relay (GPIO pin 21 command one relay, GPIO pin 22 command another relay…ecc)
3) Preparation
Remote Raspberry pi
Access to the remote raspberry pi where you want to change pin and install wiring pi. To check if it works you can change the value of the GPIO pin using.
gpio write 22 1
gpio write 22 0
User openhab has to access to the remote raspberry. Change user@hostname (e.g. root@192.168.1.100) with the one of remote raspberry and access with password. This will copy the public key to the remote system
sudo -u openhab ssh-keygen -t rsa
sudo -u openhab ssh-copy-id -i /var/lib/openhab2/.ssh/id_rsa.pub user@hostname
Check if openhab user can access to the remote system
sudo -u openhab ssh user@hostname
create a folder for Scripts (I create /home/openhabian/Script) and a file RemoteGpioSwitch.sh. Change in the file the word “user” with the right username (e.g. user@$2 → root@$2)
#!/bin/bash
## USE RemoteGpioSwitch.sh GPIO_PIN IP_SSH ON_OFF
# If I have ON in input I put on the GPIO of the relay else I put off the gpio pin of the relay
if [[ "$3" = "ON" ]] || [[ "$3" = "On" ]] || [[ "$3" = "on" ]] ; then
Comando=$(ssh user@$2 "/usr/local/bin/gpio write $1 1")
# echo $Comando > /home/openhabian/Script/onoff.txt
echo OFF
else
# gpio write $1 1
Comando=$(ssh user@$2 "/usr/local/bin/gpio write $1 0")
# echo $Comando > /home/openhabian/Script/onoff.txt
echo ON
fi
Give permission to the script (I use chmod 777 to give all the permissions to the file, remember that user openhab have to use this, when you access in SSH your user is openhabian)
Now you can test the script to see if it works like you want, arguments are:
GPIO_PIN->Pin of remote raspberry pi
IP_SSH->IP of remote raspberry pi
ON_OFF-> ON or OFF
e.g.
sudo -u openhab /home/openhabian/Script/RemoteGpioSwitch.sh 22 192.168.1.100 ON
Openhabian Paper UI
Install exec 2.x binding from Add-ons->bindings
Install RegEx transformation from binding from Add-ons->Transformations. The transformation is used by default in the binding if no other is specified(I read it somewhere in the forum, but I can’t remember where)
Openhabian SSH
Now we start with openhab configurations.
nano $OPENHAB_CONF/sitemaps/presecontrollate.sitemap
sitemap presecontrollate label="Powerplug"
{
Frame label="Powerplug"
{
Switch item=Sala_Power1_1 label="Stereo Sala"
Switch item=Sala_Power1_2 label="TV"
Switch item=Sala_Power1_3 label="Lamp"
Switch item=Sala_Power1_4 label="Vuota"
}
}
nano $OPENHAB_CONF/things/exec.things
Thing exec:command:Sala_Power1_1_Send "Sala_Power1_1" [
command="/home/openhabian/Script/RemoteGpioSwitch.sh %2$s",
interval=0,
autorun=true]
Thing exec:command:Sala_Power1_2_Send "Sala_Power1_2" [
command="/home/openhabian/Script/RemoteGpioSwitch.sh %2$s",
interval=0,
autorun=true]
Thing exec:command:Sala_Power1_3_Send "Sala_Power1_3" [
command="/home/openhabian/Script/RemoteGpioSwitch.sh %2$s",
interval=0,
autorun=true]
Thing exec:command:Sala_Power1_4_Send "Sala_Power1_4" [
command="/home/openhabian/Script/RemoteGpioSwitch.sh %2$s",
interval=0,
autorun=true]
nano $OPENHAB_CONF/items/exec.items
// Presa controllata Power1 - Sala - Raspberry
// Presa 1 - Stereo Sala
Switch Sala_Power1_1 "Stereo Sala" <poweroutlet> {alexa="PowerController.powerState"}
Switch Sala_Power1_1_Send "Running" { channel="exec:command:Sala_Power1_1_Send:run" }
String Sala_Power1_1_Send_Args "Input" { channel="exec:command:Sala_Power1_1_Send:input"}
String Sala_Power1_1_Send_Out "State" { channel="exec:command:Sala_Power1_1_Send:output"}
// Presa 2 - TV
Switch Sala_Power1_2 "TV" <poweroutlet> {alexa="PowerController.powerState"}
Switch Sala_Power1_2_Send "Running" { channel="exec:command:Sala_Power1_2_Send:run" }
String Sala_Power1_2_Send_Args "Input" { channel="exec:command:Sala_Power1_2_Send:input"}
String Sala_Power1_2_Send_Out "State" { channel="exec:command:Sala_Power1_2_Send:output" }
// Presa 3 - Palle di "Natale"
Switch Sala_Power1_3 "Lamp" <poweroutlet> {alexa="PowerController.powerState"}
Switch Sala_Power1_3_Send "Running" { channel="exec:command:Sala_Power1_3_Send:run" }
String Sala_Power1_3_Send_Args "Input" { channel="exec:command:Sala_Power1_3_Send:input"}
String Sala_Power1_3_Send_Out "State" { channel="exec:command:Sala_Power1_3_Send:output" }
// Presa 4 - Presa vuota
Switch Sala_Power1_4 "vuota sala" <poweroutlet> {alexa="PowerController.powerState"}
Switch Sala_Power1_4_Send "Running" { channel="exec:command:Sala_Power1_4_Send:run" }
String Sala_Power1_4_Send_Args "Input" { channel="exec:command:Sala_Power1_4_Send:input"}
String Sala_Power1_4_Send_Out "State" { channel="exec:command:Sala_Power1_4_Send:output" }
In the items there is also Alexa integration. This is the part of code for Alexa: {alexa=“PowerController.powerState”}, if you don’t have it remove only the part between{ }
“Lamp” in the example is part of the Alexa voice command. You can choose the label that you want
Switch Sala_Power1_3 "Lamp" <poweroutlet> {alexa="PowerController.powerState"}
Then we have to define rules.
nano $OPENHAB_CONF/items/exec.rules
import org.eclipse.smarthome.model.script.ScriptServiceUtil
//______________________________________________________Presa controllata Power1 - Sala - Raspberry_____________________________
//----------------------------------------------------- Presa 1 - Stereo Sala
rule "Power1_1 Stereo"
when
Item Sala_Power1_1 received command
then
if(receivedCommand == ON){
Sala_Power1_1_Send_Args.sendCommand("21 192.168.1.21 OFF")
}else{
Sala_Power1_1_Send_Args.sendCommand("21 192.168.1.21 ON")
}
end
// ---------------------------------------------------- Presa 2 - TV
rule "Power1_2 TV"
when
Item Sala_Power1_2 received command
then
if(receivedCommand == ON){
Sala_Power1_2_Send_Args.sendCommand("22 192.168.1.21 OFF")
}else{
Sala_Power1_2_Send_Args.sendCommand("22 192.168.1.21 ON")
}
end
//----------------------------------------------------- Presa 3 - LAMP
rule "Power1_3 Lamp"
when
Item Sala_Power1_3 received command
then
if(receivedCommand == ON){
Sala_Power1_3_Send_Args.sendCommand("23 192.168.1.21 OFF")
}
else{
Sala_Power1_3_Send_Args.sendCommand("23 192.168.1.21 ON")
}
end
//----------------------------------------------------- Presa 4 - Presa vuota
rule "Power1_4 Vuota"
when
Item Sala_Power1_4 received command
then
if(receivedCommand == ON){
Sala_Power1_4_Send_Args.sendCommand("25 192.168.1.21 OFF")
}else{
Sala_Power1_4_Send_Args.sendCommand("25 192.168.1.21 ON")
}
end
//To see log give this command in SSH
//tail -f /var/log/openhab2/openhab.log -f /var/log/openhab2/events.log
// This rule is for logging purpose.
rule "report exec finished"
when
Item Sala_Power1_1_Send changed to OFF or
Item Sala_Power1_2_Send changed to OFF or
Item Sala_Power1_3_Send changed to OFF or
Item Sala_Power1_4_Send changed to OFF
// you could use Group trigger with Member of here instead
then
// find linked item
val targetName = triggeringItem.name + "_Out"
val myStatus = ScriptServiceUtil.getItemRegistry.getItem(targetName)
// do message
logInfo("Power_Plug", "Results are: \n" + targetName + " " + myStatus.state )
end
Now you can control from Basic UI the GPIO pins
Sources
Thanks for an improvement in the tutorial code
rossko57 - OpenHAB logging items status (removed while loop in items rule)