I am quite new to openHAB but love it’s possibilities. I have spent a lot of hours reading topics (not only) on this forum which is very helpful and now, when I have some working solution of (I think) new idea, I decided to share it with you. Maybe this will help or inspire some of you, maybe you will have some suggestions how to improve it. So, stop talking, start showing
The setup:
Hardware - I am using ESP8266 NodeMCU v1, where I connected (currently 2, for proof of concept) cheap PIR sensors HC-SR501. The ESP is connected to my MQTT Broker running on RaspberryPi 3 (where also openhabianpi is running). The ESP is submitting value 0 when no motion is detected and 1 when motion was detected to topics Garden/Alarm/Pir01 and Garden/Alarm/Pir02. H / L pin on HC-SR501 is set to H so sensor keeps HIGH signal while there is a motion being detected.
Software - I love dynamic icons and HABPanel. As I plan to have many more motion sensors (probably 20+) I wanted to have all of them nicely visualized. I dreamt of ortophoto of my house and garden where PIR icons are placed exactly where PIR sensors are physically placed.
I also wanted to be able to easily track the path of the person moving (for many reasons). So I decided to change the icon color (almost like a traffic lights) depending on a time elapsed from the motion detected. So when motion detected (+5 more seconds) the icon is red, then for next 5 secs orange, then orange light and finally yellow. Afterwards is set back to original grey. See also below…
Motion detected + 5s = > > > >
This will allow you to track the move easily when more sensors are on the way.
OK, that is really nice. But not enough for me I would also like to change the icon content (so not only the color) to visualize the direction of the move, if known. I have already an idea but haven’t created a rule for that yet, so this is something to be done later. Generally this shouldn’t be hard as if you have e.g. 2 PIR sensors not far away from each other (typically two on each side of the house) then you can easilly get the direction depending which sensor was triggered first and which one the second. Then you can change the icon (keeping the color set by timeout from the trigger).
For example
So I have created two items for each PIR sensor. One Number item receiving the raw data from ESP via MQTT (0/1 values). The other item is String and it’s value is changed by a rule, which is triggered when the raw item receives update 1 (= motion detected). The value of String item must change according to sub-icon from the group of icons. This is nicely described in Icons openhab guideline.
Just a short recap - icon named motion.svg is main and will be used always when there is no sub-icon name used in string item value. Sub icons are named motion-red.svg where the “-” is separator of the sub-icon name and the main icon name (which is also icons group name). The “red” is then the sub-icon identification. So when the item value is “red” the sub-icon motion-red.svg will be used by openhab. I named my main icon dmotion.svg to have different name from the standard openhab motion icon. Don’t forget NOT to use capital letters and special characters (?) when giving icons names. Finally, you should place your icons to openhabian config folder/icons/classic/ (in my case: o:\openhab2-conf\icons\classic\dmotion.svg). Of course, these dynamic icons work in the sitemap too.
OK, we have dynamic icons ready, now set the items:
Group gPirs // Groups not used in rules yet but I think, I will use them
Group gPirsOutside
Group gPirsInside
Number Pir01_raw "PIR1 [%s]" <dmotion> (gPirs, gPirsOutside) {mqtt="<[mosquitto:Garden/Alarm/Pir01:state:default]"} //receiving 0 (no motion detected) or 1 (motion detected)
Number Pir02_raw "PIR2 [%s]" <dmotion> (gPirs, gPirsOutside) {mqtt="<[mosquitto:Garden/Alarm/Pir02:state:default]"}
String Pir01 "PIR1 [%s]" <dmotion> (gPirs, gPirsOutside) //changed by rule
String Pir02 "PIR2 [%s]" <dmotion> (gPirs, gPirsOutside)
And finally the rule: (EDIT 9.1.2018: This rule was not very effective and even with some errors, see the discussion below. The improved and fully working rule is in discussion below in my post from 9.1.2018. New Items Pir01_Timer and Pir02_Timer also needed to be added as described by Rich)
var Timer TimerPir01 = null
var Timer TimerPir02 = null
// ************************* PIR 01 ***************************
//Update PIR when PIR_raw received update
rule "Pir01 on"
when
Item Pir01_raw received update 1
then
Pir01.postUpdate("red")//by setting the item value to "red" you are also changing the dynamic icon
TimerPir01?.cancel
TimerPir01 = null //cancel any previously running timer
if(TimerPir01 === null || TimerPir01.hasTerminated) {
TimerPir01 = createTimer(now.plusSeconds(5), [|
TimerPir01?.cancel
TimerPir01 = null
Pir01.postUpdate("orange")
if(TimerPir01 === null || TimerPir01.hasTerminated) {
TimerPir01 = createTimer(now.plusSeconds(5), [|
TimerPir01?.cancel
TimerPir01 = null
Pir01.postUpdate("orangelight")
if(TimerPir01 === null || TimerPir01.hasTerminated) {
TimerPir01 = createTimer(now.plusSeconds(5), [|
TimerPir01?.cancel
TimerPir01 = null
Pir01.postUpdate("yellow")
if(TimerPir01 === null || TimerPir01.hasTerminated) {
TimerPir01 = createTimer(now.plusSeconds(5), [|
TimerPir01?.cancel
TimerPir01 = null
Pir01.postUpdate("off")//finally switch the item to any value which is NOT used in dynamic sub-icons name will use the main icon from the group
]) //yellow end
} //yellow end
]) //orangelight end
} //orangelight end
]) //orange end
} //orange end
]) //red end
} //red end
end
// ************************* PIR 02 ***************************
//Update PIR when PIR_raw received update
rule "Pir02 on"
when
Item Pir02_raw received update 1
then
Pir02.postUpdate("red") //by setting the item value to "red" you are also changing the dynamic icon
TimerPir02?.cancel
TimerPir02 = null //cancel any previously running timer
if(TimerPir02 === null || TimerPir02.hasTerminated) {
TimerPir02 = createTimer(now.plusSeconds(5), [|
TimerPir02?.cancel
TimerPir02 = null
Pir02.postUpdate("orange")
if(TimerPir02 === null || TimerPir02.hasTerminated) {
TimerPir02 = createTimer(now.plusSeconds(5), [|
TimerPir02?.cancel
TimerPir02 = null
Pir02.postUpdate("orangelight")
if(TimerPir02 === null || TimerPir02.hasTerminated) {
TimerPir02 = createTimer(now.plusSeconds(5), [|
TimerPir02?.cancel
TimerPir02 = null
Pir02.postUpdate("yellow")
if(TimerPir02 === null || TimerPir02.hasTerminated) {
TimerPir02 = createTimer(now.plusSeconds(5), [|
TimerPir02?.cancel
TimerPir02 = null
Pir02.postUpdate("off") //finally switch the item to any value which is NOT used in dynamic sub-icons name will use the main icon from the group
]) //yellow end
} //yellow end
]) //orangelight end
} //orangelight end
]) //orange end
} //orange end
]) //red end
} //red end
end
Nice, now we have dynamic icons changed by the rule. Now get back to the HABPanel. I created switch for raw item and dummy widget for string item.
In the dummy widget I set the dynamic icon:
This is not bad and look like this:
But I wanted more! I wanted something like a floorplan in HABmin but I read somewhere that it is (probably) not working in HABPanel. Damned!
So I searched for another solution and found this topic about habpanel templates where was exactly what I needed. With a great help of Yannick I got it working!
I needed the picture of my house and garden for the background. So I took it from google satellite maps and crop it to fit my widget nicely. I used 1064x768 pixels, however, you can use whatever fits your needs of course. Picture saved again in the config folder /html where I created a subfolder pic (o:\openhab2-conf\html\pic\white_house.jpg)
So I added one more widget, the template:
with this code inside (updated acc. to recommendations in comments below):
<div style="position: absolute;
top: 0;
bottom: 0;
left: -10px; right: -10px;
background: url('http://**here comes your openhab IP address, e.g. 192.1.1.1**:8080/static/pic/white_house.jpg');
background-size: cover;
background-repeat: no-repeat;">
<div ng-init='model={"name": "PIR01", "item": "Pir01", "hidelabel": false, "hideonoff": false, "iconset": "eclipse-smarthome-classic", "icon": "dmotion" }'>
<widget-dummy
style="position: absolute;
background: rgba(0,0,0,0);
border-radius: 20px;
top: 400px; left: 610px;
width: 60px; height: 80px"
ng-model="model" />
</div>
<div ng-init='model1={"name": "PIR02", "item": "Pir02", "hidelabel": false, "hideonoff": false, "iconset": "eclipse-smarthome-classic", "icon": "dmotion" }'>
<widget-dummy
style="position: absolute;
background: rgba(0,0,0,0);
border-radius: 20px;
top: 400px; left: 830px;
width: 60px; height: 80px"
ng-model="model1" />
</div>
</div>
You have to set the position of the icon/widget in the template by setting top and left values. This may, however, need to be adjusted for devices with other resolutions, I have not tested this yet.
And finally this is how it looks in the HABPanel:
Btw., is there any centralized way to share these (and in the future, maybe also other) icons, similar to share custom widgets in HABPanel?