Und noch ein Batterie check scipt

Hi,

ich habe das Script nun ein paar Tage im Einsatz. Es läuft einwandfrei.
Allerdings haben mich irgendwann die Push-Nachrichten gestört (ich bin noch am Basteln und habe ein paar tote Module, die jetzt täglich reportet werden.)

Ich verwende das Script in der Version 1.2.0, wie weiter oben gepostet.
Dort steht “local pushactiv = false”. Meine Frage daher: Wieso werden überhaupt Push-Nachrichten versendet, wenn doch “false” eingestellt ist?

Ich habe mir auf jeden Fall soweit beholfen und die local function ein wenig erweitert.
Hierdurch werden Push-Nachrichten auch nur am Email-Tag versendet.

local function sendPush(text)
 if contains(maildays, weekday) then -- ist der Zusatz, der auch den Email versandt reguliert
   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 -- dass end nicht vergessen
end

Vielleicht nützt es ja auch dem einen oder anderen von euch.

Gruß
Mr.Coffee

@Mr.Coffee, das war auch so gewollt dass push Nachrichten für tote Module sofort und immer gesendet werden, denn:
- Tote Module bei Batteriegeräten würde man sonst nie oder nur sehr spät entdecken, da sie nicht vom HC2 gepollt werden.

  • Tote Module sollen sofort inspiziert werden, es kann ja sein dass sie Teil des Alarmsystems sind.
  • Tote Module können das Routing im Mesh Netzwerk stören und dadurch andere Probleme auslösen.

Dies sind nur ein paar der Gründe warum ich dass so programmiert habe. Wenn man pushactiv auf false setzt, werden nur die push Meldungen für sehr schwache Batterien (unter 30%) unterdrückt da die auch Wochen lang noch funktionsfähig sein können. Das darf jeder so handhaben wie er will. Da könnte man “local critical = 30” auf einen kleineren Wert stellen, aber Fibaro hat den eigenen Mailversand auch ab 30% aktiviert so das ich den gleichen Wert dazu genommen habe um zu warnen. Nur das Fibaro dann Mails im 10 Minuten Rhythmus schickt. :wink:

EDIT: Ich werde den Hinweis in der nächsten Doku mit aufnehmen.

@Jeep
Danke für die Erläuterungen. Klingt pausibel.

Ich kann mich nur wiederholen: Klasse skript.

Gruß
Mr.Coffee

Hallo Jeep

Vielen Dank für den Batterie Check Script. Super Sache…
Versuche mich step-by-step in die Fibaro/LUA Welt einzuleben und das ganze zu verstehen. Die Funktion Telegram Meldungen zu versenden würde ich gerne nutzen doch leider krieg ich das nicht hin.

if teleactiv then  --Telegram sender
                   fibaro:setGlobal('telegram_text', name.. ' is dead! '.. os.date('%c'))  
                   fibaro:startScene(61)

Ich habe schon versucht ‘telegram_text’ nach ‘Telegram’ abzuändern aber leider kein Erfolg (siehe Script unten). Hast das versenden von Telegram Nachrichten anders gelöst wie ich (siehe Script unten)?
Was ist mit der folgenden Zeile gemeint: ‘fibaro:startScene(61)’?

Ich habe ein Telegramm Script mit folgendem Inhalt:

--[[
%% properties
%% globals
Telegram
--]]

--#################   Telegram fuer Home@Fibaro    ######################################

local debug = true;
local token = "xxxxxxxxxxxxxxxxxxxxxxxxx"
local chat_id = "0000000"
local url = "https://api.telegram.org/bot"..token.."/sendMessage?chat_id="..chat_id.."&text="

local function log(str) if debug then fibaro:debug(str); end; end
local function errorlog(str) fibaro:debug("<font color='red'>"..str.."</font>"); end

--Prevents the scene from running again
if (tonumber(fibaro:getGlobalValue("Telegram")) == 0) then
  fibaro:abort();
end

local selfhttp = net.HTTPClient({timeout=2000})
local msg = fibaro:getGlobalValue("Telegram")
log(msg);

url = url .. msg
selfhttp:request(url, {
  options={
    headers = selfhttp.controlHeaders,
    data = requestBody,
    method = 'GET',
    timeout = 5000
  },
  success = function(status)
    local result = json.decode(status.data);
    if result.ok == true then
      log("successful");
    else
      errorlog("failed");
      log(status.data);
    end
  end,
  error = function(error)
    errorlog("ERROR")
    log(error)
  end
})

--Reset the global Telegram variable to 0
fibaro:setGlobal("Telegram", "0") 

Dieses obige Script wird ausgelöst durch folgenden Befehl in anderen Scripts:

fibaro:setGlobal(“Telegram”, “Hello world!”)

