From 352bc23e7f24f85745c35e1a7ba526fdd3864f3c Mon Sep 17 00:00:00 2001 From: Martin Sebald Date: Wed, 15 Nov 2017 09:37:56 +0100 Subject: [PATCH] added apcups --- README.md | 3 ++ apcups/README.md | 22 ++++++++++++ apcups/USV_dump_log | 3 ++ apcups/ups.items | 10 ++++++ apcups/ups.map | 7 ++++ apcups/ups.rules | 81 +++++++++++++++++++++++++++++++++++++++++++++ 6 files changed, 126 insertions(+) create mode 100644 apcups/README.md create mode 100644 apcups/USV_dump_log create mode 100644 apcups/ups.items create mode 100644 apcups/ups.map create mode 100644 apcups/ups.rules diff --git a/README.md b/README.md index 232171e..30462e3 100644 --- a/README.md +++ b/README.md @@ -5,6 +5,9 @@ If you find problems or errors, please [let me know](https://www.sebald.com/kont The stuff I provide is based on [openHABian](http://docs.openhab.org/installation/openhabian.html) on a Raspberry Pi 3 using openHAB 2.1 and sometimes might reflect on my own (sometimes special) hardware and environment in and around my house. +## apcups +Receiving and using information from APC UPS devices + ## heating Some heating rules, based on a time schedule, presence and TV status. diff --git a/apcups/README.md b/apcups/README.md new file mode 100644 index 0000000..525a2b5 --- /dev/null +++ b/apcups/README.md @@ -0,0 +1,22 @@ +# APC UPS devices +Receiving and using information like online status (on AC power or running on battery), battery charging level, autonomy time and more from APC UPS devices. + +All you need is a APC UPS device which is connected to a [apcupsd](http://www.apcupsd.org) daemon. The daemon can run locally on the openHAB machine and or somewhere else. If it runs remote you need to install apcupsd as we access the remote apcupsd installation using the apcaccess command. + +First you need to put the USV_dump_log bash script somewhere where you can access it. I created a directory */home/openhabian/scripts* for scripts like this one. + +Then create a thing in Paper UI. Use the Exec binding and enter the following parameters: + +* **Name:** USV_dump_log +* **Command:** /home/openhabian/scripts/USV_dump_log 3551 +* **Transform:** REGEX((.*)) +* **Interval:** 60 + +The port for accessing the UPS device through apcupsd is a parameter as I check three UPS devices and only want to use one script. This is also the reason why I configured the remote UPS devices (all my UPS devices just have a USB cable, no network interfaces) in the local apcupsd. The data is received from the remote apcupsd installations. + +The new thing *USV_dump_log* gets an id like *exec:command:**a1b2c3d4*** which you then need to enter in the item created through the *ups.items* file. + +* **ups.items**: Put this file into your */etc/openhab2/items* directory and modify it for your specific setup. Maybe everything suits your needs, but you need to modify the string item *USV_Log* and match the command id in the channel command to the thing you created earlier in Paper UI. +* **ups.map**: Put this file into your */etc/openhab2/transform* directory. +* **ups.rules**: Put this file into your */etc/openhab2/rules* directory. You may want to modify it for your specific setup. +* **ups.map**: Put the bash script into */home/openhabian/scripts* (or somewhere else you like) and *chmod 755* it to make it executable. \ No newline at end of file diff --git a/apcups/USV_dump_log b/apcups/USV_dump_log new file mode 100644 index 0000000..12502d2 --- /dev/null +++ b/apcups/USV_dump_log @@ -0,0 +1,3 @@ +#!/bin/bash +export UPS_LOG="$(/sbin/apcaccess status 172.27.0.31:$1)" +echo $UPS_LOG diff --git a/apcups/ups.items b/apcups/ups.items new file mode 100644 index 0000000..d164c4b --- /dev/null +++ b/apcups/ups.items @@ -0,0 +1,10 @@ +String USV_Log "kompletter Inhalt des Logs [%s]" { channel="exec:command:a1b2c3d4:output" } +String USV_Status "USV Status [MAP(ups.map):%s]" +Number USV_Load "USV Load [%.1f %%]" +Number USV_BattCharge "USV Battery Charge [%.1f %%]" +Number USV_TimeLeft "USV Time Left [%.1f Minuten]" +Number USV_BattVoltage "USV Battery Volts [%.1f V]" +Number USV_LineV "USV Input Volts [%.1f V]" +Number USV_OutputV "USV Output Volts [%.1f V]" +Number USV_ITemp "USV Temperatur [%.1f °C]" +String USV_BattDate "USV Battery Date [%s]" diff --git a/apcups/ups.map b/apcups/ups.map new file mode 100644 index 0000000..3badbce --- /dev/null +++ b/apcups/ups.map @@ -0,0 +1,7 @@ +ONLINE=Online +OL=Online +OL\ CHRG=Online +ONBATT=Offline +OB\ DISCHRG=Offline +NULL=unbekannt +-=unbekannt diff --git a/apcups/ups.rules b/apcups/ups.rules new file mode 100644 index 0000000..5d571c2 --- /dev/null +++ b/apcups/ups.rules @@ -0,0 +1,81 @@ +import java.util.regex.Pattern +import java.util.regex.Matcher + +val org.eclipse.xtext.xbase.lib.Functions$Function4 UPS_GetNumValue = [ + StringItem logITem, + NumberItem upsITem, + String sExpr, + String logline | + var String ups_log + ups_log = logITem.state.toString + var Pattern ups_pattern + ups_pattern = Pattern::compile(sExpr) + var Matcher ups_matcher + ups_matcher = ups_pattern.matcher(ups_log) + ups_matcher.find() + var String ups_result + ups_result = ups_matcher.group(1) + upsITem.postUpdate(ups_result) +] + +val org.eclipse.xtext.xbase.lib.Functions$Function4 UPS_GetStrValue = [ + StringItem logITem, + StringItem upsITem, + String sExpr, + String logline | + var String ups_log + ups_log = logITem.state.toString + var Pattern ups_pattern + ups_pattern = Pattern::compile(sExpr) + var Matcher ups_matcher + ups_matcher = ups_pattern.matcher(ups_log) + ups_matcher.find() + var String ups_result + ups_result = ups_matcher.group(1) + upsITem.postUpdate(ups_result) +] + +rule "USV Handling" +when + Item USV_Log received update +then + UPS_GetStrValue.apply(USV_Log,USV_Status,"(?<=STATUS : )(.*?)(?= )","LogLine") + UPS_GetNumValue.apply(USV_Log,USV_LineV,"LINEV \\: ([-+]?[0-9]*\\.?[0-9]) Volts","LogLine") + UPS_GetNumValue.apply(USV_Log,USV_OutputV,"OUTPUTV \\: ([-+]?[0-9]*\\.?[0-9]) Volts","LogLine") + UPS_GetNumValue.apply(USV_Log,USV_Load,"LOADPCT \\: ([-+]?[0-9]*\\.?[0-9]) Percent","LogLine") + UPS_GetNumValue.apply(USV_Log,USV_BattCharge,"BCHARGE \\: ([-+]?[0-9]*\\.?[0-9]) Percent","LogLine") + UPS_GetNumValue.apply(USV_Log,USV_TimeLeft,"TIMELEFT \\: ([-+]?[0-9]*\\.?[0-9]) Minutes","LogLine") + UPS_GetNumValue.apply(USV_Log,USV_ITemp,"ITEMP \\: ([-+]?[0-9]*\\.?[0-9]) C","LogLine") + UPS_GetNumValue.apply(USV_Log,USV_BattVoltage," BATTV \\: ([-+]?[0-9]*\\.?[0-9]) Volts","LogLine") + UPS_GetStrValue.apply(USV_Log,USV_BattDate,"(?<=BATTDATE : )(.*?)(?= )","LogLine") +end + +rule "USV off battery" + when + Item USV_Status changed to "ONLINE" + then + if(SystemStarting.state == OFF) { + sendXMPP("user@jabberdomain.tld", new DateTimeType() + ": USV: Stromversorgung wiederhergestellt") + sendTelegram("telegrambot", new DateTimeType() + ": USV: Stromversorgung wiederhergestellt") + } +end + +rule "USV on battery" + when + Item USV_Status changed to ONBATT + then + if(SystemStarting.state == OFF) { + sendXMPP("user@jabberdomain.tld", new DateTimeType() + ": USV: Stromausfall!!!") + sendTelegram("telegrambot", new DateTimeType() + ": USV: Stromausfall!!!") + } +end + +rule "USV Comm lost" + when + Item USV_Status changed to COMMLOST + then + if(SystemStarting.state == OFF) { + sendXMPP("user@jabberdomain.tld", new DateTimeType() + ": USV: Kommunikationsverbindung verloren") + sendTelegram("telegrambot", new DateTimeType() + ": USV: Kommunikationsverbindung verloren") + } +end