All,
Here is my collection with a persistence group, zwave lights, sensors and siren,
Custom Scenes:
On Way Home - On way home from work, opens garage,turns on TV, etc
Movie Night - Dims lights to 20%, Turns on 70" LivingRoom TV, sets HDMI input to Kodi.
Kodi is booted from a PXE Server for whole house Kodi and profiles on multiple TV’s and devices.
Bed Time - Turns everything off.
In Use:
OpenHab 1.8.2 - Rock Solid
Zwave binding 1.9 - Flawless!
Extra bindings: exec, persist, http, orvibo, REST API
Aeon Labs, Door/window, Siren, LED Lights. Zstick2 latest FW
My Total Control HoneyWell WIFI Thermostat status and Management scripts.
Aquos 70" Sharp TV binding
WakeOnLan to turn on hosts (kodi)
Password-less SSH to shutdown hosts (kodi)
Banana PI 3 for garage control and status back to OH.
Banana PI 3 for Kodi
OwnTracks for presence detection with mqt.
New Hardware: Gigabyte GB-BXBT-2807 https://www.google.ca/search?q=Gigabyte+GB-BXBT-2807&biw=1600&bih=799&source=lnms&tbm=isch&sa=X&ved=0ahUKEwjwz-CqzI7MAhUIPT4KHTrJCEEQ_AUIBygC
This is a little bad ass micro PC with sound, Wifi, Bluetooth, 64bit, you can easily install any OS from a thumb drive like you do on a PC. I threw a 250GB SSD and 8GB of ram in mine. This all sits inside a secure Honeywell alarm panel with battery backup. This allows for a total self sufficient alarm system if someone cuts the power or communications the alarm system portion will still run perfectly with no point of failure!
New New Hardware
New controller I’m using. Dell Netbook 10. 8+ hour battery, added a 250gb SSD so there is no moving parts.
cool little thing…Installed debian 7 on it. Paid 40 bucks for it on
craigslist.
1 Aeon Labs Door/Window Sensors (PRO: Has a protruding tamper sensor CON: Uses AA batteries)
3 EcoLink Door Window Sensors (PRO: Lithium battery, Multiple color housings come with it, very nice CON: Tamper is only internal to case not if you pull it off the wall)
2 Z-Wave Smoke/Carbon detectors (PRO: Cheap, Zwave, First Alert, Look nice, Carbon and Smoke, CON: AA Batteries)
2 EcoLink PIR (PRO: Lithium battery, Great range, work extremely well! I’ve tried sneaking up to it from every angle to disable it and it just don’t work lol CON: NONE)
6 Go-Control Dimmable LED’s (PRO: Work very well CON: NONE)
1 Zipato RGBW (PRO: Works very well overall CON: No RGBW in zwave binding 1.9)
1 Aeon Labs Gen2 Siren (PRO: LOUD, BRIGHT, Self charging battery operated, Multi-Tone CON: NONE)
1 Aeon Labs Gen5 Siren (PRO: LOUD, BRIGHT, Self charging battery operated, Multi-tone CON: NONE)
1 Aeon Labs Z-Stick2 (PRO: Cheap, Works great. No issues, works great in SUC mode and mesh redundancy. CON: None.
Groups and Rules for:
Alarm: Disarm, Arm Away and Arm Stay
FYI: I am changing code on a daily basis so if something don’t work correctly for you lmk so i can check against running code.
/etc/default/openhab
# Execution account and group. The user account should be member of group
# "openhab" if it's different than "root" and "openhab".
# Note that some bindings may require "root" access to the system.
# Default value if isn't specified - "root:root".
#USER_AND_GROUP=root:root # changed the openhab user and group in /etc/passwd to 0:0 for root permissions.
# Web server's listening ports (plain and SSL). Note that if execution account
# is different than "root" the port numbers should be greater than 1024.
# Default value if isn't specified - none, must be specified.
HTTP_PORT=80
HTTPS_PORT=443
# Console's listening port, same restriction as this for web server's ports.
# Default value if isn't specified - none, must be specified.
TELNET_PORT=5555
# Extra arguments passed to Java
JAVA_ARGS=
# Extra arguments passed to openHAB
OPENHAB_ARGS=
# Use non-default Java VM.
# Default value if isn't specified - system default Java VM.
#OPENHAB_JAVA=/usr/bin/java
# To enable debugging set to "yes" (case insensitive).
# Default value if isn't specified - debugging is disabled.
DEBUG=yes
Rules:
import org.openhab.core.library.types.*
import org.openhab.core.persistence.*
import org.openhab.model.script.actions.*
import org.openhab.core.library.types.*
import org.joda.time.DateTime
import org.openhab.core.items.*
import org.eclipse.xtext.xbase.lib.*
import org.openhab.model.script.actions.Timer
var Timer Node2_tAlive = null
var Timer Node3_tAlive = null
var Timer Node4_tAlive = null
var Timer Node5_tAlive = null
var Timer Node6_tAlive = null
var Timer Node7_tAlive = null
var Timer Node8_tAlive = null
var Timer Node9_tAlive = null
var Timer Node10_tAlive = null
var Timer Node11_tAlive = null
var Timer Node12_tAlive = null
var Timer Node13_tAlive = null
var Timer Node14_tAlive = null
var Timer Node15_tAlive = null
var Timer Node16_tAlive = null
var Timer Node17_tAlive = null
var Timer Node18_tAlive = null
var Timer timer = null
val Functions$Function2 alert = [GroupItem g, String type |
val latest = g.members.sortBy[lastUpdate].last
val name = latest.name.split("_")
Notification_Proxy.postUpdate(name.get(1) + " " + name.get(2) + " " + name.get(3) + " " + type + " Alert!. " + latest.state.toString)
]
rule "Dispatch Notification"
when
Item Notification_Proxy received update
then
logWarn("Notification", Notification_Proxy.state.toString)
sendMail("alerts@cidcomm.com", "Security System Alert!", Notification_Proxy.state.toString)
end
rule "Process door intrusion updates"
Item gDoorSensors changed from CLOSED to OPEN
then
val aState = AlarmSysStatus.state as DecimalType
if(aState == 2 || aState == 3) {
alert.apply(gDoorSensors, "- Intrusion")
}
end
rule "DoorBell"
Item gDoorSensors changed from CLOSED to OPEN
then
executeCommandLine("mplayer /usr/share/openhab/sounds/doorbell.mp3")
end
rule "Process motion intrusion updates"
Item gMotionSensors changed from CLOSED to OPEN
then
if((AlarmSysStatus.state as DecimalType) == 2) {
alert.apply(gMotionSensors, "- Intrusion")
}
end
rule "Process smoke detector updates"
Item gSmoke changed from CLOSED to OPEN
then
alert.apply(gSmoke, "- CO/Smoke")
}
end
rule "Process Tamper updates"
Item gTamper changed from CLOSED to OPEN
then
alert.apply(gTamper, "- Tamper")
}
end
rule "Process Window updates"
Item gWindows changed from CLOSED to OPEN
then
val aState = AlarmSysStatus.state as DecimalType
if(aState == 2 || aState == 3) {
alert.apply(gWindows, "- Intrusion")
}
end
rule "Process Battery Level Updates"
when
Item gBattery received update
then
gBattery.members.forEach[ battery |
if((battery.state as DecimalType) < 20) {
val name = battery.name.split("_")
switch(name.get(1)){
case "Kitchen": Notification_Proxy.postUpdate("Replace the " + name.get(1) + " " + name.get(2) + " " + name.get(3) + " " + "Battery, " + battery.state.toString + "% left!")
case "LivingRoom": Notification_Proxy.postUpdate("Replace the " + name.get(1) + " " + name.get(2) + " " + name.get(3) + " " + "Battery, " + battery.state.toString + "% left!")
case "BedRoom": Notification_Proxy.postUpdate("Replace the " + name.get(1) + " " + name.get(2) + " " + name.get(3) + " " + "Battery, " + battery.state.toString + "% left!")
case "Hall": Notification_Proxy.postUpdate("Replace the " + name.get(1) + " " + name.get(2) + " " + name.get(3) + " " + "Battery, " + battery.state.toString + "% left!")
}
}
]
end
// Send selected temperature to MyTotalConnectComfort Portal
rule "IndHeatSet"
when
Item IndHeatSet received command
then
if(timer == null) {
timer =createTimer(now.plusSeconds(20), [|
logInfo("Security", "TIMER: Heat Timer triggered")
SendTemp.sendCommand(IndHeatSet.state as DecimalType)
timer = null
])
logInfo("Security", "TIMER: Heat Timer Set")
} else {
timer.reschedule(now.plusSeconds(20))
logInfo("Security","TIMER: Rescheduling Heat Timer")
}
end
// Set Heat Setpoint
rule "Send SetPoint to MyTotalConnectComfort Portal"
when
Item SendTemp received command
then
executeCommandLine("/etc/therm.py -h " + receivedCommand)
logInfo("Security", "RULE: Sending update to MyTotalConnectComfort Portal!")
end
// Sync Setpoint with the set temp app
rule "Update Temp App"
when
Item IndHeat received command
then
postUpdate(IndHeatSet, receivedCommand)
logInfo("Security", "CRON: Syncing SetPoint data!")
end
// Run MyTotalControl Script
rule "Update values from MyTotalControl Thermostat"
when
Time cron "0 0/5 * * * ?" // Every 5 minutes
then
executeCommandLine("/etc/tstat")
logInfo("Security", "CRON: Querying MyTotalConnectComfort Portal for data!")
end
// Check if we are on AC or Battery and send email if on battery
rule "CheckHostPower"
when
Time cron "0 0/2 * * * ?" // Every 5 minutes
then
executeCommandLine("/etc/checkac")
logInfo("Security", "CRON: Querying AC Power status!")
end
// Check if livingroom tv is on
rule "CheckLivingRoomTV"
when
Time cron "0 0/2 * * * ?" // Every 5 minutes
then
executeCommandLine("/etc/checktv")
logInfo("Security", "CRON: Querying LivingRoom TV status!")
end
// Check if kodi is on in the livingroom
rule "CheckLivingRoomKodi"
when
Time cron "0 0/2 * * * ?" // Every 5 minutes
then
executeCommandLine("/etc/checkkodi")
logInfo("Security", "CRON: Querying LivingRoom Kodi status!")
end
// Check if battery is below 25% and send email if so
rule "CheckBatteryPercentage"
when
Time cron "0 0/2 * * * ?" // Every 5 minutes
then
executeCommandLine("/etc/checkbattery")
logInfo("Security", "CRON: Querying Battery Percentage!")
end
// Turn evening lights on
rule "Turn on tv Light"
when
//Time cron "0 0 19 * * ?" // 7pm every day
Item Sunset_Time_Task received update ON
then
Lower_LivingRoom_TV_Light.sendCommand(50)
Lower_LivingRoom_DoorWay_Light.sendCommand(50)
Lower_Kitchen_Patio_Light.sendCommand(ON)
logInfo("Security", "SCHEDULE: Turning on evening lights!")
end
// Turn evening lights off
rule "Turn off tv Light"
when
Time cron "0 30 23 * * ?" // 19:00:00, every day, every month, every weekday, don't care about year
then
gAllLights.sendCommand(OFF)
logInfo("Security", "SCHEDULE: Turning off evening lights!")
end
// SCENE: On way home
rule "OnWayHome"
when
Item OnWayHomeScene received command
then
if (receivedCommand == 1) {
SharpTVPower.sendCommand(ON)
relay1.sendCommand(ON)
Thread::sleep(8000)
SharpTVInput.sendCommand(0)
logInfo("Security", "SCENE: OnWayHome Activated!")
end
// SCENE: All off
rule "AllOff"
when
Item AllOffScene received command
then
if (receivedCommand == 1) {
SharpTVPower.sendCommand(OFF)
gAllLights.sendCommand(OFF)
LRKodiPC.sendCommand(0)
logInfo("Security", "SCENE: AllOff Activated!")
end
// SCENE: All Lights off
rule "rAllLightsOff"
when
Item sAllLightsOff received command
then
if (receivedCommand == 1) {
gAllLights.sendCommand(OFF)
logInfo("Security", "SCENE: All Lights Off Activated!")
end
// SCENE: All Lights on
rule "rAllLightsOn"
when
Item sAllLightsOn received command
then
if (receivedCommand == 1) {
gAllLights.sendCommand(ON)
logInfo("Security", "SCENE: All Lights On Activated!")
end
// SCENE: Movie Time
rule "MovieTime"
when
Item MovieTimeScene received command
then
if (receivedCommand == 1) {
SharpTVPower.sendCommand(ON)
Lower_LivingRoom_TV_Light.sendCommand(20)
Lower_LivingRoom_DoorWay_Light.sendCommand(20)
LRKodiPC.sendCommand(1)
Thread::sleep(8000)
SharpTVInput.sendCommand(4)
end
// Alarm Arm and Disarm
rule "rArmState"
when
Item AlarmArmDisarm received command
then
{
if (receivedCommand == 3)
{
logInfo("Security", "SECURITY: Armed Stay!")
postUpdate(AlarmSysStatus, 3)
sendMail("jay@cidcomm.com", "Security System Alert!", "System Armed Stay!")
executeCommandLine("aplay /usr/share/openhab/sounds/armedstay.wav")
}
if (receivedCommand == 2)
{
logInfo("Security", "SECURITY: Armed Away!")
postUpdate(AlarmSysStatus, 2)
sendMail("jay@cidcomm.com", "Security System Alert!", "System Armed Away!")
executeCommandLine("aplay /usr/share/openhab/sounds/armedaway.wav")
}
if (receivedCommand == 1)
{
logInfo("Security", "SECURITY: Disarmed")
postUpdate(AlarmSysStatus, 1)
gAllSirensSwitch.sendCommand(OFF)
sendMail("jay@cidcomm.com", "Security System Alert!", "System Disarmed!")
executeCommandLine("aplay /usr/share/openhab/sounds/disarmed.wav")
if (receivedCommand == 0)
{
logInfo("Security", "SECURITY: No Update")
}
}}}
end
// Alarm System Active Action
rule "rAlarmActivated"
when
Item gMotionSensors changed from CLOSED to OPEN or
Item gDoorSensors changed from CLOSED to OPEN
then
{
if (AlarmSysStatus.state == 2 && gMotionSensors.state == OPEN)
{
logInfo("Security", "SECURITY: ARMED-AWAY Motion Intrusion Detected!")
gAllLights.sendCommand(ON)
Thread::sleep(3000)
gAllSirensSet.sendCommand(259)
Thread::sleep(1200000)
gAllSirensSwitch.sendCommand(OFF)
}
if (AlarmSysStatus.state == 2 && gDoorSensors.state == OPEN)
{
logInfo("Security", "SECURITY: ARMED-AWAY Door Intrusion Detected!")
gAllLights.sendCommand(ON)
Thread::sleep(3000)
gAllSirensSet.sendCommand(259)
Thread::sleep(1200000)
gAllSirensSwitch.sendCommand(OFF)
}
if (AlarmSysStatus.state == 3 && gDoorSensors.state == OPEN)
{
logInfo("Security", "SECURITY: ARMED-STAY Door Intrusion Detected!")
gAllLights.sendCommand(ON)
Thread::sleep(3000)
gAllSirensSet.sendCommand(259)
Thread::sleep(1200000)
gAllSirensSwitch.sendCommand(OFF)
}
}}}}
end
// Garage Door Timer Lights
rule "rGarageDoorLights"
when
Item relay1 received command
then
if (receivedCommand == ON) {
gGarageLights.sendCommand(ON)
logInfo("Security", "Garage Lights On!")
Thread::sleep(300000)
gGarageLights.sendCommand(OFF)
logInfo("Security", "EXT-TIMER: Garage Lights Off!")
end
// Garage Interior Door Timer Lights
rule "rGarageInteriorDoorLights"
when
Item Lower_Kitchen_MainDoor_Sensor changed from CLOSED to OPEN
then
gGarageLights.sendCommand(ON)
logInfo("Security", "Garage Lights On!")
Thread::sleep(300000)
gGarageLights.sendCommand(OFF)
logInfo("Security", "INT-TIMER: Garage Lights Off!")
end
// Node Health checks
rule "Node2Status"
when
Item Node2 changed
then
logInfo("Status", "NODE CHECK: Checking Node2 Status.")
Node2_tAlive?.cancel()
Node2_tAlive = createTimer(now.plusHours(8)) [|
logWarn("N2", "Node2 appears to be dead")
sendMail("jay@cidcomm.com", "Security System Alert!", "Node2 Appears dead. Please Investigate.")
]
end
rule "Node3Status"
when
Item Node3 changed
then
logInfo("Status", "NODE CHECK: Checking Node3 Status.")
Node3_tAlive?.cancel()
Node3_tAlive = createTimer(now.plusHours(8)) [|
logWarn("N3", "Node3 appears to be dead")
sendMail("jay@cidcomm.com", "Security System Alert!", "Node3 Appears dead. Please Investigate.")
]
end
rule "Node4Status"
when
Item Node4 changed
then
logInfo("Status", "NODE CHECK: Checking Node4 Status.")
Node4_tAlive?.cancel()
Node4_tAlive = createTimer(now.plusHours(8)) [|
logWarn("N4", "Node4 appears to be dead")
sendMail("jay@cidcomm.com", "Security System Alert!", "Node4 Appears dead. Please Investigate.")
]
end
rule "Node5Status"
when
Item Node5 changed
then
logInfo("Status", "NODE CHECK: Checking Node5 Status.")
Node5_tAlive?.cancel()
Node5_tAlive = createTimer(now.plusHours(8)) [|
logWarn("N5", "Node5 appears to be dead")
sendMail("jay@cidcomm.com", "Security System Alert!", "Node5 Appears dead. Please Investigate.")
]
end
rule "Node6Status"
when
Item Node6 changed
then
logInfo("Status", "NODE CHECK: Checking Node6 Status.")
Node6_tAlive?.cancel()
Node6_tAlive = createTimer(now.plusHours(8)) [|
logWarn("N6", "Node6 appears to be dead")
sendMail("jay@cidcomm.com", "Security System Alert!", "Node6 Appears dead. Please Investigate.")
]
end
rule "Node7Status"
when
Item Node7 changed
then
logInfo("Status", "NODE CHECK: Checking Node7 Status.")
Node7_tAlive?.cancel()
Node7_tAlive = createTimer(now.plusHours(8)) [|
logWarn("N7", "Node7 appears to be dead")
sendMail("jay@cidcomm.com", "Security System Alert!", "Node7 Appears dead. Please Investigate.")
]
end
rule "Node8Status"
when
Item Node8 changed
then
logInfo("Status", "NODE CHECK: Checking Node8 Status.")
Node8_tAlive?.cancel()
Node8_tAlive = createTimer(now.plusHours(8)) [|
logWarn("N8", "Node8 appears to be dead")
sendMail("jay@cidcomm.com", "Security System Alert!", "Node8 Appears dead. Please Investigate.")
]
end
rule "Node9Status"
when
Item Node9 changed
then
logInfo("Status", "NODE CHECK: Checking Node9 Status.")
Node9_tAlive?.cancel()
Node9_tAlive = createTimer(now.plusHours(8)) [|
logWarn("N9", "Node9 appears to be dead")
sendMail("jay@cidcomm.com", "Security System Alert!", "Node9 Appears dead. Please Investigate.")
]
end
rule "Node10Status"
when
Item Node10 changed
then
logInfo("Status", "NODE CHECK: Checking Node10 Status.")
Node10_tAlive?.cancel()
Node10_tAlive = createTimer(now.plusHours(8)) [|
logWarn("N10", "Node10 appears to be dead")
sendMail("jay@cidcomm.com", "Security System Alert!", "Node10 Appears dead. Please Investigate.")
]
end
rule "Node11Status"
when
Item Node11 changed
then
logInfo("Status", "NODE CHECK: Checking Node11 Status.")
Node11_tAlive?.cancel()
Node11_tAlive = createTimer(now.plusHours(8)) [|
logWarn("N11", "Node11 appears to be dead")
sendMail("jay@cidcomm.com", "Security System Alert!", "Node11 Appears dead. Please Investigate.")
]
end
rule "Node12Status"
when
Item Node12 changed
then
logInfo("Status", "NODE CHECK: Checking Node12 Status.")
Node12_tAlive?.cancel()
Node12_tAlive = createTimer(now.plusHours(8)) [|
logWarn("N12", "Node12 appears to be dead")
sendMail("jay@cidcomm.com", "Security System Alert!", "Node12 Appears dead. Please Investigate.")
]
end
rule "Node13Status"
when
Item Node13 changed
then
logInfo("Status", "NODE CHECK: Checking Node13 Status.")
Node13_tAlive?.cancel()
Node13_tAlive = createTimer(now.plusHours(8)) [|
logWarn("N13", "Node13 appears to be dead")
sendMail("jay@cidcomm.com", "Security System Alert!", "Node13 Appears dead. Please Investigate.")
]
end
rule "Node14Status"
when
Item Node14 changed
then
logInfo("Status", "NODE CHECK: Checking Node14 Status.")
Node14_tAlive?.cancel()
Node14_tAlive = createTimer(now.plusHours(8)) [|
logWarn("N14", "Node14 appears to be dead")
sendMail("jay@cidcomm.com", "Security System Alert!", "Node14 Appears dead. Please Investigate.")
]
end
rule "Node15Status"
when
Item Node15 changed
then
logInfo("Status", "NODE CHECK: Checking Node15 Status.")
Node15_tAlive?.cancel()
Node15_tAlive = createTimer(now.plusHours(8)) [|
logWarn("N15", "Node15 appears to be dead")
sendMail("jay@cidcomm.com", "Security System Alert!", "Node15 Appears dead. Please Investigate.")
]
end
rule "Node16Status"
when
Item Node16 changed
then
logInfo("Status", "NODE CHECK: Checking Node16 Status.")
Node16_tAlive?.cancel()
Node16_tAlive = createTimer(now.plusHours(8)) [|
logWarn("N16", "Node16 appears to be dead")
sendMail("jay@cidcomm.com", "Security System Alert!", "Node16 Appears dead. Please Investigate.")
]
end
rule "Node17Status"
when
Item Node17 changed
then
logInfo("Status", "NODE CHECK: Checking Node17 Status.")
Node17_tAlive?.cancel()
Node17_tAlive = createTimer(now.plusHours(8)) [|
logWarn("N17", "Node17 appears to be dead")
sendMail("jay@cidcomm.com", "Security System Alert!", "Node17 Appears dead. Please Investigate.")
]
end
rule "Node18Status"
when
Item Node18 changed
then
logInfo("Status", "NODE CHECK: Checking Node18 Status.")
Node18_tAlive?.cancel()
Node18_tAlive = createTimer(now.plusHours(8)) [|
logWarn("N18", "Node18 appears to be dead")
sendMail("jay@cidcomm.com", "Security System Alert!", "Node18 Appears dead. Please Investigate.")
]
end
rrd4j.persist:
Strategies {
everyMinute : "0 * * * * ?"
everyHour : "0 0 * * * ?"
everyDay : "0 0 0 * * ?"
// if no strategy is specified for an item entry below, the default list will be used
default = everyMinute
}
Items {
// Persist ALL items in the persist GROUP
persist* : strategy = everyMinute, everyChange, restoreOnStartup
}
Proximity Detection Demo:
Kind of a hodge podge but slowly cleaning it up as I add more…