Und noch ein Batterie check scipt

Hallo,
keine Ahnung seit welcher Version (Script bzw Software H2C) werden Umlaute in der Mail und dem iPhone nicht dargestellt.
Türe = Türe
Im Debug Modus der H2C stimmt die Ausgabe noch.

Hallo @jeep
Dein Batteriecheck Skript entpuppt sich ja inzwischen als wahres Multitalent :wink:
Habe gerade die aktuellste Version eingespielt und getestet, läuft gut!!
Durch die Modulare Bauweise mit den Funktionen konnte ich auch die Push Nachricht ganz leicht auf Pushover ändern :wink:

Frage zur Funktion:
Ich habe einige Geräte die ich zum Testen verwende, sowie eine DomiBulb die an einem physischem Schalter hängt.
Diese werden natürlich als “dead Devices” aufgelistet.
Ich weiß nicht ob das mehrere Leute brauchen könenn, aber ich würde mir eine funktion wünschen um einige Devices die nicht ind Funktion sind von der Prüfung auszunehmen.

Ist das leicht einzubauen?
Macht das überhaupt Sinn?

Hallo Jeep,
Habe dein neues Skript nun etwas ausführlicher getestet. Dazu eine alte Batterie in ein Device eingebaut und einen Emailversand ausgelöst.
Die BEbug ANzeige funktioniert gut, aber leider wird mit der V 8.0.4b bei mit kein EMail verschickt!

Habe inzwischen wieder dein Original Skript hergenommen um auszuschliessen dass meine Änderungen (Pushover) daran schuld sind.
Habe nur die phoneID, userID und die Variable “warning” auf “51” geändert, eine leerere Batterie hab ich nicht :wink:
Auch dort bekomme ich keine Email, Pushnachricht funktioniert allerdings!

Mit dem alten Skript und der selbenr UserID klappt es einwandfrei!
Liegt also eher an dem neuen Skript !?
Hab ich eine Einstellung übersehen??

Hi pblacky,

schau mal welche Tage für den Mail Versand eingetragen sind. Das Script verschickt nur Mails, manuell auch, wenn der Tag Zeile 25 eingetragen ist dort steht 1,3,7 also dürfte heute keine Mail kommen.

Trag einfach alle Tage zum testen ein.

Grüße
Gringo

Danke Gringo1,
Ich hab total übersehen, dass das Skript ja noch Tage auch berücksichtigt!!
Werd das gleich mal testen…

Hallo,
Bin den Rest der Woche nicht, da, kann also nur mitlesen, ?

Gesendet von meinem Nexus 7 mit Tapatalk

Habe mir eine funktion um die Nachricht gebaut, so werden Umlaute wieder richtig dargestellt. Warum es erst ging, keine Ahnung. Die Zeit wird es zeigen, ob es vielleicht doch an der eingesetzen Beta lag.

Hallo, Bin den Rest der Woche nicht, da, kann also nur mitlesen, ?

Wie? Tu mal was für dein Geld ???

Die Anzal v von vstatus = vstatus …v… ' non battery devices checked.'
scheint nicht zustimmen. Bei mir kommt da 19 raus was eher der Zahl der gesamten IDs entspricht.

Das Problem mit den Umlauten gibt es laut Fibaro Forum seit einer der letzten Betas. Andere Länder mit ihren Sonderzeichen
sind auch betroffen.
In der 0.8.4b gab es noch das Problem das eine größere Anzahl an devices ausgegeben wurde als tatsächlich vorhanden. Der
Grund dafür, in der Fibaro DB stehen normale devices, Batterie devices, Virtuelle devices, iOS_devices, Plugins usw. also
bunt gemischt drin.
Hab jetzt noch ein wenig am Filter gedreht und eine zusätzliche Typenabfrage erstellt, so dass es jetzt (ich hoffe es)
stimmen müsste. Bei mir bin ich von 66 auf 45 nicht Batteriedevices runter und das scheint zu stimmen. Es ist möglich dass
es noch andere Typen gibt, die ich aber nicht habe und sie deshalb auch nicht filtern kann.

Changelog für Version 0.8.5b
— Erweiterter Filter für Plugins
— Neue Typenabfrage


--[[
%% autostart
%% properties
%% globals
--]]

