Und noch ein Batterie check scipt

Ich werd mal lieber die V 121 wieder einspielen, mich stören die API Meldungen nicht und das alte Skript funktioniert hervoragend :wink:

@pblacky, @BlackOSX,

bitte mal die Funktion mit dieser ersetzen:


local function getSNamebyID(sectionID)
   if checkSection then
     if sectionID == nil 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

Leider nicht :

[DEBUG] 16:22:38: [1;31m2018-09-03 16:22:38.174166 [ fatal] Unknown exception: /opt/fibaro/scenes/218.lua:100: unexpected symbol near '&'

@jeep

Wenn das auch nicht hilft vermute ich dass Ihr devices habt die ich nicht habe und dann muss ich wahrscheinlich auf diese reagieren.
Keine Ahnung obs da mehr um die Section geht? Alle Fixes von Dir probiert , Fehler bleibt. Mit local checkSection = false; läuft es durch. Zwischen diesen zwei Meldungen kommt mit true der Fehler.

Screenshot_2018-09-03-Home-Center-2.png

Dass ist ja echt blöd, es geht schon um um die Section, eben weil mit false der Fehler nicht auftritt.
Wer mir helfen will der soll mal diese Funktion so ändern:

 local function getSNamebyID(sectionID)
  print('SectionID: '..sectionID)
  if checkSection then
     if sectionID == nil 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

Vor dem Fehler sollte in der Debug Ausgabe bei "SectionID: ", hoffentlich etwas drinnen stehen was uns weiterbringt.

Da kommt, sorry hatte ich vorhin vergessen, hatte das print schonmal drin

113 ist
if tonumber(sectionID) > 0 then

Screenshot_2018-09-03-Home-Center-22.png

@BlackOSX,
OK, Danke, das ist gut, versuche es jetzt zu reproduzieren.

@pblacky, @BlackOSX
Ja, ich denke ihr habt ein paar Devices ohne Raumnamen. Hoffe das ich das umgehen konnte. Da steht jetzt bei der Section ‘ns’ drin.
Danke für Eure Hilfe. Trotzdem werden jetzt auch Batteriegeräte ohne Raumnamen berücksichtigt.

--[[
%% autostart
%% properties
%% globals
--]]
 
--[[
file    :    Battery&devicestatus.lua
version : 1.2.7 - DE, 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.7"
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 = false;   -- true - sendpush notification
local teleactiv = false;   -- true - send message via telegram
local phoneID   = {495}   -- phone IDs for push notification
local checktime = "19:25" -- 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 == 'unassigned' then return 'ns' 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 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 = tonumber(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

Damit läuft es wieder durch :slight_smile:

Am Ende kommt noch das

Bildschirmfoto-2018-09-04-um-05.03.30.png

Danke @BlackOSX, immerhin ein Fortschritt. Das dumme ist, dass ich bei mir keine Fehler mehr bekomme. Bin jetzt auch auf feedback von anderen Benutzern angewiesen. Auf alle Fälle werde ich den Code nochmal durchgehen, vielleicht fällt mir was auf.

Muss doch gleich ein Update nachschieben. In der letzten Version, bedingt durch den Umbau des Scripts stimmen die lastBreached Werte der Module nicht. Die sind einfach veraltet und werden nur rehreshed wenn man das Script neu startet startet.
Der Fehler ist in dieser Version behoben.

Changelog für Version 1.2.8
Bugfix im bei lastBreached Werten

--[[
%% autostart
%% properties
%% globals
--]]
 
--[[
file    :    Battery&devicestatus.lua
version : 1.2.8 - DE, 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.8"
local oldnodeId = nil ;
-- The variables below can be changed by user.
local subject   = "Battery and device status";
local userIDs   = {2,4}     -- mailuser ids
local devpEmail = 25      -- devices per email
local maildays  = {1,3,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:25" -- 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 == 'unassigned' then return 'ns' 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 tdev = {}
local sym ={warn='?', ok='✔️', empty='❓', crit='⛔️', err='❌' }
local sectiontab = api.get("/sections")
local values = #sectiontab

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 = tonumber(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
           -- 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(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
             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
       devices_all = api.get('/devices/?enabled=true&visible=true&isPlugin=false');
       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
       devices_all = api.get('/devices/?enabled=true&visible=true&isPlugin=false');
       checkallDevices()
    end
end

Hi @jeep,
Bin gerade vom Urlaub zurück und habe gleich mal dein aktuelles Skript getestet.
Kann es sein, dass es keine Mails verschickt?
Hat das jemand außer mir auch ?

@pblacky, ich bekomme auch keine Mails verschickt. Anscheinend nur über dieses Script. Ein anderes funktioniert ohne Probleme. Hat Fibaro vielleicht was an der maximalen Länge der Mail geändert und der Inhalt wandert in’s Nirvana?
Ok, nochmal geprüft und genauer angeschaut. Jeep hat ja die Deviceanzahl ja änderbar gemacht. Wird diese reduziert, z.B. 25 -> 20 funktioniert die Mail auch wieder.

Klappt bei mir mit “20” auch, danke für den Tipp

@Jeep
tolles Script, genau danach habe ich gesucht. Habe schon einige leere Batterien ausgewechselt ohne vorherige Warnung durch HC2.
Läuft bei mir ohne Probleme!

In der Auflistung der Sensoren werden die Bereiche/Sektionen leider nur mit 2 Buchstaben angezeigt.
An welcher Stelle in Deinem Script kann ich die Länge des Textes ändern, ich hab’ nichts gefunden
an dem der Text auf 2 Stellen reduziert wird.

Danke im Voraus

ATARI

@pblacky, @Andy
bei mir läuft es auch mit 25 devices pro Mail. Es kann aber sein dass ihr längere Raum und/oder Device Namen habt. Es könnte aber auch speziell an dieser Version liegen denn die entnimmt die Daten aus einer Variablen in der alle Devices Daten stehen. Die Versionen bis 1.2.1 lesen die Daten für jedes Gerät einzeln direkt aus der api. Mal schauen ob Fibaro in der nächsten Version was an der API dreht. Oder zumindest den Fehler in der Funktion getRoomNameByDeviceID fixt.

@ATARI,
die Zeile 103 ist dafür verantwortlich:
return string.sub(tostring(section.name),1, 2)…','

So bekommst Du 5 Zeichen der Section geliefert.
return string.sub(tostring(section.name),1, 5)…','

Weitere Hinweise findest Du im PDF bei Version 1.2.1 (also eine Seite zurück)

@jeep
Vielen Dank, nun ist’s perfekt für mich.

Gruß,
ATARI

@jeep

Ich erhalte seit einiger Zeit folgende Einträge:

  1. MK Haustür, Flur hat --------------- 40 % :heavy_check_mark:
  2. MK Haustür, Flur ist tot. --------------- :x:

Die Bat. scheint leer zu sein, habe sie deswegen entfernt, neue Bat. sind bestellt.
Da es sich um ein und den gleichen Sensor handelt wundere ich mich über die 2 Einträge.
Außerdem ist es merkwürdig, das der Bat.Status immer noch bei 40% liegt, obwohl keine
Bat. mehr vorhanden (vermutlich letzter gespeicherter Bat.wert in der HC2).
Merkwürdig ist auch, das der Sensor bei 40% Bat. nicht mehr funktioniert.

Gruß,
ATARI

@atari

genau so ist es. Der letzte gemeldete Wert bleibt in der HC2 gespeichert. Das heißt die Batterie ist zwischen 2
Aufwachzyklen verstorben.
Das ist bei Lithium Batterien normal. Hatte auch schon Fälle wo ab 70% die Batterie den nächsten Zyklus nicht
überlebte. Die Batterie bricht einfach beim nächstbesten Verbindungsaufbau (denn da wird Strom gezogen) zusammen.
Manchmal geht der Saft auch während der Kommunikation aus, macht sich durch 255% Wert bemerkbar.
Deshalb habe ich ja auch den “Dead Status” und den “Last breached” mit einbezogen. Sonst wäre es ein trügerische Sicherheit
auf die man sich verlassen hätte.

Also, alles so wie es sein soll. Neue Batterie einsetzen und alles ist wieder OK.

Weil hier gerade die Rede von Batterien ist…
Ich falle regelmäßig darauf herein diese Lithium Batterien nachzumessen zu wollen. Hab gerade bei einen toten Türsensor 3,5V gemessen, also eigentlich nicht leer. Jedoch reicht wohl Strom/Leistung nicht mehr aus, den Sensor zu betreiben. Beim Nachmessen des Kurzschlussstromes wird der Unterschied dann etwas deutlicher. Die leere bringt 200mA, während eine frische 600mA liefert. Neue rein und er läuft wieder…