So, damit wir es auch in der richtigen Kategorie haben und ich so wieso weitergebastelt habe.
Ich warte aber mit weiteren Änderungen bis Fibaro das Mailproblem gelöst hat.
Ich habe nie direkt im Script nachgeschaut sondern hab mich auf die Mails verlassen.
Was ich noch plane: da ich schon seit längerem den ER4 aus dem Fibaro Forum nutze (den kann ich wirklich jedem empfehlen) steuere ich viele Sachen für die ich vorher ein Script hatte, nur noch über eine Regel im ER4, könnte ich mir vorstellen das Batterie Script nicht mehr über das Gateway starten sondern über eine ER4 Regel. Oder zur Auswahl. Mal sehen.
-- Trigger auf Gateway-start ändern
--[[
file : Battery&devicestatus.lua
version : 0.1.4 - DE, released on Feb. 2021
Copyright: Mar-2017 - 2021 {jwi}
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.
This is very important to identify your dead devices.
A manual check is possible at any time. Simply press the Start button.
For more information, please read the attached PDF.
--]]
--local sourceTrigger = fibaro.getSourceTrigger();
local version = "0.1.0 - DE"
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,2,3,4,5,6,7} -- 1=Sunday, 2=Monday, 3=Tuesday ...7=Saturday
local pushactiv = true; -- true - sendpush notification
local teleactiv = false; -- true - send message via telegram
local phoneID = {2,} -- phone IDs for push notification
local checktime = "19:25" -- At this time the script is triggerd
local dtformat = '%d %b. %Y - %X' --Datumsformat
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 onlySummaryM = false; -- send only a summary email if true
local debugout = true -- | true | false
local htmlout = true -- | true | false
local sortout = true -- | true | false
--
local function printf(...) fibaro.debug(tag, string.format(...)) end
--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
--function printf(fmt, ...)
-- print(string.format(fmt, ...))
--end
local function sendPush(text)
if (phoneID[1] ~= nil) then
for i=1, #phoneID do
if phoneID[i] ~= nil then
fibaro.alert("push", {phoneID[i]}, text) --phoneID[i]
-- fibaro.call(phoneID[i],'sendPush', text)
end
end
end
end
local function sendMail(userIDs,subject,mstat,m)
local subject = subject..'-'..m
if (userIDs[1] ~= nil) then
for u=1, #userIDs do
if userIDs[u] ~= nil then
-- fibaro.call(userIDs[u], "sendEmail", subject, mstat)
fibaro.alert("email",{2},mstat)
-- fibaro.alert("email",{48},mstat)
end
end
mstat = ' ';
if debugout then print('<font color="green">'..'Mail Nr. '..m.. ' sent.') end
end
end
local function checklastBreached(uxtimeStamp, lbreached)
local xseconds = (uxtimeStamp - lbreached)
local xtime = (xseconds /60) / 60
return math.floor(xtime)
end
local function formatString(dname, room)
local slength = string.len(dname) + string.len(room)
local dlength = 30 - slength
return string.rep ("-", dlength)
end
local function getSNamebyID(sectionID)
if checkSection then
if sectionID == nil or sectionID == "unassigned" then return ' ' end
if tonumber(sectionID) > 0 then
local section = api.get("/sections/" .. tostring(sectionID))
return string.sub(tostring(section.name),1, 2)..','
end
end
return ''
end
local function validate(phoneID)
local ios = api.get('/iosDevices')
local nID = 0
for n = 1,#phoneID do
for _,i in pairs(ios) do
if phoneID[n] == i.id then
nID = nID+1
end
end --for
end --for
if #phoneID ~= nID then fibaro.warning('phoneID','Hinweis - unbekannte phoneID entdeckt, bitte korrigieren!\n<font color=yellow>Oder Sie können keine Push-Meldungen empfangen.') end
end
local function createlink(id)
local devID = id
local linkID = string.format(
"<a href=\"../devices/configuration.html?id=%u#bookmark-advanced\" target=\"_blank\""..
"style=\"display:inline;color:Cyan\">%u</a>",id,id )
return devID, linkID
end
local function checkhc2()
local info = api.get("/settings/info")
FW = info.softVersion
local date = info.serverStatus
local daysfrom = (os.time() - date) / (24 * 60 * 60)
local wholedays = math.floor(daysfrom)
return os.date('%d-%m-%Y %H:%M:%S', date)..', ('..wholedays..') Tage'
end
local fc_o = "<font color=orange>"
local fc_r = "<font color=red>"
local fc_c = "<font color=cyan>"
local fc_g = "<font color=green>"
local sym ={warn='🔔', ok='✔️', empty='❓', crit='⛔️', err='❌' }
local sectiontab = api.get("/sections")
local values = #sectiontab
--
local function checkallDevices()
-- print('Start checckalldevices')
local devices_all = api.get('/devices/?enabled=true&visible=true&isPlugin=false');
--print(devices_all)
local uxtimeStamp = os.time(dt);
local mstat = '';
local vstatus = '';
local bstatus = '';
local bstatm = '';
local vstatm = '---------------~= Zusammenfassung der Überprüfung. =~----------------\r\n';
local stathtml= "<pre><span style='border: 1px solid grey'>"..'Nr |id |Sec| Geräte Name | Raum Name ------------ ----- |Wert% |Sym ' .. "</span></pre>";
local tdev = {};
local n = 0; -- battery device counter
local v = 0; -- non battery device counter
local m = 0; -- mail counter
local x = 0; -- other devices
local nb= 0;
local b_full,b_low,b_warn,b_empty = 0,0,0,0
printf('<font color="cyan">'..os.date(dtformat).. ' Version: '..version);
validate(phoneID)
printf('<font color="skyblue">Daten werden aufbereitet...')
if debugout then print('<span style="border:1px solid green"><font color="green">Nr |Sec| Geräte Name | Raum Name ------------ ----- |XWert% |Sym</font></span>') end
for id = 1, #devices_all do
--print('for id')
if(devices_all[id].properties.batteryLevel ~= nil) then
--print('ist batterie')
batteryLevel = devices_all[id].properties.batteryLevel;
--print(batteryLevel)
else
batteryLevel = nil;
end
if(devices_all[id].properties.nodeId ~= nil) then
nodeId = devices_all[id].properties.nodeId;
--print(nodeId)
else
nodeId = nil;
end
if(devices_all[id].properties.dead ~= nil) then
if(devices_all[id].properties.dead == false) then
--print('isdead ist false')
isdead = 0;
else
isdead = 1;
end
else
isdead = nil;
end
-- print(isdead)
local devID, linkID = createlink(devices_all[id].id )
if(tonumber(devices_all[id].roomID) == 0) then
room = 'unassigned';
sectionID = 'unassigned';
else
room = fibaro.getRoomNameByDeviceID(devices_all[id].id)
sectionID = tonumber(fibaro.getSectionID(devices_all[id].id))
end
-- print(room)
-- print(sectionID)
if batteryLevel ~= nil and nodeId ~= nil and batteryLevel ~= '' then
dname = devices_all[id].name
-- print(dname)
if oldnodeId ~= nodeId then -- alt lbreached = fibaro.get(devices[id], 'lastBreached')
if(devices_all[id].properties.dead ~= nil) then
lbreached = devices_all[id].properties.lastBreached;
else
lbreached = nil;
end
local sname = getSNamebyID(sectionID)
--if not(room == "unassigned") then
n = string.format('%02d',n+1)
if tonumber(batteryLevel) >= warning and tonumber(batteryLevel) <= full then
local dots = formatString(dname, room)
local tableOK = string.format("%s %s, im Raum %s hat %s %s %% %s", sname, dname, room, dots, batteryLevel, sym.ok)
local statusOK = n..') ' ..tableOK
local htmlOK = "<pre>"..n..') '.. linkID..' '..tableOK .. "</pre>"
if debugout then print('<font color="green">'.. statusOK) end
stathtml = stathtml .. htmlOK;b_full = b_full+1
mstat = mstat .. statusOK ..'\n'
table.insert(tdev, tableOK )
elseif
tonumber(batteryLevel) >= critical and tonumber(batteryLevel) <= warning then
local dots = formatString(dname, room)
local tablewarn = string.format("%s %s, im Raum %s hat %s %s %% %s", sname, dname, room, dots, batteryLevel, sym.warn)
local statuswarn = n..') '..tablewarn
local htmlWarn = "<pre>" ..n..') '..linkID..' '.. tablewarn .. "</pre>"
if debugout then print('<font color ="yellow">'.. statuswarn) end
stathtml = stathtml .. htmlWarn;b_low = b_low+1
mstat = mstat .. statuswarn ..'\n'
table.insert(tdev, tablewarn )
elseif
tonumber(batteryLevel) < critical then
local dots = formatString(dname, room)
local tablecrit = string.format("%s %s, im Raum %s hat %s %s %% %s", sname, dname, room, dots, batteryLevel, sym.crit)
local statuscrit= n..') '.. tablecrit
local htmlcrit = "<pre>"..n..') '..linkID..' '.. tablecrit .. "</pre>"
if debugout then print('<font color="red">'.. statuscrit) end
stathtml = stathtml .. htmlcrit;b_warn = b_warn+1
if pushactiv then
sendPush(statuscrit)
end
mstat = mstat .. statuscrit ..'\n'
table.insert(tdev, tablecrit )
elseif
tonumber(batteryLevel) > full or tonumber(batteryLevel) == empty then
local dots = formatString(dname, room)
local tableempty = string.format("%s %s, im Raum %s hat %s %s %% %s", sname, dname, room, dots, batteryLevel, sym.empty)
local statusempty = n..') ' .. tableempty
local htmlempty = "<pre>"..n..') '.. linkID..' '..tableempty .. "</pre>"
stathtml = stathtml .. htmlempty;b_empty = b_empty+1
if debugout then print('fontcolor="red">'.. statusempty) end
if pushactiv then
sendPush(statusempty)
end
mstat = mstat .. statusempty..'\n';
table.insert(tdev, tableempty )
end
if tonumber(isdead) == 1 then
local dots = formatString(dname, room)
local tabledead = string.format("%s %s, im Raum %s ist tot. %s %s", sname, dname, room, dots, sym.err)
local statusv = string.format("%s %s %s | room %s is dead! ----%s %s", linkID, sname, dname, room, dots, sym.err)
local statusdead = n..') '.. tabledead
local htmldead = "<pre>"..n..') '..linkID.. ' '..tabledead .. "</pre>"
if debugout then print('<font color="red">', statusdead) end
mstat = mstat .. statusdead .. '\n';
stathtml = stathtml .. htmldead
vstatus = vstatus ..fc_r..n..') '..linkID..' '..tabledead .. '\n';
vstatm = vstatm ..n..') '.. devID ..' '.. tabledead..'\n';
sendPush(statusdead)
table.insert(tdev, tabledead )
if teleactiv then --Telegram sender
fibaro.setGlobal('telegram_text', dname.. ' is dead! '.. os.date('%c'))
fibaro.startScene(61)
end
end
-- [[ Check last breached time ]]
if lbreached ~= nil and checklBreached and tonumber(lbreached) > 0 then
local xhours = checklastBreached(uxtimeStamp, lbreached)
if xhours > nBreacheds then
local sname = getSNamebyID(sectionID)
if xhours >= 72 then -- laenger als 3 Tage
timestr = string.format('%.2f',xhours / 24)..' Tagen.'
else
timestr = tostring(xhours) .. ' Stunden.'
end
bstatus = bstatus..'</br>' ..fc_o .. sname ..' '.. dname ..' ('..room..') nicht ausgelöst seit: ' ..timestr.. '\n'
bstatm = bstatm .. sname ..' '.. dname ..' ('..room..') nicht ausgelöst seit: ' ..timestr.. '\n'
nb = nb+1
end
end
if lbreached ~= nil and checklBreached and tonumber(lbreached) == 0 then
bstatus = bstatus..'</br>' ..fc_o.. sname ..' '.. dname ..' ('..room..') noch nie ausgelöst.\n'
bstatm = bstatm .. sname ..' '.. dname ..' ('..room..') noch nie ausgelöst.\n'
nb = nb+1
end
if (n % devpEmail == 0) and oldNodeId == nodeID then
if contains(maildays, weekday) and onlySummaryM == false then
m = m+1
sendMail(userIDs,subject,mstat,m)
mstat = ' '
fibaro.sleep(500)
end
end
--end
end
oldnodeId = nodeId
else -- [[ device is non battery device ]]
if(devices_all[id].type ~= nil) then
dtype = devices_all[id].type;
else
dtype = nil;
end
if (dtype == 'virtual_device') or (dtype == 'HC_user') or (dtype == 'iOS_device') then
x = x+1
else
v = v+1
local dname = devices_all[id].name
if(tonumber(devices_all[id].roomID) == 0) then
room = 'unassigned';
else
room = fibaro.getRoomNameByDeviceID(devices_all[id].id)
end
if (isdead ~= nil and tonumber(isdead) == 1) then
local dots = formatString(dname, room)
local sectionID = fibaro.getSectionID(devices_all[id].id)
local sname = getSNamebyID(sectionID)
local statusdead = string.format("%s %s, im Raum %s ist tot! --%s %s", sname, dname, room, dots, sym.err)
local statusv = string.format("nb)%s %s %s, im Raum %s ist tot! --%s %s", linkID, sname, dname, room, dots, sym.err)
local htmldead = "<pre>nb) "..string.format("%s %s %s im Raum %s ist tot! --%s %s", linkID, sname, dname, room, dots, sym.err).."</pre>"
mstat = mstat .. statusdead .. '\n';
vstatm = vstatm..'nb) '.. devID..' '..sname..' '..dname..' im Raum'..room..' ist tot'.. ' '..sym.err..'\n';
table.insert(tdev, statusdead )
if debugout then print('<font color="red">'.. statusdead) end
vstatus = vstatus .. fc_r.. statusv .. '\n';
stathtml = stathtml .. htmldead
sendPush(statusdead)
end
end
end
fibaro.sleep(80)
end --for
-- [[ data output and last mail send ]]
if sortout then
print('')
table.sort(tdev)
table.insert(tdev, 1, "<span style='border:1px solid grey'>"..'Sec| Geräte Name | Raum Name - - - - - - - - - - |Wert% |Sym.' .. "</span>")
printf('<font color="skyblue" --- Sortierte Ausgabe nach Bereichen ---')
for i,j in ipairs(tdev) do
--print(j)
print(fc_c..j)
end
end
--end sending battery status----------------------------------
if contains(maildays, weekday) and onlySummaryM == false then
m = m+1
sendMail(userIDs,subject,mstat,m)
mstat = ' ';
end
--end sending battery status----------------------------------
if ( not checklBreached) then bstatus = "Der 'last breached status' wurde nicht gecheckt. \n" end
if (vstatus == '') then
vstatus = vstatus .."\nKeine toten Geräte gefunden.\n"
vstatm = vstatm .. vstatus
end
hc2runtime = "HC3 läuft seit: " .. checkhc2().. ' mit FW: '.. FW
vstatus = vstatus ..'</br>'.. fc_o.. n .. ' Batterie Geräte wurden gecheckt.\n</br>'
vstatus = vstatus ..fc_o.. 'Davon: '..b_full..' Voll, '..b_low.. ' Medium, '..b_warn..' Schwach, '..b_empty..' Leer\n'
vstatus = vstatus ..'</br>'..fc_o.. 'Alle nicht Batterie Geräte gecheckt.'
b_stat = n .. ' Batterie Geräte wurden gecheckt.\n'
b_stat = b_stat..'Davon: '..b_full..' Voll, '..b_low.. ' Medium, '..b_warn..' Schwach, '..b_empty..' Leer'
bstatus = bstatus ..'</br>'..fc_r..'Anzahl: '..nb..' <- Behalten sie diesen Wert im Auge.'
separator = '-----------------------------------------------------------------'
if htmlout then print('<font color="lightgreen">'.. stathtml) end
printf('<font color="cyan"> -------------~= Zusammenfassung der Überprüfung. =~--------------')
printf('<font color="orange">'..vstatus)
printf(fc_c.. separator)
print(fc_c..'--- Geräte deren Status "not breached" seit längerem besteht. ---')
print(fc_o.. bstatus)
print(fc_g..hc2runtime )
print(fc_c.. "Geräte geprüft am: ".. os.date(dtformat))
mstat = vstatm..b_stat..'\n'
mstat = mstat..separator..'\n'..bstatm
mstat = mstat..'Anzahl: '..nb.. ' <- Behalten sie diesen Wert im Auge.\n'
mstat = mstat .. hc2runtime .. '\n \rGeprüft am: '..os.date(dtformat)..' Ver.: '..version
if contains(maildays, weekday) then
m = m+1
sendMail(userIDs,subject,mstat,m)
mstat = ' ';
end
end -- function
function main()
-- print("Main Start")
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
checkallDevices()
end
fibaro.setTimeout(60*1000,main)
end
if (sourceTrigger["type"] == "se-start") then
main()
else
if (sourceTrigger["type"] == "user") then
print('User start')
local currentDate = os.date("*t");
weekday = currentDate.wday
checkallDevices()
end
end
main()
Debug Ausgabe:D