-- file:    Batterystatus.lua 
-- version: 0.8.5b
-- 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.
-- For batteries that are almost empty, or a dead device is recognized,
-- a push messages will be sent immediately.
-- A manual check is possible at any time. Simply press the Start button.
-- Copyleft 03-2017 {jeep}

local sourceTrigger = fibaro:getSourceTrigger();
local version   = "0.8.5b"
local oldnodeId = nil ;
local subject   = "Battery status";
local userId    = 2      -- primary email address
local devpEmail = 20     -- devices per email
local days      = {3,7} --  1=Sunday, 2=Monday, 3=Tuesday ...7=Saturday
local pushactiv = true;   -- true - sendpush notification
local teleactiv = true;   -- true - send message via telegram 
local phoneID   = {13}    -- phone IDs for push notification
local checktime = "19:15" -- At this time the script runs
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 

Debug = function ( color, message )
  fibaro:debug(string.format('<%s style="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 sendPush(text)
 if (phoneID[1] ~= nil) then
   for i=1, #phoneID do
      if phoneID[i] ~= nil then
        fibaro:debug('Versende Push an ID ' ..phoneID[i])
        fibaro:call(phoneID[i],'sendPush', text)
      end
   end
 end
end

function useremail(userId,subject,status,m)
  local subject = subject..'-'..m
  fibaro:call(userId, "sendEmail", subject, status)
  --fibaro:call(5, "sendEmail", subject, status)  
  status = ' ';
    print('Mail gesendet-'.. m)
end  

function checklastBreached(uxtimeStamp, lbreached)
  xseconds = (uxtimeStamp - lbreached)
  xtime    = (xseconds /60) / 60
  xhours   = math.floor(xtime)
  return xhours
end  

devices = fibaro:getDevicesId({visible = true, enabled = true, isPlugin =false })
--print(json.encode(devices))
function checkBatteries() 
  uxtimeStamp = os.time(dt);
  status  = '';
  vstatus = '';
  bstatus = ''; 
  local n = 0; -- battery device counter
  local v = 0; -- non battery device counter
  local m = 0; -- mail counter
  local x = 0;
  Debug('withe', os.date('%c')..', Version: '.. version );
  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 lbreached = fibaro:get(devices[id], 'lastBreached')
          if not(room == "unassigned") then
             n = n+1
             if tonumber(batteryLevel) >= warning and tonumber(batteryLevel) <= full then
        		Debug('green', "Battery " ..name..' ('..room..') - Battery: '..batteryLevel..' % OK') 
                status = status .. n .. ") " ..name..' ('..room..') ' ..batteryLevel..' % OK\n';
             elseif
               tonumber(batteryLevel) >= critical and tonumber(batteryLevel) <= warning then
               Debug('yellow', "Battery " ..name..' ('..room..') - Battery: '..batteryLevel..' % Warning') 
               status = status .. n .. ") " ..name..' ('..room..') ' ..batteryLevel..' % Warning\n';
             elseif 
               tonumber(batteryLevel) < critical  then 
               Debug('red', "Battery " ..name..' ('..room..') - Battery: '..batteryLevel..' %') 
               if pushactiv then           
                  sendPush('Batterie: '.. name ..' in room '.. room ..' '.. batteryLevel..'%.')
               end
               status = status .. n .. ") " ..name..' ('..room..') ' ..batteryLevel..' % Critical\n';
             elseif
               tonumber(batteryLevel) > full or tonumber(batteryLevel) == empty then 
               Debug('red', "Battery " ..name..' ('..room..') - Battery: '..batteryLevel..' % probably empty!') 
               if pushactiv then           
                  sendPush('Batterie: '.. name ..' in room '.. room ..' '.. batteryLevel..'%.')
               end
               status = status .. n .. ") " ..name..' ('..room..') ' ..batteryLevel..' % Error\n';
             end
          
             if tonumber(isdead) == 1 then
                Debug('red', "Battery " ..name..' ('..room..') - Device is dead!') 
                status = status .. 'Alert! ' .. name..' ('..room..') - Device is dead \n';
                vstatus = vstatus .. 'Alert! ' .. 'device '.. name ..' - Device is dead! \n';   
                sendPush(name ..' in room '.. room ..' '.. batteryLevel..'%. Device is dead!')
               -- if teleactiv then
               --   	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
                 xhours = checklastBreached(uxtimeStamp, lbreached)
                 if xhours > nBreacheds then
                    bstatus = bstatus .. name ..' not breached since: ' ..xhours.. ' hours\n'
                 end
              end    
                              
             if (n % devpEmail == 0) and oldNodeId == nodeID then
                if contains(days, weekday) then
                   m = m+1
                   useremail(userId,subject,status,m)
                   fibaro:debug(status)
                   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
             Debug('red', "Device " ..name..' ('..room..') - Device is dead!') 
             vstatus = vstatus .. 'Alert! ' .. 'device '.. name ..' - Device is dead! \n';
             sendPush('Device: '.. name ..' in room '.. room .. ' - is dead!')
          end 
       end 
    end  
  end  --for
 
  status    = status .. 'Checked at: ' .. os.date('%c') ..'\n'
  status    = status ..n.. ' battery devices were checked.\n' 
  vstatus   = vstatus ..v.. ' non battery devices checked.'
  separator = '------------------------------------------------------------'
  Debug('withe', os.date('%c'));
  Debug('withe', separator)
  Debug('withe', status)
  Debug('withe', separator)
  Debug('white', vstatus)
  Debug('withe', separator)
  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(days, weekday) then
      m = m+1
     useremail(userId,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

@Jeep
Werde das mal testen, danke. Muss aber erst noch meine Ändeungen mit der SectionID in deiner neuen Einfügen, da meine Räume in den Sectionen (Etagen) sind.

Die Umlaute habe ich hier mit gefixt

function encodeURI(str)
	if (str) then
		str = string.gsub (str, "\n", "\r\n")
		str = string.gsub (str, "([^%w ])",
		function (c) return string.format ("%%%02X", string.byte(c)) end)
		str = string.gsub (str, " ", "+")
  	end
  return str
end

@Jeep es sind weniger als erst. Wie kann ich schauen, ob es bei mir noch andere Typen zum ausschliessen gibt?

if (dtype == 'virtual_device' ) then
   debug('ja');
else 
  debug('anderer Typ'..dtype);
end 

Mein Code gibt einen Fehler nil, das war es dann ja nicht. Hast Du eine Idee?

Ja, es ist ganz einfach, füge nach Zeile 153: local dtype = fibaro:getType(devices[id])
ein “print(dtype)” ein. Dann einfach im Debugfenster nachschauen.
Viel Erfolg.

Danke, Ausgabe ist schonmal da. Muss die Tage mal schauen was dahinter steckt.
Noch eine Frage @Jeep
Wenn ich die Ausgabe der “Nicht-Batterie” reduziere sollte da statt v nicht x sein ?
vstatus = vstatus …x… ’ non battery devices checked.’
weil sonst gibts ja dann Null, was so auch nicht stimmt :slight_smile:

Nein, das ist richtig so in der Variable “x” zähle ich bloss die devices die weder Batterie noch normale devices sind. Das sind die “other devices”
Beachte bitte die Ausgabe der letzten Zeile im Debug Fenster. Das ist also die Anzahl derGeräte die mit dtype weggefiltert werden.

Hast Recht, hatte da zu viel ausgenommen von der Abfrage :-), so das die Zahl v gegen 0 ging.
Bei mir ist jetzt alles ok, habe das mal gegengezählt.

Danke für das Script @Jeep

Hallo zusammen,

vermutlich eines der letzten Updates, denn so langsam gehen mir die Ideen aus ;-). Aber vielleicht gibt’s ja noch Input durch den einen oder anderen.
Bis dahin viel Spass mit dem Script.

Changelog für Version 0.9.1
– Variable userId durch Array userIDs ersetzt. Es können jetzt mehrere Emailkonten angegeben werden.
– Diverse kosmetische Änderungen

--[[
%% autostart
%% properties
%% globals
--]]

-- file:    Batterystatus.lua 
-- version: 0.9.1
-- 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, only 980 characters per per e-mail 
-- can 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.
-- A manual check is possible at any time. Simply press the Start button.
-- Copyleft 03-2017 {jeep}

local sourceTrigger = fibaro:getSourceTrigger();
local version   = "0.9.1"
local oldnodeId = nil ;
local subject   = "Battery and device status";
local userIDs   = {2,303} -- mailuser ids
local devpEmail = 20      -- devices per email
local days      = {1,3,6,7} --  1=Sunday, 2=Monday, 3=Tuesday ...7=Saturday
local pushactiv = true;   -- true - sendpush notification
local teleactiv = true;   -- true - send message via telegram 
local phoneID   = {2,303}   -- phone IDs for push notification
local checktime = "19:15" -- At this time the script runs
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 

Debug = function ( color, message )
  fibaro:debug(string.format('<%s style="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 sendPush(text)
 if (phoneID[1] ~= nil) then
   for i=1, #phoneID do
      if phoneID[i] ~= nil then
        fibaro:debug('Sent push message to ID ' ..phoneID[i])
        fibaro:call(phoneID[i],'sendPush', text)
      end
   end
 end
end

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

function checklastBreached(uxtimeStamp, lbreached)
  xseconds = (uxtimeStamp - lbreached)
  xtime    = (xseconds /60) / 60
  xhours   = math.floor(xtime)
  return xhours
end  

devices = fibaro:getDevicesId({visible = true, enabled = true, isPlugin =false })

function checkBatteries() 
  uxtimeStamp = os.time(dt);
  status  = '';
  vstatus = '';
  bstatus = ''; 
  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 );
  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 lbreached = fibaro:get(devices[id], 'lastBreached')
          if not(room == "unassigned") then
             n = n+1
             if tonumber(batteryLevel) >= warning and tonumber(batteryLevel) <= full then
        		Debug('green', "Battery " ..name..' ('..room..') - Battery: '..batteryLevel..' % OK') 
                status = status .. n .. ") " ..name..' ('..room..') ' ..batteryLevel..' % OK\n';
             elseif
               tonumber(batteryLevel) >= critical and tonumber(batteryLevel) <= warning then
               Debug('yellow', "Battery " ..name..' ('..room..') - Battery: '..batteryLevel..' % Warning') 
               status = status .. n .. ") " ..name..' ('..room..') ' ..batteryLevel..' % Warning\n';
             elseif 
               tonumber(batteryLevel) < critical  then 
               Debug('red', "Battery " ..name..' ('..room..') - Battery: '..batteryLevel..' %') 
               if pushactiv then           
                  sendPush('Batterie: '.. name ..' in room '.. room ..' '.. batteryLevel..'%.')
               end
               status = status .. n .. ") " ..name..' ('..room..') ' ..batteryLevel..' % Critical\n';
             elseif
               tonumber(batteryLevel) > full or tonumber(batteryLevel) == empty then 
               Debug('red', "Battery " ..name..' ('..room..') - Battery: '..batteryLevel..' % probably empty!') 
               if pushactiv then           
                  sendPush('Batterie: '.. name ..' in room '.. room ..' '.. batteryLevel..'%.')
               end
               status = status .. n .. ") " ..name..' ('..room..') ' ..batteryLevel..' % Error\n';
             end
          
             if tonumber(isdead) == 1 then
                Debug('red', "Battery " ..name..' ('..room..') - Device is dead!') 
                status = status .. 'Alert! ' .. name..' ('..room..') - Device is dead \n';
                vstatus = vstatus .. 'Alert! ' .. 'device '.. name ..' - Device is dead! \n';   
                sendPush(name ..' in room '.. room ..' '.. batteryLevel..'%. Device is dead!')
                -- 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
                 xhours = checklastBreached(uxtimeStamp, lbreached)
                 if xhours > nBreacheds then
                    bstatus = bstatus .. name ..' not breached since: ' ..xhours.. ' hours\n'
                 end
              end    
                              
             if (n % devpEmail == 0) and oldNodeId == nodeID then
                if contains(days, weekday) then
                   m = m+1
                   sendMail(userIDs,subject,status,m)
                   fibaro:debug(status)
                   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
             Debug('red', "Device " ..name..' ('..room..') - Device is dead!') 
             vstatus = vstatus .. 'Alert! ' .. 'device '.. name ..' - Device is dead! \n';
             sendPush('Device: '.. name ..' in room '.. room .. ' - is dead!')
          end 
       end 
    end  
  end  --for
 
  status    = status .. 'Checked at: ' .. os.date('%c') ..'\n'
  status    = status ..n.. ' battery devices were checked.\n' 
  vstatus   = vstatus ..v.. ' non battery devices checked.'
  separator = '------------------------------------------------------------'
  Debug('withe', os.date('%c'));
  Debug('withe', separator)
  Debug('withe', status)
  Debug('withe', separator)
  Debug('white', vstatus)
  Debug('withe', separator)
  Debug('withe', bstatus)
  Debug('withe', "There are " .. x .." other devices, such as virtual devices, HC-user iOSdevices, etc.")
  status = status..separator..'\n'..vstatus..'\n'
  status = status..separator..'\n'..bstatus..'\n'..os.date('%c')
  if contains(days, 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

Das Problem mit den Umlauten, ist mit der neuen FW wieder Geschichte.

Hallo zusammen,

erstmal eine gute Nachricht. Seit der Firmware 4.140 scheint Fibaro die Beschränkung beim Mailversand gefixt zu haben. (Vermutlich haben die doch
meinen Beitrag im Fibaro Forum beachtet.) Vorher war bei 980 Zeichen Schluss. Gestern habe ich mit dem Script eine Mail mit über 1.550 Zeichen
verschickt. Konnte also meine ganzen Batterie-Geräte in einer Mail packen.
Zweitens habe ich dann versucht ein wenig Format in der Mail zu bringen, was mir aber nur teilweise gelang. Das Problem ist ja, dass im Debug-Fenster
und vermutlich in jedem Mailprogramm proportionale Schriften benutzt werden. Durch die Farben im Debug-Fenster ist das nicht so dramatisch,
Problem-Devices fallen sofort auf. Anders in der Mail, da tat ich mir dann immer schwer durch die unterschiedlichen Längen von Device- und Raumnamen
Auffäligkeiten zu entdecken.
Kurz und gut, durch die Art der Schriften ist es mir nur teilweise gelungen die Mail lesbarer zu machen. Wenn ich die Mail in einem Textprogrramm
kopiere und eine Monospace Schrift einstelle, sieht es wie im unteren Bild aus. Also warten wir mal darauf ob jemand eine Idee hat und wir hier
HTML-Mails verschicken können.

Changelog für Version 0.9.2
– Funktion um die Zeilenlänge gleich lang zu machen hinzugefügt.

--[[
%% autostart
%% properties
%% globals
--]]

-- file:    Batterystatus.lua 
-- version: 0.9.2
-- 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, only 980 characters per per e-mail 
-- can 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.
-- A manual check is possible at any time. Simply press the Start button.
-- Copyleft 03-2017 {jeep}

local sourceTrigger = fibaro:getSourceTrigger();
local version   = "0.9.2"
local oldnodeId = nil ;
local subject   = "Battery and device status";
local userIDs   = {2}     -- mailuser ids
local devpEmail = 25      -- devices per email
local days      = {1,4,6} --  1=Sunday, 2=Monday, 3=Tuesday ...7=Saturday
local pushactiv = true;   -- true - sendpush notification
local teleactiv = true;   -- true - send message via telegram 
local phoneID   = {303}    -- phone IDs for push notification
local checktime = "19:15" -- At this time the script runs
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 

Debug = function ( color, message )
  fibaro:debug(string.format('<%s style="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 sendPush(text)
 if (phoneID[1] ~= nil) then
   for i=1, #phoneID do
      if phoneID[i] ~= nil then
        fibaro:debug('Sent push message to ID ' ..phoneID[i])
        fibaro:call(phoneID[i],'sendPush', text)
      end
   end
 end
end

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

function checklastBreached(uxtimeStamp, lbreached)
  xseconds = (uxtimeStamp - lbreached)
  xtime    = (xseconds /60) / 60
  xhours   = math.floor(xtime)
  return xhours
end  

function formatString(name, room)
   slength = string.len(name) + string.len(room)
   dlength = 35 - slength 
   dots    = string.rep ("-", dlength)
   return dots
end  

devices = fibaro:getDevicesId({visible = true, enabled = true, isPlugin =false })
--print(json.encode(devices))
function checkBatteries() 
  uxtimeStamp = os.time(dt);
  status  = '';
  vstatus = '';
  bstatus = ''; 
  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 );
  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 lbreached = fibaro:get(devices[id], 'lastBreached')
          if not(room == "unassigned") then
             n = n+1
             if tonumber(batteryLevel) >= warning and tonumber(batteryLevel) <= full then
        		Debug('green', "Battery " ..name..' ('..room..') - Battery: '..batteryLevel..' % OK') 
                dots = formatString(name, room)
                status = status .. n .. ") " ..name..' ('..room..') ' .. dots ..batteryLevel..' % OK\n';
             elseif
               tonumber(batteryLevel) >= critical and tonumber(batteryLevel) <= warning then
               Debug('yellow', "Battery " ..name..' ('..room..') - Battery: '..batteryLevel..' % WARNING') 
               dots = formatString(name, room)  
               status = status .. n .. ") " ..name..' ('..room..') '..dots ..batteryLevel..' % WARNING\n';
             elseif 
               tonumber(batteryLevel) < critical  then 
               Debug('red', "Battery " ..name..' ('..room..') - Battery: '..batteryLevel..' %') 
               if pushactiv then           
                  sendPush('Batterie: '.. name ..' in room '.. room ..' '.. batteryLevel..'%.')
               end
               dots = formatString(name, room)
               status = status .. n .. ") " ..name..' ('..room..') ' .. dots ..batteryLevel..' % CRITICAL\n';
             elseif
               tonumber(batteryLevel) > full or tonumber(batteryLevel) == empty then 
               Debug('red', "Battery " ..name..' ('..room..') - Battery: '..batteryLevel..' % probably empty!') 
               if pushactiv then           
                  sendPush('Batterie: '.. name ..' in room '.. room ..' '.. batteryLevel..'%.')
               end
               dots = formatString(name, room)
               status = status .. n .. ") " ..name..' ('..room..') ' .. dots .. batteryLevel..' % Error\n';
             end
          
             if tonumber(isdead) == 1 then
                Debug('red', "Battery " ..name..' ('..room..') - Device is dead!') 
                status = status .. 'Alert! ' .. name..' ('..room..') - Device is dead \n';
                vstatus = vstatus .. 'Alert! ' .. 'device '.. name ..' - Device is dead! \n';   
                sendPush(name ..' in room '.. room ..' '.. batteryLevel..'%. Device is dead!')
                -- 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
                 xhours = checklastBreached(uxtimeStamp, lbreached)
                 if xhours > nBreacheds then
                    bstatus = bstatus .. name ..' not breached since: ' ..xhours.. ' hours\n'
                 end
              end    
                              
             if (n % devpEmail == 0) and oldNodeId == nodeID then
                if contains(days, weekday) then
                   m = m+1
                   sendMail(userIDs,subject,status,m)
                   fibaro:debug(status)
                   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
             Debug('red', "Device " ..name..' ('..room..') - Device is dead!') 
             vstatus = vstatus .. 'Alert! ' .. 'device '.. name ..' - Device is dead! \n';
             sendPush('Device: '.. name ..' in room '.. room .. ' - is dead!')
          end 
       end 
    end  
  end  --for
 
  status    = status .. 'Checked at: ' .. os.date('%c') ..'\n'
  status    = status ..n.. ' battery devices were checked.\n' 
  vstatus   = vstatus ..v.. ' non battery devices checked.'
  separator = '------------------------------------------------------------'
  Debug('withe', os.date('%c'));
  Debug('withe', separator)
  Debug('withe', status)
  Debug('withe', separator)
  Debug('white', vstatus)
  Debug('withe', separator)
  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(days, 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

AusMail2monospace.png

Hallo Jeep,
Schön dass du dein tolles Skript immer noch weiterentwickelst :wink:

Habe es gestern wieder mal aktualisiert und dabei ist mir was aufgefallen:
Habe einen Fibaro Testkontakt, den ich immer nur aktiviere, wenn ich was ausprobieren muss.
In diesem ist eine Batterie die nur noch 50% Batteriestand hat. Ich nehme sie immer her um die Signalisierung in deinem Skript zu testen.

Mit der neuen Version deines Skriptes ist mir aufgefallen dass dieser Kontakt nicht berücksichtigt wird, obwohl er im System funktioniert.
Der Kontakt war kurze Zeit deaktiviert und ich habe ihn reaktiviert und einen Wakeup durchgeführt.
Hast du einen Tipp?