Powiadomienia
Wyczyść wszystko

Te dwa skrypty przydadzą się każdemu

1 Wpisów
1 Użytkownicy
2 Reactions
2,076 Wyświetleń
isom
 isom
(@isom)
Wpisów: 5170
Szef wszystkich szefów Moderator Zasłużony dla Forum, Donator 2K19, Donator 2K20
Autor tematu
 

Problemy z bazą danych i samym domoticz,  przy złym zasilaniu czy kiepskiej jakości kartach to zmora,  warto więc na bieżąco kontrolować bazę i stan serwera .

Poniżej skrypt, który działa u mnie już dość długo i przy jakimkolwiek problemie z bazą danych wysyła mi powiadomienie. Nie naprawi to bazy ale pozwoli szybko zareagować.

Skrypt nie jest mojego autorstwa a jedynie go odrobinę dopasowałem do swoich potrzeb i ważne komentarze zmieniłem na rodzimy język.

Do działania skryptu trzeba sobie w domoticz utworzyć czujnik typu "Alert" i nazwać "Baza danych" , lub jeśli nazwiecie inaczej to zmienić to w skrypcie.

W samym skrypcie trzeba odkomentować rodzaj powiadomień i ewentualnie wpisać prawidłowy adres email . W tym przykładzie powiadomienie przychodzi na telegram skonfigurowany w domoticzu.

