Hallo zusammen,
dies ist ein kleines Update dass in der Ausgabe jetzt auch die Geräte enthält die noch nie ausgelöst haben - zum Beispiel Rauchmelder oder Wassersensoren.
Zusätzlich habe ich das PDF aktualisiert.
Changelog für Version 1.2.1
– Ausgabe der Geräte die noch nie ausgelöst (breached) haben
– PDF aktualisiert
--[[
%% autostart
%% properties
%% globals
--]]
--[[
file : Battery&devicestatus.lua
version : 1.2.1, released on 30.03.2018
purpose : This script checks the batteries and sends reports via
email. Since version 0.6.1 and higher: The script also performs a check on
non battery devices and reports all devices marked as dead by HC2.
The batterie status is checked daily and several reports per week can be
emailed.
Due to some limitations in the HC2 with FW less then 4.130, only 980
characters per per e-mail could be sent.
For batteries that are almost empty, or a dead device is recognized,
a push and/or telegram messages will be sent immediately.
Also the status of lastBreached can be checked, so you can easely identify
devices whose battery may have been empty for a longer time.
If you have added new devices or sections, you should restart the script.
A manual check is possible at any time. Simply press the Start button.
Copyleft Mar-2017 - 2018 {jeep} siio-forum
--]]
local sourceTrigger = fibaro:getSourceTrigger();
local version = "1.2.1"
local oldnodeId = nil ;
-- The variables below can be changed by user.
local subject = "Battery and device status";
local userIDs = {2} -- mailuser ids
local devpEmail = 25 -- devices per email
local maildays = {1,3,6} -- 1=Sunday, 2=Monday, 3=Tuesday ...7=Saturday
local pushactiv = true; -- true - sendpush notification
local teleactiv = false; -- true - send message via telegram
local phoneID = {303} -- phone IDs for push notification
local checktime = "19:15" -- At this time the script is triggerd
local full = 100 --between 50 and 100 the battery status is assumed to be good
local warning = 50 --between 30 and 50 battery is running low
local critical = 30 --below 30 battery status is asumed as critical
local empty = 255 --probably a completely empty battery
local nBreacheds= 24 --not Breached since nn hours
local checklBreached = true; -- should lastBreached be checked
local checkSection = true; -- if false, the section is not output.
local debugout = false --false
local htmlout = false --false
--
local Debug = function ( color, message )
fibaro:debug(string.format('<%s style="font-family:Courier New;font-size:12px;color:%s;">%s', "span", color, message, "span"))
end
local function contains(days, val)
for i=1,#days do
if days[i] == val then
return true
end
end
return false
end
local function sendPush(text)
if (phoneID[1] ~= nil) then
for i=1, #phoneID do
if phoneID[i] ~= nil then
fibaro:call(phoneID[i],'sendPush', text)
end
end
end
end
local function sendMail(userIDs,subject,status,m)
local subject = subject..'-'..m
if (userIDs[1] ~= nil) then
for m=1, #userIDs do
if userIDs[m] ~= nil then
fibaro:call(userIDs[m], "sendEmail", subject, status)
end
end
status = ' ';
print('Mail Nr. '..m.. ' sent.')
end
end
local function checklastBreached(uxtimeStamp, lbreached)
local xseconds = (uxtimeStamp - lbreached)
local xtime = (xseconds /60) / 60
local xhours = math.floor(xtime)
return xhours
end
local function formatString(name, room)
local slength = string.len(name) + string.len(room)
local dlength = 30 - slength
local dots = string.rep ("-", dlength)
return dots
end
local function getSectionNamebyID(values, sectionNr, sectiontab)
if checkSection then
for i=1, values do
section = sectiontab[i].id
if section == sectionNr then
return string.sub(sectiontab[i].name,1,2)..','
end
end
end
return ''
end
local tdev = {}
local sym ={warn='?', ok='✔️', empty='❓', crit='⛔️', err='❌' }
local sectiontab = api.get("/sections")
local values = #sectiontab
local devices = fibaro:getDevicesId({visible = true, enabled = true, isPlugin =false })
local function checkBatteries()
local uxtimeStamp = os.time(dt);
local status = '';
local vstatus = '';
local bstatus = '';
local stathtml= '';
local n = 0; -- battery device counter
local v = 0; -- non battery device counter
local m = 0; -- mail counter
local x = 0; -- other devices
Debug('withe', os.date('%c')..', Version: '.. version );
Debug('skyblue', 'Daten werden aufbereitet...')
for id = 1, #devices do
local batteryLevel = fibaro:get(devices[id], 'batteryLevel')
local nodeId = fibaro:get(devices[id], 'nodeId')
local isdead = fibaro:get(devices[id], 'dead')
if batteryLevel ~= nil and nodeId ~= nil and batteryLevel ~= '' then
local name = fibaro:getName(devices[id])
if oldnodeId ~= nodeId then
local room = fibaro:getRoomNameByDeviceID(devices[id])
local sectionID = fibaro:getSectionID(devices[id])
local lbreached = fibaro:get(devices[id], 'lastBreached')
local sname = getSectionNamebyID(values, sectionID, sectiontab)
if not(room == "unassigned") then
n = string.format('%02d',n+1)
if tonumber(batteryLevel) >= warning and tonumber(batteryLevel) <= full then
local dots = formatString(name, room)
local tableOK = string.format("%s %s, im Raum %s hat %s %s %% %s", sname, name, room, dots, batteryLevel, sym.ok)
local statusOK = n..') ' ..tableOK
local htmlOK = "<pre>" .. statusOK .. "</pre>"
if debugout then Debug('green', statusOK) end
stathtml = stathtml .. htmlOK
status = status .. statusOK ..'\n'
table.insert(tdev, tableOK )
elseif
tonumber(batteryLevel) >= critical and tonumber(batteryLevel) <= warning then
local dots = formatString(name, room)
local tablewarn = string.format("%s %s, im Raum %s hat %s %s %% %s", sname, name, room, dots, batteryLevel, sym.warn)
local statuswarn = n..') '..tablewarn
local htmlWarn = "<pre>" .. statuswarn .. "</pre>"
if debugout then Debug('yellow', statuswarn) end
stathtml = stathtml .. htmlWarn
status = status .. statuswarn ..'\n'
table.insert(tdev, tablewarn )
elseif
tonumber(batteryLevel) < critical then
local dots = formatString(name, room)
local tablecrit = string.format("%s %s, im Raum %s hat %s %s %% %s", sname, name, room, dots, batteryLevel, sym.crit)
local statuscrit= n..') '.. tablecrit
local htmlcrit = "<pre>".. statuscrit .. "</pre>"
if debugout then Debug('red', statuscrit) end
stathtml = stathtml .. htmlcrit
if pushactiv then
sendPush(statuscrit)
end
status = status .. statuscrit ..'\n'
table.insert(tdev, tablecrit )
elseif
tonumber(batteryLevel) > full or tonumber(batteryLevel) == empty then
local dots = formatString(name, room)
local tableempty = string.format("%s %s, im Raum %s hat %s %s %% %s", sname, name, room, dots, batteryLevel, sym.empty)
local statusempty = n..') ' .. tableempty
local htmlempty = "<pre>"..statusempty .. "</pre>"
stathtml = stathtml .. htmlempty
if debugout then Debug('red', statusempty) end
if pushactiv then
sendPush(statusempty)
end
status = status .. statusempty..'\n';
table.insert(tdev, tableempty )
end
if tonumber(isdead) == 1 then
local dots = formatString(name, room)
local tabledead = string.format("%s %s, im Raum %s ist tot. %s %s", sname, name, room, dots, sym.err)
local statusdead = n..') '.. tabledead
local htmldead = "<pre>"..statusdead .. "</pre>"
if debugout then Debug('red', statusdead) end
status = status .. statusdead .. '\n';
stathtml = stathtml .. htmldead
vstatus = vstatus .. statusdead .. '\n';
sendPush(statusdead)
table.insert(tdev, tabledead )
if teleactiv then --Telegram sender
fibaro:setGlobal('telegram_text', name.. ' is dead! '.. os.date('%c'))
fibaro:startScene(61)
end
end
if lbreached ~= nil and checklBreached and tonumber(lbreached) > 0 then
local xhours = checklastBreached(uxtimeStamp, lbreached)
if xhours > nBreacheds then
local sname = getSectionNamebyID(values, sectionID, sectiontab)
bstatus = bstatus ..sname ..' '.. name ..' ('..room..') not breached since: ' ..xhours.. ' hours.\n'
end
end
if lbreached ~= nil and checklBreached and tonumber(lbreached) == 0 then
bstatus = bstatus ..sname ..' '.. name ..' ('..room..') was never breached.\n'
end
if (n % devpEmail == 0) and oldNodeId == nodeID then
if contains(maildays, weekday) then
m = m+1
sendMail(userIDs,subject,status,m)
status = ' '
fibaro:sleep(500)
end
end
end
end
oldnodeId = nodeId
else
local dtype = fibaro:getType(devices[id])
if (dtype == 'virtual_device') or (dtype == 'HC_user') or (dtype == 'iOS_device') then
x = x+1
else
v = v+1
local name = fibaro:getName(devices[id])
local room = fibaro:getRoomNameByDeviceID(devices[id])
if tonumber(isdead) == 1 then
local dots = formatString(name, room)
local sectionID = fibaro:getSectionID(devices[id])
local sname = getSectionNamebyID(values, sectionID, sectiontab)
local statusdead = string.format("%s %s, im Raum %s ist tot! ----%s %s", sname, name, room, dots, sym.err)
local htmldead = "<pre>"..string.format("%s %s, im Raum %s ist tot! ----%s %s", sname, name, room, dots, sym.err).."</pre>"
Debug('red', statusdead)
vstatus = vstatus .. statusdead .. '\n';
stathtml = stathtml .. htmldead
sendPush(statusdead)
end
end
end
fibaro:sleep(100)
end --for
print('')
table.sort(tdev)
Debug('skyblue', '--- Sortierte Ausgabe nach Bereichen ---')
for i,j in ipairs(tdev) do
Debug('skyblue',j)
end
if ( not checklBreached) then bstatus = "The 'last breached status' was not checked. \n" end
if (vstatus == '') then vstatus = "No dead device found.\n" end
status = status .. 'Checked at: ' .. os.date('%c') ..'\n'
status = status ..n.. ' battery devices were checked.\n'
vstatus = vstatus .. 'All non battery devices checked.'
separator = '------------------------------------------------------------'
Debug('withe', os.date('%c'));
Debug('withe', separator)
if htmlout then Debug('lightgreen', stathtml) end
Debug('cyan', '------------ Summary of dead devices. -------------')
Debug('withe', vstatus)
Debug('withe', separator)
Debug('cyan', '--- Summary of devices not breached for a period of time. ---')
Debug('withe', bstatus)
Debug('withe', "There are " .. x .." other devices, such as plugins, virtual devices, etc.")
status = status..separator..'\n'..vstatus..'\n'
status = status..separator..'\n'..bstatus..'\n'..os.date('%c')
if contains(maildays, weekday) then
m = m+1
sendMail(userIDs,subject,status,m)
status = ' ';
end
end -- function
function main()
local currentDate = os.date("*t");
local currenthour = string.format("%02d", currentDate.hour) .. ":" .. string.format("%02d", currentDate.min)
weekday = currentDate.wday
local startSource = fibaro:getSourceTrigger();
if currenthour == checktime then
checkBatteries()
end
setTimeout(main, 60*1000)
end
if (sourceTrigger["type"] == "autostart") then
main()
else
local currentDate = os.date("*t");
local startSource = fibaro:getSourceTrigger();
weekday = currentDate.wday
if (startSource["type"] == "other") then
checkBatteries()
end
end