Battery level check

From Domoticz
Jump to: navigation, search

Purpose

This script is used to check battery level.

This script has been taken from here

Dependencies - hardware / software / operating system

This script will work on Linux systems and needs jq installed. You can install jq using the following instructions:

wget https://github.com/stedolan/jq/releases/download/jq-1.4/jq-1.4.tar.gz
tar -zxvf jq-1.4.tar.gz
rm jq-1.4.tar.gz
cd jq-1.4
./configure
make
sudo make install

Before you can use jq it needs it needs to be compiled. If you never configure or make a installation before. You probably won't have the development tools needed. Follow the instructions to install the development tools and continue with the jq installation.

sudo apt-get update

sudo apt-get install build-essential

Domoticz Setup - switches, variables, version

The single user variable DevicesWithBatteries set in Domoticz with the name of each device seperated by a | i.e. stored as "name one|name 2|name 3|name Forty one" with correct case and spacing.

Installation instructions

Copy this script in your domoticz\scripts\lua\ folder.

Script with comments

--~/domoticz/scripts/lua/script_time_battery.lua
commandArray = {}

-- ==============================
-- Check battery level of devices
-- ==============================
 
--Uservariables
BatteryLevelSetPoint=99
EmailTo="[email protected]"
ReportHour=20
ReportMinute=01
DomoticzIP="192.168.5.70"
DomoticzPort="8080"
Message = 'Batterijchecker'
DeviceFileName = "/var/tmp/JsonAllDevData.tmp"
 
-- Time to run?
time = os.date("*t")
if time.hour == ReportHour and time.min == ReportMinute then
 
    -- Update the list of device names and ids to be checked later
    os.execute("curl 'http://" .. DomoticzIP .. ":" .. DomoticzPort .. "/json.htm?type=devices&order=name' 2>/dev/null| /usr/local/bin/jq -r '.result[]|{(.Name): .idx}' >" .. DeviceFileName)
    BattToReplace = false

    -- Retrieve the battery device names from the user variable - stored as name one|name 2|name 3|name forty one
    DevicesWithBatteries = uservariables["DevicesWithBatteries"]
    DeviceNames = {}
    for DeviceName in string.gmatch(DevicesWithBatteries, "[^|]+") do
       DeviceNames[#DeviceNames + 1] = DeviceName
    end
        
    -- Loop round each of the devices with batteries
    for i,DeviceName in ipairs(DeviceNames) do

       --Determine device id
       local handle = io.popen("/usr/local/bin/jq -r '.\"" .. DeviceName .. "\" | values' " .. DeviceFileName)
       local DeviceIDToCheckBatteryLevel = handle:read("*n")
       handle:close()
 
       --Determine battery level
       local handle = io.popen("curl 'http://" .. DomoticzIP .. ":" .. DomoticzPort .. "/json.htm?type=devices&rid=" .. DeviceIDToCheckBatteryLevel .. "' 2>/dev/null | /usr/local/bin/jq -r .result[].BatteryLevel")
       local BattLevel = string.gsub(handle:read("*a"), "\n", "")
       handle:close()
       print(DeviceName .. ' batterylevel is ' .. BattLevel .. "%")
 
       -- Check batterylevel against setpoint
       if tonumber(BattLevel) < BatteryLevelSetPoint then
          BattToReplace = true
          print("!!!" .. DeviceName .. " batterylevel below " .. BatteryLevelSetPoint .. "%, current " .. BattLevel .. "%")
          Message = Message .. '\n *** ' .. DeviceName .. ' battery level is ' .. BattLevel .. '%'
       end
    end
 
    -- Only send an email if at least one battery fails the test
    if(BattToReplace) then
       commandArray['SendEmail']='Domoticz Battery Levels#'.. Message .. '#' .. EmailTo
    end
end
 
--LUA default
return commandArray


Alternate LUA script

This script will execute once a day at the time that you specify. It will check all your used devices and send an email with a list of all devices below the battery threshold. Optionally you can also receive a weekly summary of all your battery devices and their current battery level regardless of the threshold.

This script will run on Linux or Windows and does not require an external json parsing library. It uses the json library provided with Domoticz. It also doesn't need to write any temporary json files to disk.

Instructions

Under Setup..More Options..Events add a new LUA script named battery_check to execute on 'time' and overwrite the sample code with the below script.

-- =========================================
-- Check battery level for all used devices
-- =========================================

-- User Configuration
BatteryThreshold = 40
WeeklySummary = true
SummaryDay = 1 -- Sunday is 1
EmailTo = "[email protected]"
ReportHour = 9
ReportMinute = 01
Domoticz = "localhost"
DomoticzPort = "8080"
Message = ''

json = (loadfile "/home/pi/domoticz/scripts/lua/JSON.lua")() -- linux
--json = (loadfile "C:\\Domoticz\\scripts\\lua\\json.lua")() -- windows
commandArray = {}
time = os.date("*t")

-- Weekly Device Battery Summary
if WeeklySummary == true and time.wday == SummaryDay and time.hour == ReportHour and time.min == ReportMinute then
 
    -- Get a list of all devices
    handle = io.popen("curl 'http://" .. Domoticz .. ":" .. DomoticzPort .. "/json.htm?type=devices&order=name'")
    devicesJson = handle:read('*all')
    handle:close()
    devices = json:decode(devicesJson)
    BattToReplace = false
    for i,device in ipairs(devices.result) do
        if device.BatteryLevel < 100 and device.Used == 1 then
            Message = Message .. device.Name .. ' battery level is ' .. device.BatteryLevel .. '%<br>'
            print(device.Name .. ' battery level is ' .. device.BatteryLevel .. '%')
        end
    end
    commandArray['SendEmail']='Domoticz Battery Levels#'.. Message .. '#' .. EmailTo

-- Daily Low Battery Report
elseif time.hour == ReportHour and time.min == ReportMinute then
 
    -- Get a list of all devices
    handle = io.popen("curl 'http://" .. Domoticz .. ":" .. DomoticzPort .. "/json.htm?type=devices&order=name'")
    devicesJson = handle:read('*all')
    handle:close()
    devices = json:decode(devicesJson)
    BattToReplace = false
    for i,device in ipairs(devices.result) do
        if device.BatteryLevel < BatteryThreshold and device.Used == 1 then
            Message = Message .. device.Name .. ' battery level is ' .. device.BatteryLevel .. '%<br>'
            print(device.Name .. ' battery level is ' .. device.BatteryLevel .. '%')
        end
    end
    commandArray['SendEmail']='Domoticz Battery Levels#'.. Message .. '#' .. EmailTo
 
end

return commandArray


Alternative script using PHP, Pushover and CRONTAB

For people that have already PHP installed and want to use Pushover for alerts there is an alternative script that can be used using PHP instead of LUA. Create the following batt.php file in /home/pi/domoticz/scripts (fill in your Domoticz IP and port number for xxxx and yyyy)

nano /home/pi/domoticz/scripts/batt.php

contents:

<?php
// Test if Battery level from sensors is still within range.
// If below, send pushover alert
// Called every 4 hours from crontab

$json = json_decode(file_get_contents('http://xxx.xxx.xx.xxx:yyyy/json.htm?type=devices&order=name'));
$threshold = 65;
$hst = "";

foreach  ($json->result as $r) {
        if ($r->BatteryLevel > 0 && $r->BatteryLevel<$threshold) {
                $hst = $hst . $r->Name.": ".$r->BatteryLevel."%\n";
        }
}

if ($hst) {
        $hst = "Batt Low:\n".$hst;
        echo $hst;
        $url = "https://api.pushover.net/1/messages.json";
        $data = array(
            "token" => "[ your pushover application token ]",
            "user" => "[ your pushover user token ]",
            "message" => $hst,
        );
        $options = array(
                'http' => array(
                        'header'  => "Content-type: application/x-www-form-urlencoded\r\n",
                        'method'  => 'POST',
                        'content' => http_build_query($data),
                )
        );

        $context  = stream_context_create($options);
        $result = file_get_contents($url, false, $context);
        var_dump($result);
}

?>

We do not use a varable called DevicesWithBatteries as with the LUA script. We simply loop through all devices and select the devices that have a battery level >0. Devices without a battery typically show a value of 0 or 255.

We then create a crontab file with root priviledges in /etc/cron.d

sudo nano /etc/cron.d/domoticzbatt

contents:

# Battery check run ever 6 hours at a few minutes past the hour
2 0,6,12,18     * * *   root    php /home/pi/domoticz/scripts/batt.php