return {
            on =    {  
                        timer   =   { 
                                        "at 01:00",             -- ustaw godziny jakie chcesz
                                        "at 09:00",
                                        "at 19:00", 
                                    },            
                    },
    
        logging =   {  
                        level     =   domoticz.LOG_DEBUG,       -- zmień na  LOG_ERROR, jak skrypt będzie OK
                        marker    =   " Sprawdzanie DB domoticz" 
                    },

    execute = function(dz)
        -- =======================  USTAWIENIA =================
        local email               = false                        -- jak nie chcesz poczty email to ustaw false
        local notify              = true                         -- jak nie chcesz powiadomien ustaw na false
        local afterSuccessCommand = false                        
        local afterFailCommand    = false                        
     
        local followUpAfterFail   = false                         
        
        local alert = {
                        active   = true,                             -- set to false if you don't want an Alert device set. 
                        device   = "Baza danych",                    -- Nazwa czujnika alert w domoticz
                        failText = "Problem z bazą",
                        OKText   = "Baza danych OK",    
                      }
                      
        local subject             = "Domoticz db check"            -- Dowolny tekst
        local emailaddress        = "twójmail@gmail.com"        -- Twój Email 
        local path                = "/home/pi/domoticz/"            -- pełna ściezka do bazy danych , w malinie nic nie zmieniac 
        local database            = "domoticz.db"               -- database filename + extension
        -- local database         = "corrupt.db"                -- test database filename + extension
                                                                    -- you can corrupt a test database by just load it in an editor
                                                                    -- and remove a couple of bytes
        local sqlite              = "/usr/bin/sqlite3"          -- location of your sqlite3 tool (use the command 'which sqlite3' to find location)
  
        local myNotificationTable     =     {
                                             -- table with one or more notification systems. 
                                             -- uncomment the notification systems that you want to be used
                                             -- Can be one or more of
                                             
                                             -- dz.NSS_GOOGLE_CLOUD_MESSAGING, 
                                             -- dz.NSS_HTTP, 
                                             -- dz.NSS_KODI, 
                                             -- dz.NSS_LOGITECH_MEDIASERVER, 
                                             -- dz.NSS_NMA,
                                             -- dz.NSS_PROWL, 
                                             -- dz.NSS_PUSHALOT, 
                                             -- dz.NSS_PUSHBULLET, 
                                             -- dz.NSS_PUSHOVER, 
                                             -- dz.NSS_PUSHSAFER,
                                             dz.NSS_TELEGRAM,
                                            }
        -- =======================  Nie zmieniaj nic ponizej ==================

         local function logWrite(str,level)             -- Support function for shorthand debug log statements
            dz.log(tostring(str),level or dz.LOG_DEBUG)
        end
    
        local space                   = " " 
        local baseCommand             = "sudo" .. space .. sqlite .. space .. path .. database .. space
        local checks                  = {} 
              checks                  = {
                                                  "\'select count(id) from deviceStatus;\'",
                                                   "\'.schema\'",
                                                  "\'pragma integrity_check;\'",
                                                  "\'pragma foreign_key_check;\'",
                                        }

        local function rc2Text(rc)
            local errorMessages =   {
                                          [0] = "baza domoticz OK",
                                          [1] = "Generic error",
                                          [2] = "Internal logic error in SQLite",
                                          [3] = "Access permission denied",
                                          [4] = "Callback routine requested an abort",
                                          [5] = "The database file is locked",
                                          [6] = "A table in the database is locked",
                                          [7] = "memory allocation failed",
                                          [8] = "Attempt to write a readonly database",
                                          [9] = "Operation terminated by sqlite3_interrupt",
                                         [10] = "Some kind of disk I/O error occurred",
                                         [11] = "The database disk image is malformed",
                                         [12] = "Unknown opcode in sqlite3_file_control",
                                         [13] = "Insertion failed because database is full",
                                         [14] = "Unable to open the database file",
                                         [15] = "Database lock protocol error",
                                         [16] = "Internal use only",
                                         [17] = "The database schema changed",
                                         [18] = "String or BLOB exceeds size limit",
                                         [19] = "Abort due to constraint violation",
                                         [20] = "Data type mismatch",
                                         [21] = "Library used incorrectly",
                                         [22] = "Uses OS features not supported on host",
                                         [23] = "Authorization denied",
                                         [24] = "Not used",
                                         [25] = "2nd parameter to sqlite3_bind out of range",
                                         [26] = "File opened that is not a database file",
                                     }
            return(errorMessages[rc] or "Unknown error")
        end

        local function followUp(cmd)
            os.execute('sudo ' .. cmd ..' &')
        end

        local function osExecute(base,check)
            local fileHandle     = assert(io.popen(base .. check, 'r'))
            local commandOutput  = assert(fileHandle:read('*a'))
            local returnTable    = {fileHandle:close()}
            check = check:gsub("'","") .." result ==>> " ..  ( returnTable[3] ~= 0 and "Failed: " .. rc2Text(returnTable[3]) .. commandOutput .. " (".. returnTable[3] .. ")" or true and "OK" )
            logWrite("Command " .. check )
            return check,returnTable[3]            -- rc[3] contains returnCode
        end

        local function checkDatabase()
            if dz.utils.fileExists(path .. database) then
                if dz.utils.fileExists(sqlite) then
                    for _,check in ipairs (checks) do
                        local result,rc = osExecute(baseCommand,check)
                        if rc ~= 0 then 
                            return rc, result  
                        end
                    end
                else
                    return -1,"sqlite3 not installed"
                end
            else
                return -1,"wrong path to database"
            end
            return 0
        end

        local function updateAlert(rc)
            if alert and alert.active then
                local now = dz.time.rawDate .. ', ' .. dz.time.rawTime .. ': '
                local alertLevel = dz.ALERTLEVEL_RED
                if rc == 0 then  alertLevel = dz.ALERTLEVEL_GREEN end
                dz.devices(alert.device).updateAlertSensor(alertLevel, now .. rc2Text(rc))
            end
        end

        -- main program
        local rc, result = checkDatabase()
        if rc ~= 0 then
            logWrite(result,dz.LOG_ERROR)
            if email then dz.email(subject,result,emailaddress) end
            if notify then 
                dz.notify(subject, result or "Sprawdzanie bazy danych napotkało nieznany błąd", dz.PRIORITY_NORMAL, dz.SOUND_INTERMISSION,"",  myNotificationTable ) 
            end
            if afterFailCommand and ( rc > 0 ) then followUp(afterFailCommand) end
        else
            if afterSuccessCommand then followUp(afterSuccessCommand) end
        end
        updateAlert(rc) 
    end
}

 

Drugi skrypt sprawdza kondycję maliny na podstawie jej wewnętrznych czujników i co dwie minuty aktualizuje identyczny czujnik "Alert" . Jak coś się dzieje z maliną np napięcie zasilania jest za niskie, alert zmieni się na czerwono z odpowiednim opisem

W tym skrypcie wystarczy wpisać IDX utworzonego czujnika "ALERT" z dowolną nazwą np Kondycja Maliny.

return {
      on = { 
	        timer = { 'every 2 minutes' }
	  },        
         logging = {level =  domoticz.LOG_DEBUG, -- zmien na LOG_ERROR, jak skrypt będzie OK
              marker    =   "Kondycja RPI"
  },
    execute = function(dz, item )

    --Flag Bits
    local UNDERVOLTED=0x1
    local CAPPED=0x2
    local THROTTLED=0x4
    local SOFT_TEMPLIMIT=0x8
    local HAS_UNDERVOLTED=0x10000   -- 
    local HAS_CAPPED=0x20000
    local HAS_THROTTLED=0x40000
    local HAS_THROTTLED_RB=0x50000
    local UNDERVOLTED_THROTTLED=0x50005
    local HAS_SOFT_TEMPLIMIT=0x80000
    local Alertidx = 560 -- Tu wpisz IDX swojego czujnika "Alert"
    local function GetRpiSensor()
            local command = 'vcgencmd get_throttled'
            --dz.log(command,dz.LOG_INFO)
            local handle = assert(io.popen(command))
            for line in handle:lines() do
                findsensor=line
            end
            handle:close()
        return findsensor
       end
       
    -- Start main script   
    local RpiSensorvalue= GetRpiSensor()
    local splittedResult = dz.utils.stringSplit(RpiSensorvalue,'=')  -- split string into (table) parts with , as separator
    local RPIhex = tonumber(splittedResult[2])
    local AlertL = dz.ALERTLEVEL_GREEN
    local AlertT = ''
    
    if ( RPIhex > (HAS_SOFT_TEMPLIMIT-1) ) then
        RPIhex = RPIhex -HAS_SOFT_TEMPLIMIT
        AlertL = dz.ALERTLEVEL_RED
        AlertT = 'Rpi HAS Soft TempLimit'
    end
    if ( RPIhex > (UNDERVOLTED_THROTTLED-1) ) then
        RPIhex = RPIhex -UNDERVOLTED_THROTTLED
        AlertL = dz.ALERTLEVEL_RED
        AlertT = 'Rpi currently under-voltage and throttled'
    end
    
    if ( RPIhex > (HAS_THROTTLED_RB-1) ) then
        RPIhex = RPIhex -HAS_THROTTLED_RB
        AlertL = dz.ALERTLEVEL_RED
        AlertT = 'Rpi throttled occurred since last reboot'
    end
    if ( RPIhex > (HAS_THROTTLED-1) ) then
        RPIhex = RPIhex -HAS_THROTTLED
        AlertL = dz.ALERTLEVEL_RED
        AlertT = 'Rpi HAS Throttled'
    end
    if ( RPIhex > (HAS_CAPPED-1) ) then
        RPIhex = RPIhex -HAS_CAPPED
        AlertL = dz.ALERTLEVEL_RED
        AlertT = 'Rpi HAS Capped'
    end
        if ( RPIhex > (HAS_UNDERVOLTED-1) ) then
        RPIhex = RPIhex -HAS_UNDERVOLTED
        AlertL = dz.ALERTLEVEL_RED
        AlertT = 'Rpi HAS undervolted'
    end
    if ( RPIhex > (SOFT_TEMPLIMIT-1) ) then
        RPIhex = RPIhex -8
        AlertL = dz.ALERTLEVEL_RED
        AlertT = 'Rpi Soft Temp Limit'
    end
    if ( RPIhex > (THROTTLED-1) ) then
        RPIhex = RPIhex -4
        AlertL = dz.ALERTLEVEL_RED
        AlertT = AlertT .. ' Rpi Throttled'
    end
    if ( RPIhex > (CAPPED-1) ) then
        RPIhex = RPIhex -2
        AlertL = dz.ALERTLEVEL_RED
        AlertT = AlertT .. ' RPI Ograniczone'
    end    
    if ( RPIhex > (UNDERVOLTED-1) ) then
        AlertL = dz.ALERTLEVEL_RED
        AlertT = AlertT .. ' RPI za niskie napięcie'
    end
    
    if ( AlertT == '') then
        AlertT = 'RPI działa OK'
    end 
    -- Set the Alert Sensor
    dz.devices(Alertidx).updateAlertSensor(AlertL, AlertT)
   
    end
}

A tak wyglądają czujniki

3

 

 
Dodane : 02/09/2021 11:19 am
wojtek_gtx and adrian reacted
Udostępnij: