-
-
Notifications
You must be signed in to change notification settings - Fork 1.7k
MiOS Binding Example
MiOS Binding and MiOS Action Examples
This document is intended to provide MiOS Binding users with real-world example openHAB configurations.
Users typically have configurations falling into one or more of the following categories, which will be used to outline any subsequent examples:
- Augmenting - openHAB Rules that "add" to existing MiOS Scenes.
- Co-existing - Replacing MiOS Scenes with openHAB Rules, but keeping the Devices.
- Replacing - wholesale replacement of MiOS functionality (Devices|Scenes) with openHAB equivalent functionality.
MiOS has a standardized definition that most Alarm Panel plugins adhere to (DSC, Ademco, GE Caddx, Paradox, etc). This exposes a standardized UPnP-style attribute, AlarmPartition2/Alarm
, for the Alarm System being in active Alarm mode. It has the value None
or Alarm
.
Here we check the specific transition between those two states as we want to avoid being re-notified, when the Uninitialized
» Alarm
state transition occurs, should openHAB restart.
Item declaration (house.items
):
String AlarmArea1Alarm "Alarm Area 1 Alarm [%s]" (GAlarmArea1) {mios="unit:house,device:228/service/AlarmPartition2/Alarm"}
String AlarmArea1ArmMode "Alarm Area 1 Arm Mode [%s]" (GAlarmArea1) {mios="unit:house,device:228/service/AlarmPartition2/ArmMode"}
String AlarmArea1LastUser "Alarm Area 1 Last User [%s]" (GAlarmArea1) {mios="unit:house,device:228/service/AlarmPartition2/LastUser"}
Rule declaration (house-alarm.rules
):
rule "Alarm Panel Breach"
when
Item AlarmArea1Alarm changed to Active
then
pushNotification("House-Alarm", "House in ALARM!! Notification")
say("Alert: House in Alarm Notification")
end
rule "Alarm Panel Armed (Any)"
when
Item AlarmArea1ArmMode changed from Disarmed to Armed
then
say("Warning! House Armed Notification")
// Perform deferred notifications, as the User.state may not have been processed yet.
createTimer(now.plusSeconds(1)) [
logDebug("house-alarm", "Alarm-Panel-Armed-Any Deferred notification")
var user = AlarmArea1LastUser.state as StringType
if (user == null) user = "user unknown"
pushNotification("House-Armed", "House Armed Notification (" + user + ")")
]
end
rule "Alarm Panel Disarmed (Fully)"
when
Item AlarmArea1ArmMode changed from Armed to Disarmed
then
say("Warning! House Disarmed Notification")
// Perform deferred notifications, as the User.state may not have been processed yet.
createTimer(now.plusSeconds(1)) [
logDebug("house-alarm", "Alarm-Panel-Disarmed-Fully Deferred notification")
var user = AlarmArea1LastUser.state as StringType
if (user == null) user = "user unknown"
pushNotification("House-Disarmed", "House Disarmed Notification (" + user + ")")
]
end
MiOS Systems standardize Battery Level indications (0-100%) for all battery-power devices (Alarm sensors, Z-Wave Door Locks, etc) and Nest uses a simple "ok" String to represent the Battery Status.
Item declaration (house.items
):
Number GarageDeadboltBatteryLevel "Garage Deadbolt Battery Level [%d %%]" <energy> (GBattery,GPersist) {mios="unit:house,device:189/service/HaDevice1/BatteryLevel"}
Number HallCupboardZoneBatteryLevel "Hall Cupboard Battery Level [%d %%]" <energy> (GBattery,GPersist) {mios="unit:house,device:301/service/HaDevice1/BatteryLevel"}
Number EXTFrontMotionZoneBatteryLevel "EXT Front Motion Zone Battery Level [%d %%]" <energy> (GBattery,GPersist) {mios="unit:house,device:302/service/HaDevice1/BatteryLevel"}
Number EXTRearMotionZoneBatteryLevel "EXT Rear Motion Battery Level [%d %%]" <energy> (GBattery,GPersist) {mios="unit:house,device:396/service/HaDevice1/BatteryLevel"}
String NestSmokeGuestBedroom_battery_health "Guest Bedroom Smoke Battery Health [%s]" <energy> (GSmoke,GBattery,GPersist) {nest="<[smoke_co_alarms(Guest Bedroom).battery_health]"}
Rule declaration (house-battery.rules
):
import org.openhab.core.library.types.*
val Number LOW_BATTERY_THRESHOLD = 60 // for Z-Wave Battery devices
val String OK_BATTERY_STATE = 'ok' // for Nest Thermostat and Protect devices
rule "Low Battery Alert"
when
Time cron "0 0 8,12,20 * * ?"
then
GBattery?.members.filter(s|s.state instanceof DecimalType).forEach[item |
var Number level = item.state as Number
var String name = item.name
if (level < LOW_BATTERY_THRESHOLD) {
logInfo('Low-Battery-Alert', 'Bad: ' + name)
pushNotification("Low-Battery-Alert", "House Low Battery Notification (" + name + ")")
} else {
logDebug('Low-Battery-Alert', 'Good: ' + name)
}
]
GBattery?.members.filter(s|s.state instanceof StringType).forEach[item |
var String level = (item.state as StringType).toString
var String name = item.name
if (level != OK_BATTERY_STATE) {
logInfo('Low-Battery-Alert', 'Bad: ' + name)
pushNotification("Low-Battery-Alert", "House Low Battery Notification (" + name + ")")
} else {
logDebug('Low-Battery-Alert', 'Good: ' + name)
}
]
end
This is typical of a declarative Scene in MiOS. In this case, the lights are left on for 5 minutes, and if new motion is detected in that time, another 5 minute clock is started.
The logging can be removed as needed.
Item declaration (house.items
):
Group GSwitch All
Switch MasterClosetLightsStatus "Master Closet Lights" (GSwitch) {mios="unit:house,device:391/service/SwitchPower1/Status"}
Switch MasterClosetFibaroLightStatus "Master Closet Fibaro Light" (GSwitch) {mios="unit:house,device:431/service/SwitchPower1/Status"}
Rule declaration (house-master.rules
):
import org.openhab.model.script.actions.Timer
import org.joda.time.*
import java.util.concurrent.locks.ReentrantLock
val int MCL_DELAY_SECONDS = 300
var Timer mclTimer = null
var ReentrantLock mclLock = new ReentrantLock(false)
rule "Master Closet Motion"
when
Item MasterClosetZoneTripped changed from CLOSED to OPEN
then
logInfo("house-master", "Master-Closet-Motion Timer lights ON")
sendCommand(MasterClosetLightsStatus, ON)
sendCommand(MasterClosetFibaroLightStatus, ON)
mclLock.lock
if (mclTimer != null) {
mclTimer.cancel
logInfo("house-master", "Master-Closet-Motion Timer Cancel")
}
mclTimer = createTimer(now.plusSeconds(MCL_DELAY_SECONDS)) [
logInfo("house-master", "Master-Closet-Motion Timer lights OFF")
sendCommand(MasterClosetLightsStatus, OFF)
sendCommand(MasterClosetFibaroLightStatus, OFF)
]
mclLock.unlock
end
A variant of the above, this Rule has parts that only run at Nighttime. Here we use the Astro Binding to compute daylight hours. See the Astro Binding configuration for details on how to setup that Binding's configuration/openhab.cfg
entry.
Item declaration (sunrise.items
):
DateTime ClockDaylightStart "Daylight Start [%1$tH:%1$tM]" <calendar> {astro="planet=sun, type=daylight, property=start, offset=-30"}
DateTime ClockDaylightEnd "Daylight End [%1$tH:%1$tM]" <calendar> {astro="planet=sun, type=daylight, property=end, offset=+30"}
Item declaration (house.items
):
Switch KitchenSinkLightStatus "Kitchen Sink Light" (GSwitch) {mios="unit:house,device:99/service/SwitchPower1/Status"}
Switch KitchenPantryLightStatus "Kitchen Pantry Light" (GSwitch) {mios="unit:house,device:425/service/SwitchPower1/Status"}
Switch PowerHotWaterPumpStatus "Power Hot Water Pump" (GSwitch) {mios="unit:house,device:303/service/SwitchPower1/Status"}
Switch KitchenPantryZoneArmed "Zone Armed [%s]" {mios="unit:house,device:426/service/SecuritySensor1/Armed"}
Rule declaration (house-kitchen.rules
):
import org.openhab.core.library.types.*
import org.openhab.model.script.actions.Timer
import org.joda.time.*
import java.util.concurrent.locks.ReentrantLock
val int K_DELAY_SECONDS = 240
var Timer kTimer = null
var ReentrantLock kLock = new ReentrantLock(false)
rule "Kitchen Motion"
when
Item KitchenMotionZoneTripped changed from CLOSED to OPEN
then
logInfo("house-kitchen", "Kitchen-Motion Timer ON")
// Ignore this Rule if the Motion sensor is bypassed.
if (KitchenMotionZoneArmed.state != ON) {
logInfo("house-kitchen", "Kitchen-Motion Not Armed, skipping")
return void
}
val DateTime daylightStart = new DateTime((ClockDaylightStart.state as DateTimeType).getCalendar)
val DateTime daylightEnd = new DateTime((ClockDaylightEnd.state as DateTimeType).getCalendar)
var boolean night = daylightStart.isAfterNow || daylightEnd.isBeforeNow
if (night) {
logInfo("house-kitchen", "Kitchen-Motion Night Time")
sendCommand(KitchenSinkLightStatus, ON)
sendCommand(KitchenPantryLightStatus, ON)
}
logInfo("house-kitchen", "Kitchen-Motion Any Time")
sendCommand(PowerHotWaterPumpStatus, ON)
kLock.lock
if (kTimer != null) {
kTimer.cancel
logInfo("house-kitchen", "Kitchen-Motion Timer Cancel")
}
kTimer = createTimer(now.plusSeconds(K_DELAY_SECONDS)) [
logInfo("house-kitchen", "Kitchen-Motion Timer OFF")
sendCommand(KitchenSinkLightStatus, OFF)
sendCommand(KitchenPantryLightStatus, OFF)
sendCommand(PowerHotWaterPumpStatus, OFF)
]
kLock.unlock
end
This originally ran as a Scene on the MiOS Unit, but was replaced with an openHAB Rule. The Items are a mix of Items, from an Alarm system running on MiOS, and the Nest Binding, running locally.
Explicitly check for the OPEN
» CLOSED
state transition, to avoid issues when openHAB restarts (Uninitialized
» OPEN
) or when duplicate values come in from the MiOS System (OPEN
» OPEN
).
Item declaration (house.items
):
Group GPersist (All)
Group GWindow "All Windows [%d]" <contact> (GContact)
Contact LivingRoomZoneTripped "Living Room (Zone 2) [MAP(en.map):%s]" <contact> (GWindow,GPersist) {mios="unit:house,device:117/service/SecuritySensor1/Tripped"}
Contact KitchenZoneTripped "Kitchen (Zone 3) [MAP(en.map):%s]" <contact> (GWindow,GPersist) {mios="unit:house,device:118/service/SecuritySensor1/Tripped"}
Contact FamilyRoomZoneTripped "Family Room (Zone 5) [MAP(en.map):%s]" <contact> (GWindow,GPersist) {mios="unit:house,device:120/service/SecuritySensor1/Tripped"}
Contact MasterBedroomZoneTripped "Master Bedroom (Zone 8) [MAP(en.map):%s]" <contact> (GWindow,GPersist) {mios="unit:house,device:122/service/SecuritySensor1/Tripped"}
Contact Bedroom3ZoneTripped "Bedroom #3 (Zone 9) [MAP(en.map):%s]" <contact> (GWindow,GPersist) {mios="unit:house,device:123/service/SecuritySensor1/Tripped"}
Contact Bedroom2ZoneTripped "Bedroom #2 (Zone 10) [MAP(en.map):%s]" <contact> (GWindow,GPersist) {mios="unit:house,device:124/service/SecuritySensor1/Tripped"}
Contact GuestBathZoneTripped "Guest Bathroom (Zone 11) [MAP(en.map):%s]" <contact> (GWindow,GPersist) {mios="unit:house,device:125/service/SecuritySensor1/Tripped"}
Contact StairsWindowsZoneTripped "Stairs Windows (Zone 12) [MAP(en.map):%s]" <contact> (GWindow,GPersist) {mios="unit:house,device:126/service/SecuritySensor1/Tripped"}
Contact MasterBath1ZoneTripped "Master Bath (Zone 19) [MAP(en.map):%s]" <contact> (GWindow,GPersist) {mios="unit:house,device:133/service/SecuritySensor1/Tripped"}
Contact MasterBath2ZoneTripped "Master Bath (Zone 20) [MAP(en.map):%s]" <contact> (GWindow,GPersist) {mios="unit:house,device:134/service/SecuritySensor1/Tripped"}
Contact MasterBath3ZoneTripped "Master Bath (Zone 21) [MAP(en.map):%s]" <contact> (GWindow,GPersist) {mios="unit:house,device:135/service/SecuritySensor1/Tripped"}
Rule declaration (house.rules):
rule "Windows Closed (all)
when
Item Bedroom2ZoneTripped changed from OPEN to CLOSED or
Item Bedroom3ZoneTripped changed from OPEN to CLOSED or
Item FamilyRoomZoneTripped changed from OPEN to CLOSED or
Item GuestBathZoneTripped changed from OPEN to CLOSED or
Item KitchenZoneTripped changed from OPEN to CLOSED or
Item LivingRoomZoneTripped changed from OPEN to CLOSED or
Item MasterBath1ZoneTripped changed from OPEN to CLOSED or
Item MasterBath2ZoneTripped changed from OPEN to CLOSED or
Item MasterBath3ZoneTripped changed from OPEN to CLOSED or
Item MasterBedroomZoneTripped changed from OPEN to CLOSED or
Item StairsWindowsZoneTripped changed from OPEN to CLOSED
then
if (GWindow.members.filter(s|s.state==OPEN).size == 0) {
say("Attention: All Windows closed.")
sendCommand(Nest_away, "home")
}
end
rule "Windows Opened (any)"
when
Item Bedroom2ZoneTripped changed from CLOSED to OPEN or
Item Bedroom3ZoneTripped changed from CLOSED to OPEN or
Item FamilyRoomZoneTripped changed from CLOSED to OPEN or
Item GuestBathZoneTripped changed from CLOSED to OPEN or
Item KitchenZoneTripped changed from CLOSED to OPEN or
Item LivingRoomZoneTripped changed from CLOSED to OPEN or
Item MasterBath1ZoneTripped changed from CLOSED to OPEN or
Item MasterBath2ZoneTripped changed from CLOSED to OPEN or
Item MasterBath3ZoneTripped changed from CLOSED to OPEN or
Item MasterBedroomZoneTripped changed from CLOSED to OPEN or
Item StairsWindowsZoneTripped changed from CLOSED to OPEN
then
if (GWindow.members.filter(s|s.state==OPEN).size == 1) {
say("Attention: First Window opened.")
sendCommand(Nest_away, "away")
}
end
I wrote this script to publish data from MiOS to SmartEnergyGroups (SEG) for analysis.
Here's what you do to replace it with openHAB functionality:
Item declaration (house.items
):
Group GPersist (All)
Group GMonitor (All)
Group GMonitorTemperature (GMonitor)
Group GMonitorHumidity (GMonitor)
Group GMonitorPower (GMonitor)
Group GMonitorEnergy (GMonitor)
Number WeatherTemperatureCurrentTemperature "Outside [%.1f °F]" <temperature> (GPersist,GMonitorTemperature) {mios="unit:house,device:318/service/TemperatureSensor1/CurrentTemperature"}
Number WeatherLowTemperatureCurrentTemperature "Outside Low [%.1f °F]" <temperature> (GPersist,GMonitorTemperature) {mios="unit:house,device:319/service/TemperatureSensor1/CurrentTemperature"}
Number WeatherHighTemperatureCurrentTemperature "Outside High [%.1f °F]" <temperature> (GPersist,GMonitorTemperature) {mios="unit:house,device:320/service/TemperatureSensor1/CurrentTemperature"}
Number WeatherHumidityCurrentLevel "Outside Humidity [%d %%]" (GPersist,GMonitorHumidity) {mios="unit:house,device:321/service/HumiditySensor1/CurrentLevel"}
Number NestTStatUpstairs_humidity "Humidity [%d %%]" (GPersist,GMonitorHumidity) {nest="<[thermostats(Upstairs).humidity]"}
Number NestTStatUpstairs_ambient_temperature_f "Upstairs [%.1f °F]" <temperature> (GPersist,GMonitorTemperature) {nest="<[thermostats(Upstairs).ambient_temperature_f]"}
Number NestTStatDownstairs_humidity "Humidity [%d %%]" (GPersist,GMonitorHumidity) {nest="<[thermostats(Downstairs).humidity]"}
Number NestTStatDownstairs_ambient_temperature_f "Downstairs [%.1f °F]" <temperature> (GPersist,GMonitorTemperature) {nest="<[thermostats(Downstairs).ambient_temperature_f]"}
Persistence declaration (rrd4j.persist
):
Strategies {
// for rrd charts, we need a cron strategy
everyMinute : "0 * * * * ?"
everyDay : "0 0 23 * * ?"
}
Items {
SystemDataVersion, SystemUserDataDataVersion, SystemTimeStamp, SystemLocalTime, SystemLoadTime : strategy = everyDay
GPersist* : strategy = everyChange, everyMinute, restoreOnStartup
GTemperature* : strategy = everyMinute, restoreOnStartup
}
Rule declaration (seg.rules
):
import org.openhab.core.library.types.*
import java.util.Locale
rule "Log Data to SmartEnergyGroups (SEG)"
when
Time cron "0 0/2 * * * ?" or
Item NestTStatUpstairs_ambient_temperature_f changed or
Item NestTStatDownstairs_ambient_temperature_f changed or
Item WeatherTemperatureCurrentTemperature changed or
Item WeatherLowTemperatureCurrentTemperature changed or
Item WeatherHighTemperatureCurrentTemperature changed or
Item NestTStatUpstairs_humidity changed or
Item NestTStatDownstairs_humidity changed or
Item WeatherHumidityCurrentLevel changed
then
val String SEG_SITE = "<yourSiteKeyHere>"
val String SEG_URL = "http://api.smartenergygroups.com/api_sites/stream"
val String NODE_NAME = "openHAB"
val Locale LOCALE = Locale::getDefault
var String segData = ""
GMonitorTemperature?.members.forEach(item|
segData = segData + String::format(LOCALE, "(t_%s %s)", item.name, (item.state as Number).toString)
)
GMonitorHumidity?.members.forEach(item |
segData = segData + String::format(LOCALE, "(h_%s %s)", item.name, (item.state as Number).toString)
)
GMonitorPower?.members.forEach(item |
segData = segData + String::format(LOCALE, "(p_%s %s)", item.name, (item.state as Number).toString)
)
GMonitorEnergy?.members.forEach(item |
segData = segData + String::format(LOCALE, "(e_%s %s)", item.name, (item.state as Number).toString)
)
segData = String::format("(site %s (node %s ? %s))", SEG_SITE, NODE_NAME, segData)
sendHttpPostRequest(SEG_URL, "application/x-www-form-urlencoded", segData)
end
ℹ Please find all documentation for openHAB 2 under http://docs.openhab.org.
The wiki pages here contain (outdated) documentation for the older openHAB 1.x version. Please be aware that a lot of core details changed with openHAB 2.0 and this wiki as well as all tutorials found for openHAB 1.x might be misleading. Check http://docs.openhab.org for more details and consult the community forum for all remaining questions.
- Classic UI
- iOS Client
- Android Client
- Windows Phone Client
- GreenT UI
- CometVisu
- Kodi
- Chrome Extension
- Alfred Workflow
- Cosm Persistence
- db4o Persistence
- Amazon DynamoDB Persistence
- Exec Persistence
- Google Calendar Presence Simulator
- InfluxDB Persistence
- JDBC Persistence
- JPA Persistence
- Logging Persistence
- mapdb Persistence
- MongoDB Persistence
- MQTT Persistence
- my.openHAB Persistence
- MySQL Persistence
- rrd4j Persistence
- Sen.Se Persistence
- SiteWhere Persistence
- AKM868 Binding
- AlarmDecoder Binding
- Anel Binding
- Arduino SmartHome Souliss Binding
- Asterisk Binding
- Astro Binding
- Autelis Pool Control Binding
- BenQ Projector Binding
- Bluetooth Binding
- Bticino Binding
- CalDAV Binding
- Chamberlain MyQ Binding
- Comfo Air Binding
- Config Admin Binding
- CUL Transport
- CUL Intertechno Binding
- CUPS Binding
- DAIKIN Binding
- Davis Binding
- DD-WRT Binding
- Denon Binding
- digitalSTROM Binding
- DIY on XBee Binding
- DMX512 Binding
- DSC Alarm Binding
- DSMR Binding
- eBUS Binding
- Ecobee Binding
- EDS OWSever Binding
- eKey Binding
- Energenie Binding
- EnOcean Binding
- Enphase Energy Binding
- Epson Projector Binding
- Exec Binding
- Expire Binding
- Fatek PLC Binding
- Freebox Binding
- Freeswitch Binding
- Frontier Silicon Radio Binding
- Fritz AHA Binding
- Fritz!Box Binding
- FritzBox-TR064-Binding
- FS20 Binding
- Garadget Binding
- Global Caché IR Binding
- GPIO Binding
- HAI/Leviton OmniLink Binding
- HDAnywhere Binding
- Heatmiser Binding
- Homematic / Homegear Binding
- Horizon Mediabox Binding
- HTTP Binding
- IEC 62056-21 Binding
- IHC / ELKO Binding
- ImperiHome Binding
- Insteon Hub Binding
- Insteon PLM Binding
- IPX800 Binding
- IRtrans Binding
- jointSPACE-Binding
- KM200 Binding
- KNX Binding
- Koubachi Binding
- LCN Binding
- LightwaveRF Binding
- Leviton/HAI Omnilink Binding
- Lg TV Binding
- Logitech Harmony Hub
- MailControl Binding
- MAX!Cube-Binding
- MAX! CUL Binding
- MCP23017 I/O Expander Binding
- MCP3424 ADC Binding
- MiLight Binding
- MiOS Binding
- Mochad X10 Binding
- Modbus Binding
- MPD Binding
- MQTT Binding
- MQTTitude binding
- MystromEcoPower Binding
- Neohub Binding
- Nest Binding
- Netatmo Binding
- Network Health Binding
- Network UPS Tools Binding
- Nibe Heatpump Binding
- Nikobus Binding
- Novelan/Luxtronic Heatpump Binding
- NTP Binding
- One-Wire Binding
- Onkyo AV Receiver Binding
- Open Energy Monitor Binding
- OpenPaths presence detection binding
- OpenSprinkler Binding
- OSGi Configuration Admin Binding
- Panasonic TV Binding
- panStamp Binding
- Philips Hue Binding
- Picnet Binding
- Piface Binding
- PiXtend Binding
- pilight Binding
- Pioneer-AVR-Binding
- Plex Binding
- Plugwise Binding
- PLCBus Binding
- PowerDog Local API Binding
- Powermax alarm Binding
- Primare Binding
- Pulseaudio Binding
- Raspberry Pi RC Switch Binding
- RFXCOM Binding
- RWE Smarthome Binding
- Sager WeatherCaster Binding
- Samsung AC Binding
- Samsung TV Binding
- Serial Binding
- Sallegra Binding
- Satel Alarm Binding
- Siemens Logo! Binding
- SimpleBinary Binding
- Sinthesi Sapp Binding
- Smarthomatic Binding
- Snmp Binding
- Somfy URTSI II Binding
- Sonance Binding
- Sonos Binding
- Souliss Binding
- Squeezebox Binding
- Stiebel Eltron Heatpump
- Swegon ventilation Binding
- System Info Binding
- TA CMI Binding
- TCP/UDP Binding
- Tellstick Binding
- TinkerForge Binding
- Tivo Binding
- UCProjects.eu Relay Board Binding
- UPB Binding
- VDR Binding
- Velleman-K8055-Binding
- Wago Binding
- Wake-on-LAN Binding
- Waterkotte EcoTouch Heatpump Binding
- Weather Binding
- Wemo Binding
- Withings Binding
- XBMC Binding
- xPL Binding
- Yamahareceiver Binding
- Zibase Binding
- Z-Wave Binding
- Asterisk
- DoorBird
- FIND
- Foscam IP Cameras
- LG Hombot
- Worx Landroid
- Heatmiser PRT Thermostat
- Google Calendar
- Linux Media Players
- Osram Lightify
- Rainforest EAGLE Energy Access Gateway
- Roku Integration
- ROS Robot Operating System
- Slack
- Telldus Tellstick
- Zoneminder
- Wink Hub (rooted)
- Wink Monitoring
- openHAB Cloud Connector
- Google Calendar Scheduler
- Transformations
- XSLT
- JSON
- REST-API
- Security
- Service Discovery
- Voice Control
- BritishGasHive-Using-Ruby
- Dropbox Bundle
A good source of inspiration and tips from users gathered over the years. Be aware that things may have changed since they were written and some examples might not work correctly.
Please update the wiki if you do come across any out of date information.
- Rollershutter Bindings
- Squeezebox
- WAC Binding
- WebSolarLog
- Alarm Clock
- Convert Fahrenheit to Celsius
- The mother of all lighting rules
- Reusable Rules via Functions
- Combining different Items
- Items, Rules and more Examples of a SmartHome
- Google Map
- Controlling openHAB with Android
- Usecase examples
- B-Control Manager
- Spell checking for foreign languages
- Flic via Tasker
- Chromecast via castnow
- Speedtest.net integration