@Fa_Do
die Telegram Function wird nur aktiv wenn das Script ein “dead device” sprich totes Modul erkennt und die Variable teleactiv auf true steht.
Meine Telegram Szene ist ähnlich, wird aber nicht durch die globale Variable getriggert sondern wird mit fibaro:startScene(NR_DER_TELEGRAMM_SZENE) aufgerufen. Das du dann “telegram_text” durch Deine Variable “Telegram” ersetzen musst ist korrekt.
Eigentlich brauchst Du dann die Zeile fibaro:startScene(61) gar nicht.
Vielleicht kannst Du ein totes Modul simulieren (Zwischenstecker ziehen und ein paar man ON/OFF senden).

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

bei mir läuft das Skript unter Firmware 4.503 nicht mehr, folgende Fehlermeldungen (ca. 40x):

[DEBUG] 15:34:45: [1;31m2018-07-03 15:34:45.573409 [ error] API: Not found

Läuft das bei euch durch?

Viele Grüße
Schnuckman

@schnuckman79

da ich keine Betas installiere kann ich Dir noch keine Antwort geben. Dass Fibaro die API geändert hat liegt auf der Hand. Sobald die Final 4.5xx raus ist werde ich mich sofort darum kümmern.

Hallo zusammen, hat sich hier schon etwas bezüglich der Fehlermeldung getan?

Grüße Cannon

@Cannon_82
Leider hat Fibaro den Fehler in der 4.510 immer noch nicht beseitigt. Im Prinzip sind das nur Warnungen, das Script läuft aber ohne Probleme weiter. Ist unschön aber erstmal diese Warnungen ignorieren.
Fibaro will sich bis zur nächsten Version darum kümmern. Wenn dann nichts passiert ist muss ich wohl an einem Umbau des Scripts denken.

@jeep
Danke für die Antwort. Ich hatte das Problem bei mir in meinem eigenen Skript zur Prüfung des Batterie-Status. Dieses ist aber bei weitem nicht so komplex wie deines und bei mir kam der “Fehler” durch die Abfrage von Devices, welche keine Batterie haben.

Ich konnte den “Fehler” durch die Einschränkung “local deviceID = fibaro:getDevicesId({interfaces = {‘battery’}, enabled = true, visible = true})” in meinem Skript beheben und alles läuft wieder wie ich es gerne hätte.

Grüße Cannon

@Cannon_82

Ich konnte den „Fehler“ durch die Einschränkung „local deviceID = fibaro:getDevicesId({interfaces = {‚battery‘}, enabled = true, visible = true})“ in meinem Skript beheben und alles läuft wieder wie ich es gerne hätte.

Ja genau das kann ich nicht machen, weil das Script über alle device gehen muss um tote Geräte festzustellen. Ist halt schon lange kein reines Battery Check Script mehr.
Müsste eher „Device check Script“ heißen.

Hallo Jeep,

schönes Script ich nutze es auch schon länger :). Wie du ja weißt gab es bei der letzte FW ein Update der API das jetzt immer Fehler ausgeworfen werden wenn man was anfragt was es nicht gibt. Da ich alle Debug Fenster mit einer anderen Scene auf error, fehler etc. überwache ist das natürlich nur so mittel geil.

Ich habe das Script so umgebaut das die Fehler weg sind. Ein Problem habe ich aber noch:

[DEBUG] 09:32:08: [1;31m2018-08-24 09:32:08.704570 [ error] API: Bad request
ich konnte es auch eingrenzen: Das Problem ist in der send_mail aber nur bei der zweiten Mail die erste Mail funktioniert normal -> Wenn ich die variable status in der zweiten Mail auf einen festen wert wie test setze kommt der Fehler nicht. Irgendwas mag Fibaro also am Content nicht. Vielleicht findest du, oder wir zusammen ja den Fehler. Magst du mir mal eine E-Mail schreiben (nico2018@intelligentes-haus.de) oder mir einfach mal bei Facebook schreiben: ttps://www.facebook.com/nico.bode90 dann können wir mal schauen das wir den Fehler auch noch wegbekommen :).

Ich möchte es ungern hier posten da a) noch ein Fehler enthalten ist (und die Foren hier eh schon unübersichtlich sind weil man den ersten Beitrag nicht editieren kann :-() und b) es klar ersichtlich sein soll das, dass Script von dir ist.

Liebe Grüße,
Nico Bode

Hallo Nico,

habe eben Deine Version jetzt mal 1 zu 1 übernommen. Danke für die Hilfe. Der Fehler der bei Dir auftritt kann ich nicht bestätigen. Die Mails laufen ohne API-Fehler durch. Aber das habe ich ja schon in meiner Mail geschrieben das manche Sachen auch Userbezogen sein könnten. Fibaro hat ja mal monatelang keine Mails an Domains mit Bindestrich im Domainnamen zugestellt.
Habe noch eine kleine Änderung in einer Funktion eingearbeitet (hat aber nichts mit mailen zu tun) und teste es noch ein paar Tage bevor ich es einstelle.

Da fibaro sich diesmal mit einer Beta ewig Zeit lässt, gibt es jetzt eine geänderte Version die hoffentlich keine “API not found” Warnungen produziert. Danke an Nico für die Unterstützung.
Ansonsten wurden keine große Änderungen am Script gemacht. Die Variablen können wie vorher beliebig geändert werden und somit die Ausgabe angepasst werden. Das letzte PDF ist immer noch gültig.

--[[
%% autostart
%% properties
%% globals
--]]
 
--[[
file    :    Battery&devicestatus.lua
version : 1.2.5 released on 31.08.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.5"
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,4,6} -- 1=Sunday, 2=Monday, 3=Tuesday ...7=Saturday
local pushactiv = false;   -- true - sendpush notification
local teleactiv = false;   -- true - send message via telegram
local phoneID   = {495}   -- 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 = true -- | false
local htmlout  = true -- | 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 u=1, #userIDs do
      if userIDs[u] ~= nil then
        fibaro:call(userIDs[u], "sendEmail", subject, status)
      end
   end
   status = ' ';
   if debugout then Debug('green','Mail Nr. '..m.. ' sent.') end 
  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 getSNamebyID(sectionID)
  if checkSection then
     if sectionID > 0 then
        local section = api.get("/sections/" .. tostring(sectionID))
        return string.sub(tostring(section.name),1, 2)..','
     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 devices_all = api.get('/devices/?enabled=true&visible=true&isPlugin=false');

local function checkallDevices()
  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_all do
    if(devices_all[id].properties.batteryLevel ~= nil) then
       batteryLevel = devices_all[id].properties.batteryLevel;
    else
       batteryLevel = nil;
    end
 
    if(devices_all[id].properties.nodeId ~= nil) then
       nodeId  = devices_all[id].properties.nodeId;
    else
       nodeId = nil;
    end
  
    if(devices_all[id].properties.dead ~= nil)  then
       if(devices_all[id].properties.dead == false) then
          isdead = 0;
       else
          isdead = 1;
       end
    else
       isdead = nil;
    end
 
    if(tonumber(devices_all[id].roomID) == 0) then
       room = 'unassigned';
       sectionID = 'unassigned';
    else
       room = fibaro:getRoomNameByDeviceID(devices_all[id].id)
       sectionID = fibaro:getSectionID(devices_all[id].id)
    end
   
    if batteryLevel ~= nil and nodeId ~= nil and batteryLevel ~= '' then
        name   = devices_all[id].name
        if oldnodeId ~= nodeId then
           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(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';
                if pushactiv then              
                sendPush(statusdead)
                end
                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 = getSNamebyID(sectionID)
                    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
 
        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 name = devices_all[id].name
 
           if(tonumber(devices_all[id].roomID) == 0)
           then
               room = 'unassigned';
           else
               room = fibaro:getRoomNameByDeviceID(devices_all[id].id)
           end
 
          if tonumber(isdead) == 1 then
             local dots = formatString(name, 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, 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
             if pushactiv then              
                sendPush(statusdead)
             end
          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
       checkallDevices()
    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
       checkallDevices()
    end
end

Ich bekomme:
[DEBUG] 10:38:37: Sun Sep 2 10:38:37 2018, Version: 1.2.5
[DEBUG] 10:38:37: Daten werden aufbereitet…
[DEBUG] 10:38:40: [1;31m2018-09-02 10:38:40.526960 [ fatal] Unknown exception: /opt/fibaro/scenes/218.lua:100: attempt to compare number with string

Hat das außer mir noch jemand?
Genauere Infos siehe Anhang

2018-09-02-10_43_13-Home-Center-2.jpg

Nein, hab ich nicht, wurde an 2 HC2s getestet, aber versuch mal Zeile 155 durch folgende zu ersetzen.
sectionID = tonumber(fibaro:getSectionID(devices_all[id].id))

Wenn das auch nicht hilft kann ich Dir die alte Function zur Verfügung stellen.

[DEBUG] 20:36:11: [1;31m2018-09-02 20:36:11.031237 [ fatal] Unknown exception: /opt/fibaro/scenes/23.lua:100: attempt to compare number with string
Kommt bei mir auch ,nur bissl weiter unten, nach Ausgabe einiger Devises.
Deine Zeile ändert dabei nix.

OK, das war auch nicht richtig gedacht, aber probiert bitte das in Zeile 100 :
if tonumber(sectionID) > 0 then

Wenn das auch nicht hilft vermute ich dass Ihr devices habt die ich nicht habe und dann muss ich wahrscheinlich auf diese reagieren.
Ein print(sectionID) vor der Zeile hundert wäre auch hilfreich. Eventuell ist der Wert vor dem Fehler ‘nil’.

Jetzt bekomm ich :

[DEBUG] 07:34:18: Mon Sep 3 07:34:18 2018, Version: 1.2.5 [DEBUG] 07:34:18: Daten werden aufbereitet... [DEBUG] 07:34:21: [1;31m2018-09-03 07:34:21.178354 [ fatal] Unknown exception: /opt/fibaro/scenes/218.lua:100: attempt to compare number with nil

Ich werd mal lieber die Vorgänger Version wieder einspielen, mich stören die API Meldungen nicht und das alte Skript funktioniert hervoragend :wink: