Earthquake info from KNMI

In this subforum you can show projects you have made, or you are busy with. Please create your own topic.

Moderator: leecollings

janpep
Posts: 241
Joined: Thursday 14 March 2024 10:11
Target OS: Linux
Domoticz version: 2024.7
Location: Netherlands
Contact:

Re: Earthquake info from KNMI

Post by janpep »

HvdW pointed out to me that Weerlive also offers the data that I obtain from Buienradar. So I could reduce the number of sources I use. I am currently working on realizing that. For my own use, I continue to obtain wind and air quality index parameters (for the Dutch local 'Stookwijzer') from one common source at Open Meteo. This because others do not provide current and forecast values per hour for pm10, pm2_5, nitrogen_dioxide and ozone. These are used to calculate the air quality index.
When it's done, I shall post the weerlive end result in a separate topic.
Domoticz in Ubuntu virtual machine on Synology DS718+ behind FRITZ!Box.
Using: EvoHome; MELCloud; P1 meter; Z-Stick GEN5; Z-Wave-js-ui; MQTT; Greenwave powernodes 1+6; Fibaro switch, plugs, smoke; FRITZ!DECT 200. Scripts listed in profile interests.
HvdW
Posts: 539
Joined: Sunday 01 November 2015 22:45
Target OS: Raspberry Pi / ODroid
Domoticz version: 2023.2
Location: Twente
Contact:

Re: Earthquake info from KNMI

Post by HvdW »

Nice addition, this eartquake thing.
aardbeving.jpg
aardbeving.jpg (17.88 KiB) Viewed 1007 times
Bugs bug me.
janpep
Posts: 241
Joined: Thursday 14 March 2024 10:11
Target OS: Linux
Domoticz version: 2024.7
Location: Netherlands
Contact:

Re: Earthquake info from KNMI

Post by janpep »

Update with some minor changes, including adding font color for better visibility of the hyperlinks.
BTW. The problem with interaction between scripts no longer occurred. It remains unclear to me what caused it and what solved it. So, as I always say: "Don't ask how it is done, but enjoy it." For now I consider it resolved.

Code: Select all

-- 07-05-2024 script by Jan Peppink, https://ict.peppink.nl
-- Based on earlier script found on https://www.domoticz.com/forum/viewtopic.php?t=41380
-- Missed Dutch earthquakes. Modified script to get info from KNMI Aardbevingen RSS.
-- Parse XML result to get info from the most recent of 30 in the list.
-- URL = https://cdn.knmi.nl/knmi/map/page/seismologie/GQuake_KNMI_RSS.xml
-- Function 'getUTCtimediffseconds' expected in global_data.
-- 09-05-2024 directly make use of dz.log instead of the 'logthis' function in global_data.
-- 10-05-2024 Again some adjustments to the log function.
-- 13-05-2024 Added font color for hyperlinks.

--- Your settings ----------------------------------------------------------------
-- First set the used device index numbers and variables you might want to change.
local alertIdx = n           -- Set to the idx of the Virtual Alert sensor you have to create for this script
local mailto = '[email protected]' -- Set E-mail adres to sent notification to.
local knmiURL = 'https://cdn.knmi.nl/knmi/map/page/seismologie/GQuake_KNMI_RSS.xml'

-- Define distance for ALERTLEVEL colors
-- From dClose to the maxRadius we get: ALERTLEVEL_GREY
local dClose = 300          -- From distance dCloser to dClose: ALERTLEVEL_YELLOW
local dCloser = 200         -- From distance dClosest to dCloser: ALERTLEVEL_ORANGE (+ eMail notification)
local dClosest = 100        -- From distance 0 to closest: ALERTLEVEL_RED (+ eMail notification)

return {
	on = {
		timer = { 
			'every 5 minutes',
        },
		httpResponses = {
            'knmi-rss'   -- matches callback string below
        }
	},
    logging = {
	    -- Level can be domoticz.LOG_INFO, domoicz.LOG_MODULE_EXEC_INFO, domoticz.LOG_DEBUG, domoticz.LOG_ERROR or domoticz.LOG_FORCE
        level = domoticz.LOG_INFO,
        --level = domoticz.LOG_DEBUG,
    	marker = 'KNMI-',
    },	
	execute = function(dz, triggeredItem)
        -- Set Local environment=================
        local _u = dz.utils       -- Holds subset of handy utilities.
        local _h = dz.helpers     -- Holds the global functions.
        local _d = dz.globalData  -- Holds the global data.

	    -- Set your loccation coordinates from Domoticz settings =================
		local yourLatitude = dz.settings.location.latitude
		local yourLongitude = dz.settings.location.longitude

        -- Use some color variables
        local cBlue = '#0000FF;'
        htmlColor = cBlue

        -- Set your alert device index to store the result.
        local alertLevel = dz.ALERTLEVEL_GREY -- Holds the alertLevel (color) to set
        local alertText = ''
		local lastalertText = dz.devices(alertIdx).text   -- Holds string of the previous round.

		local lTimediff = 0     -- Calculate diff in seconds between UTC and local time of this event.
		local delString = ""	-- Holds (sub) string to delete.

        -- Local Functions go here =============
		-- Calculate distance using Haversine formula
		local function calculateDistance(lat1, lon1, lat2, lon2)
		    local R = 6371 -- Earth radius in kilometers
		    local dLat = math.rad(lat2 - lat1)
			local dLon = math.rad(lon2 - lon1)
			local a = math.sin(dLat / 2) * math.sin(dLat / 2) + math.cos(math.rad(lat1)) * math.cos(math.rad(lat2)) * math.sin(dLon / 2) * math.sin(dLon / 2)
			local c = 2 * math.atan2(math.sqrt(a), math.sqrt(1 - a))
			local distance = R * c
			return distance
		end

        -- Now start to do something ============
		if (triggeredItem.isTimer) then
			dz.openURL({
			    url = knmiURL,
				method = 'GET',
				callback = 'knmi-rss'
			})	
		end
        
		if (triggeredItem.isHTTPResponse) then
            -- Process the obtained data.
			if (triggeredItem.ok and triggeredItem.isXML) then
			    -- We have something, which looks like this:
                --<rss xmlns:geo="http://www.w3.org/2003/01/geo/wgs84_pos#" xmlns:georss="http://www.georss.org/georss" version="2.0">
                --  <channel>
                --      <copyright>Copyright KNMI</copyright>
                --      <description>KNMI - de laatste 30 registraties van aardbevingen en andere seismo-akoestische bronnen in en rondom Nederland</description>
                --      <title>KNMI - de meest recente registraties van aardbevingen en andere seismo-akoestische bronnen in en rondom Nederland</title>
                --      <item>
                --          <title>2024-05-05, 't Zandt, M=0.3</title>
                --          <description>2024-05-05, 19:14:45, Lat = 53.357, Lon = 6.783, Diepte = 3.0 km, M = 0.3, Plaats = 't Zandt, Author = KNMI, Type = Geinduceerd, Analyse = Reviewed</description>
                --          <geo:lat>53.357</geo:lat>
                --          <geo:lon>6.783</geo:lon>
                --          <georss:point>53.357 6.783</georss:point>
                --          <link>http://www.knmi.nl/nederland-nu/seismologie/aardbevingen/knmi2024ivvz</link>
                --          <guid>knmi2024ivvz</guid>
                --      </item>
                local result_table = triggeredItem.xml
                if type( result_table ) == "table" then
                    dz.log( 'result_table: type = ' .. type(result_table), dz.LOG_DEBUG )
                    -- Get only the info from the first item.

                    -- Get link to page with details.
                    dz.log( result_table.rss.channel.item[1].link, dz.LOG_DEBUG )
                    local qUrl = tostring( triggeredItem.xml.rss.channel.item[1].link )

                    -- The complete description to split up. Put it in a table.
                    dz.log( result_table.rss.channel.item[1].description, dz.LOG_DEBUG )
                    local description_table = _u.stringSplit( result_table.rss.channel.item[1].description, ',' )

                    -- Get time (= UTC time) from the description_table.
                    -- Record 1 = 2024-05-05; Record 2 = 19:14:45 (strip the seconds)
                    local atUTCtime = description_table[1] .. ' ' .. string.sub( description_table[2], 2, 6 )
                    atUTCtime = dz.time.dateToDate( atUTCtime, 'yyyy-mm-dd hh:MM', 'dd-mm-yyyy hh:MM', 0 )
                    dz.log( 'atUTCtime = ' .. atUTCtime, dz.LOG_DEBUG )

                    -- Calculate the Local time.			    
                    local qUnixtime = dz.time.dateToTimestamp( atUTCtime, 'dd-mm-yyyy hh:MM' )
                    lTimediff = _h.getUTCtimediffseconds( qUnixtime )
                    local atLocalTime = dz.time.timestampToDate( qUnixtime, 'dd-mm-yyyy hh:MM', lTimediff )
                    dz.log( 'atLocalTime = ' .. atLocalTime, dz.LOG_DEBUG )

                    -- Record 3 = Lat = 53.357
                    delString = "Lat = "
                    local qLat = tostring(description_table[3]):gsub( delString, "" )
                    dz.log( 'qLat = ' .. qLat, dz.LOG_DEBUG )
			    
                    -- Record 4 = Lon = 6.783
                    delString = "Lon = "
                    local qLon = tostring(description_table[4]):gsub( delString, "" )
                    dz.log( 'qLon = ' .. qLon, dz.LOG_DEBUG )
			    
                    -- Record 5 = Diepte = 3.0 km
                    delString = "Diepte = "
                    local qDepth = tostring(description_table[5]):gsub( delString, "" )
                    dz.log( 'qDepth = ' .. qDepth, dz.LOG_DEBUG )
			    
                    -- Record 6 = M = 0.3
                    delString = "M = "
                    local qMag = tostring( description_table[6]):gsub( delString, "" )
                    dz.log( 'qMag = ' .. qMag, dz.LOG_DEBUG )
			    
                    -- Record 7 = Plaats = 't Zandt
                    delString = "Plaats = "
                    local qPlace = tostring(description_table[7]):gsub( delString, "" )
                    dz.log( 'qPlace = ' .. qPlace, dz.LOG_DEBUG )

                    -- Record 8 = Author = KNMI
                    local qAuthor = description_table[8]
                
                    -- Record 9 = Type = Geinduceerd
                    local qType = description_table[9]
                
                    -- Record 10 = Analyse = Reviewed

                    -- Calculate distance from home location.
                    local distance = calculateDistance( yourLatitude, yourLongitude, qLat, qLon )
                    -- Round the distance to the nearest kilometer
                    local roundedDistance = _u.round( distance, 0 )
				
                    --Set Alertlevel color based on distance.
                    if roundedDistance < dClosest then
                        alertLevel = dz.ALERTLEVEL_RED
                    elseif roundedDistance >= dClosest and roundedDistance < dCloser then
                        alertLevel = dz.ALERTLEVEL_ORANGE
                    elseif roundedDistance >= dCloser and roundedDistance < dClose then
                        alertLevel = dz.ALERTLEVEL_YELLOW
                    else
                        alertLevel = dz.ALERTLEVEL_GREY
                    end
                
                    --Set and format the new alertText
                    local alertText = tostring( atLocalTime .. ' uur in ' .. qPlace .. '\n' .. 'Magnitude: ' .. qMag .. '. Diepte: ' .. qDepth .. '. Afstand: ' .. roundedDistance ..' km.\n' .. '<a href="https://maps.google.com/?q=' .. qLat .. ',' .. qLon .. '" target="_blank"><span style="color: ' ..  htmlColor .. '">Toon locatie</span></a>' .. ' - ' .. '<a href="'  .. qUrl ..  '" target="_blank"><span style="color: ' ..  htmlColor .. '">Toon bron</span></a>' )

                    -- Only update and send mail when info has changed. and 
                    if alertText ~= lastalertText then
                        -- We have new information, so update the device.
                        dz.devices(alertIdx).updateAlertSensor(alertLevel, alertText)

                        -- Only send email when it comes closer then dCloser
                        if roundedDistance <= dCloser then
                            --Set and format the new mail message
                            local message = tostring('Plaats: ' .. qPlace .. '<br>' ..
                            'Magnitude: ' .. qMag .. '<br>' ..
                            'Diepte: ' .. qDepth .. '.<br>' ..
                            'Lokale Tijd: ' .. atLocalTime .. ' uur.<br>' ..
                            'UTC Tijd: ' .. atUTCtime .. ' uur.<br>' ..
                            'Afstand: ' .. roundedDistance .. 'km.<br>'..
                            'Coördinaten: ' .. qLat .. ','.. qLon .. '<br>' ..
                            qAuthor .. '<br>' ..
                            qType .. '<br>' ..
                            '<a href="https://maps.google.com/?q=' .. qLat .. ',' .. qLon .. '">Toon locatie</a>' .. '<br>' ..
                            '<a href="' .. qUrl .. '">Toon bron</a>' .. '<br>' )
                            -- Send the mail
                            dz.email( 'Aardbeving ' .. qPlace, message, mailto )
                        end
                    end
                else
                    dz.log( 'No result_table found', dz.LOG_ERROR )
                end
	        else
    			dz.log( 'Item or XML - NOT OK', dz.LOG_ERROR )
		    end
		end
	end
}
-- That's All --------------------------------------------------
Domoticz in Ubuntu virtual machine on Synology DS718+ behind FRITZ!Box.
Using: EvoHome; MELCloud; P1 meter; Z-Stick GEN5; Z-Wave-js-ui; MQTT; Greenwave powernodes 1+6; Fibaro switch, plugs, smoke; FRITZ!DECT 200. Scripts listed in profile interests.
janpep
Posts: 241
Joined: Thursday 14 March 2024 10:11
Target OS: Linux
Domoticz version: 2024.7
Location: Netherlands
Contact:

Re: Earthquake info from KNMI

Post by janpep »

Oops!
I discovered that the comparison with the last saved value does not work when using hex color. Clear example of not being tested long enough. This is now causing the mail to be sent every 5 minutes. Excuse me. I am working on it.
Domoticz in Ubuntu virtual machine on Synology DS718+ behind FRITZ!Box.
Using: EvoHome; MELCloud; P1 meter; Z-Stick GEN5; Z-Wave-js-ui; MQTT; Greenwave powernodes 1+6; Fibaro switch, plugs, smoke; FRITZ!DECT 200. Scripts listed in profile interests.
janpep
Posts: 241
Joined: Thursday 14 March 2024 10:11
Target OS: Linux
Domoticz version: 2024.7
Location: Netherlands
Contact:

Re: Earthquake info from KNMI

Post by janpep »

The issue is solved by using plain text 'Blue' instead of the hexadecimal color code '#0000FF;'.
It turned out this caused the problem when comparing last and new alert string, because of the semicolon, which is not escaped and ended the string.
Update of the device and sending of mail notification will again only take place when the content has changed.
Sorry for the inconvenience. This shoud be beter:

Code: Select all

-- 07-05-2024 script by Jan Peppink, https://ict.peppink.nl
-- Based on earlier script found on https://www.domoticz.com/forum/viewtopic.php?t=41380
-- Missed Dutch earthquakes. Modified script to get info from KNMI Aardbevingen RSS.
-- Parse XML result to get info from the most recent of 30 in the list.
-- URL = https://cdn.knmi.nl/knmi/map/page/seismologie/GQuake_KNMI_RSS.xml
-- Function 'getUTCtimediffseconds' expected in global_data.
-- 09-05-2024 directly make use of dz.log instead of the 'logthis' function in global_data.
-- 10-05-2024 Again some adjustments to the log function.
-- 13-05-2024 Added font color for hyperlinks.

--- Your settings ----------------------------------------------------------------
-- First set the used device index numbers and variables you might want to change.
local alertIdx = n           -- Set to the idx of the Virtual Alert sensor you have to create for this script
local mailto = '[email protected]' -- Set E-mail adres to sent notification to.
local knmiURL = 'https://cdn.knmi.nl/knmi/map/page/seismologie/GQuake_KNMI_RSS.xml'

-- Define distance for ALERTLEVEL colors
-- From dClose to the maxRadius we get: ALERTLEVEL_GREY
local dClose = 300          -- From distance dCloser to dClose: ALERTLEVEL_YELLOW
local dCloser = 200         -- From distance dClosest to dCloser: ALERTLEVEL_ORANGE (+ eMail notification)
local dClosest = 100        -- From distance 0 to closest: ALERTLEVEL_RED (+ eMail notification)

return {
	on = {
		timer = { 
			'every 5 minutes',
        },
		httpResponses = {
            'knmi-rss'   -- matches callback string below
        }
	},
    logging = {
	    -- Level can be domoticz.LOG_INFO, domoicz.LOG_MODULE_EXEC_INFO, domoticz.LOG_DEBUG, domoticz.LOG_ERROR or domoticz.LOG_FORCE
        level = domoticz.LOG_INFO,
        --level = domoticz.LOG_DEBUG,
    	marker = 'KNMI-',
    },	
	execute = function(dz, triggeredItem)
        -- Set Local environment=================
        local _u = dz.utils       -- Holds subset of handy utilities.
        local _h = dz.helpers     -- Holds the global functions.
        local _d = dz.globalData  -- Holds the global data.

	    -- Set your loccation coordinates from Domoticz settings =================
		local yourLatitude = dz.settings.location.latitude
		local yourLongitude = dz.settings.location.longitude

        -- Use color variable for hyperlink font color
        htmlColor = 'Blue'

        -- Set your alert device index to store the result.
        local alertLevel = dz.ALERTLEVEL_GREY -- Holds the alertLevel (color) to set
        local alertText = ''
		local lastalertText = dz.devices(alertIdx).text   -- Holds string of the previous round.
        
		local lTimediff = 0     -- Calculate diff in seconds between UTC and local time of this event.
		local delString = ""	-- Holds (sub) string to delete.

        -- Local Functions go here =============
		-- Calculate distance using Haversine formula
		local function calculateDistance(lat1, lon1, lat2, lon2)
		    local R = 6371 -- Earth radius in kilometers
		    local dLat = math.rad(lat2 - lat1)
			local dLon = math.rad(lon2 - lon1)
			local a = math.sin(dLat / 2) * math.sin(dLat / 2) + math.cos(math.rad(lat1)) * math.cos(math.rad(lat2)) * math.sin(dLon / 2) * math.sin(dLon / 2)
			local c = 2 * math.atan2(math.sqrt(a), math.sqrt(1 - a))
			local distance = R * c
			return distance
		end

        -- Now start to do something ============
		if (triggeredItem.isTimer) then
			dz.openURL({
			    url = knmiURL,
				method = 'GET',
				callback = 'knmi-rss'
			})	
		end
        
		if (triggeredItem.isHTTPResponse) then
            -- Process the obtained data.
			if (triggeredItem.ok and triggeredItem.isXML) then
			    -- We have something, which looks like this:
                --<rss xmlns:geo="http://www.w3.org/2003/01/geo/wgs84_pos#" xmlns:georss="http://www.georss.org/georss" version="2.0">
                --  <channel>
                --      <copyright>Copyright KNMI</copyright>
                --      <description>KNMI - de laatste 30 registraties van aardbevingen en andere seismo-akoestische bronnen in en rondom Nederland</description>
                --      <title>KNMI - de meest recente registraties van aardbevingen en andere seismo-akoestische bronnen in en rondom Nederland</title>
                --      <item>
                --          <title>2024-05-05, 't Zandt, M=0.3</title>
                --          <description>2024-05-05, 19:14:45, Lat = 53.357, Lon = 6.783, Diepte = 3.0 km, M = 0.3, Plaats = 't Zandt, Author = KNMI, Type = Geinduceerd, Analyse = Reviewed</description>
                --          <geo:lat>53.357</geo:lat>
                --          <geo:lon>6.783</geo:lon>
                --          <georss:point>53.357 6.783</georss:point>
                --          <link>http://www.knmi.nl/nederland-nu/seismologie/aardbevingen/knmi2024ivvz</link>
                --          <guid>knmi2024ivvz</guid>
                --      </item>
                local result_table = triggeredItem.xml
                if type( result_table ) == "table" then
                    dz.log( 'result_table: type = ' .. type(result_table), dz.LOG_DEBUG )
                    -- Get only the info from the first item.

                    -- Get link to page with details.
                    dz.log( result_table.rss.channel.item[1].link, dz.LOG_DEBUG )
                    local qUrl = tostring( triggeredItem.xml.rss.channel.item[1].link )

                    -- The complete description to split up. Put it in a table.
                    dz.log( result_table.rss.channel.item[1].description, dz.LOG_DEBUG )
                    local description_table = _u.stringSplit( result_table.rss.channel.item[1].description, ',' )

                    -- Get time (= UTC time) from the description_table.
                    -- Record 1 = 2024-05-05; Record 2 = 19:14:45 (strip the seconds)
                    local atUTCtime = description_table[1] .. ' ' .. string.sub( description_table[2], 2, 6 )
                    atUTCtime = dz.time.dateToDate( atUTCtime, 'yyyy-mm-dd hh:MM', 'dd-mm-yyyy hh:MM', 0 )
                    dz.log( 'atUTCtime = ' .. atUTCtime, dz.LOG_DEBUG )

                    -- Calculate the Local time.			    
                    local qUnixtime = dz.time.dateToTimestamp( atUTCtime, 'dd-mm-yyyy hh:MM' )
                    lTimediff = _h.getUTCtimediffseconds( qUnixtime )
                    local atLocalTime = dz.time.timestampToDate( qUnixtime, 'dd-mm-yyyy hh:MM', lTimediff )
                    dz.log( 'atLocalTime = ' .. atLocalTime, dz.LOG_DEBUG )

                    -- Record 3 = Lat = 53.357
                    delString = "Lat = "
                    local qLat = tostring(description_table[3]):gsub( delString, "" )
                    dz.log( 'qLat = ' .. qLat, dz.LOG_DEBUG )
			    
                    -- Record 4 = Lon = 6.783
                    delString = "Lon = "
                    local qLon = tostring(description_table[4]):gsub( delString, "" )
                    dz.log( 'qLon = ' .. qLon, dz.LOG_DEBUG )
			    
                    -- Record 5 = Diepte = 3.0 km
                    delString = "Diepte = "
                    local qDepth = tostring(description_table[5]):gsub( delString, "" )
                    dz.log( 'qDepth = ' .. qDepth, dz.LOG_DEBUG )
			    
                    -- Record 6 = M = 0.3
                    delString = "M = "
                    local qMag = tostring( description_table[6]):gsub( delString, "" )
                    dz.log( 'qMag = ' .. qMag, dz.LOG_DEBUG )
			    
                    -- Record 7 = Plaats = 't Zandt
                    delString = "Plaats = "
                    local qPlace = tostring(description_table[7]):gsub( delString, "" )
                    dz.log( 'qPlace = ' .. qPlace, dz.LOG_DEBUG )

                    -- Record 8 = Author = KNMI
                    local qAuthor = description_table[8]
                
                    -- Record 9 = Type = Geinduceerd
                    local qType = description_table[9]
                
                    -- Record 10 = Analyse = Reviewed

                    -- Calculate distance from home location.
                    local distance = calculateDistance( yourLatitude, yourLongitude, qLat, qLon )
                    -- Round the distance to the nearest kilometer
                    local roundedDistance = _u.round( distance, 0 )
				
                    --Set Alertlevel color based on distance.
                    if roundedDistance < dClosest then
                        alertLevel = dz.ALERTLEVEL_RED
                    elseif roundedDistance >= dClosest and roundedDistance < dCloser then
                        alertLevel = dz.ALERTLEVEL_ORANGE
                    elseif roundedDistance >= dCloser and roundedDistance < dClose then
                        alertLevel = dz.ALERTLEVEL_YELLOW
                    else
                        alertLevel = dz.ALERTLEVEL_GREY
                    end
                
                    --Set and format the new alertText
                    local alertText = tostring( atLocalTime .. ' uur in ' .. qPlace .. '\n' .. 'Magnitude: ' .. qMag .. '. Diepte: ' .. qDepth .. '. Afstand: ' .. roundedDistance ..' km.\n' .. '<a href="https://maps.google.com/?q=' .. qLat .. ',' .. qLon .. '" target="_blank"><span style="color: ' ..  htmlColor .. '">Toon locatie</span></a>' .. ' - ' .. '<a href="'  .. qUrl ..  '" target="_blank"><span style="color: ' ..  htmlColor .. '">Toon bron</span></a>' )
                    dz.log( 'LastalertText = ' .. lastalertText, dz.LOG_DEBUG )
                    dz.log( 'NewalertText = ' .. alertText, dz.LOG_DEBUG )
                    
                    -- Only update and send mail when info has changed. and 
                    if alertText ~= lastalertText then
                        -- We have new information, so update the device.
                        dz.devices(alertIdx).updateAlertSensor( alertLevel, alertText )

                        -- Only send email when it comes closer then dCloser
                        if roundedDistance <= dCloser then
                            --Set and format the new mail message
                            local message = tostring('Plaats: ' .. qPlace .. '<br>' ..
                            'Magnitude: ' .. qMag .. '<br>' ..
                            'Diepte: ' .. qDepth .. '.<br>' ..
                            'Lokale Tijd: ' .. atLocalTime .. ' uur.<br>' ..
                            'UTC Tijd: ' .. atUTCtime .. ' uur.<br>' ..
                            'Afstand: ' .. roundedDistance .. 'km.<br>' ..
                            'Coördinaten: ' .. qLat .. ','.. qLon .. '<br>' ..
                            qAuthor .. '<br>' ..
                            qType .. '<br>' ..
                            '<a href="https://maps.google.com/?q=' .. qLat .. ',' .. qLon .. '">Toon locatie</a>' .. '<br>' ..
                            '<a href="' .. qUrl .. '">Toon bron</a>' .. '<br>' )
                            -- Send the mail
                            dz.email( 'Aardbeving ' .. qPlace, message, mailto )
                        end
                    end
                else
                    dz.log( 'No result_table found', dz.LOG_ERROR )
                end
	        else
    			dz.log( 'Item or XML - NOT OK', dz.LOG_ERROR )
		    end
		end
	end
}
-- That's All --------------------------------------------------
Domoticz in Ubuntu virtual machine on Synology DS718+ behind FRITZ!Box.
Using: EvoHome; MELCloud; P1 meter; Z-Stick GEN5; Z-Wave-js-ui; MQTT; Greenwave powernodes 1+6; Fibaro switch, plugs, smoke; FRITZ!DECT 200. Scripts listed in profile interests.
User avatar
psubiaco
Posts: 205
Joined: Monday 20 August 2018 9:38
Target OS: Raspberry Pi / ODroid
Domoticz version: Beta
Location: Italy
Contact:

Re: Earthquake info from KNMI

Post by psubiaco »

post cancelled
Last edited by psubiaco on Monday 20 May 2024 7:48, edited 1 time in total.
Paolo
--
I use DomBus modules to charge EV car, get a full alarm system, control heat pump, fire alarm detection, lights and much more. Video
Facebook page - Youtube channel
janpep
Posts: 241
Joined: Thursday 14 March 2024 10:11
Target OS: Linux
Domoticz version: 2024.7
Location: Netherlands
Contact:

Re: Earthquake info from KNMI

Post by janpep »

psubiaco wrote: Saturday 18 May 2024 15:28 It gets info from seismicportal.eu <cut>
Please note that I have specially started this separate earthquake topic with the name "Eurthquake info from KNMI" !!
I did this to prevent confusion by mixing things up.
That is precisely why I have not posted my script information in the topic that already concerns the other source: seismicportal.eu
Please keep it there!
Domoticz in Ubuntu virtual machine on Synology DS718+ behind FRITZ!Box.
Using: EvoHome; MELCloud; P1 meter; Z-Stick GEN5; Z-Wave-js-ui; MQTT; Greenwave powernodes 1+6; Fibaro switch, plugs, smoke; FRITZ!DECT 200. Scripts listed in profile interests.
User avatar
psubiaco
Posts: 205
Joined: Monday 20 August 2018 9:38
Target OS: Raspberry Pi / ODroid
Domoticz version: Beta
Location: Italy
Contact:

Re: Earthquake info from KNMI

Post by psubiaco »

post cancelled
Paolo
--
I use DomBus modules to charge EV car, get a full alarm system, control heat pump, fire alarm detection, lights and much more. Video
Facebook page - Youtube channel
User avatar
waltervl
Posts: 5397
Joined: Monday 28 January 2019 18:48
Target OS: Linux
Domoticz version: 2024.7
Location: NL
Contact:

Re: Earthquake info from KNMI

Post by waltervl »

waltervl wrote: Wednesday 08 May 2024 16:01 You can set log level per logging line. eg

Code: Select all

dz.log('extra debug: Device 123 is ' .. myName, dz.LOG_DEBUG)  
From documentation:
domoticz.log(message, [level]): Function. Creates a logging entry in the Domoticz log but respects the log level settings. You can provide the loglevel: domoticz.LOG_INFO, domoticz.LOG_DEBUG, domoticz.LOG_ERROR or domoticz.LOG_FORCE. In Domoticz settings you can set the log level for dzVents.
See following topic for examples https://www.domoticz.com/forum/viewtopi ... 85#p279685
In latest Beta dVents logging has been simplified and more on line of normal logging. See for more info the already mentioned link and the new logging dzvents template.
Domoticz running on Udoo X86 (on Ubuntu)
Devices/plugins: ZigbeeforDomoticz (with Xiaomi, Ikea, Tuya devices), Nefit Easy, Midea Airco, Omnik Solar, Goodwe Solar
janpep
Posts: 241
Joined: Thursday 14 March 2024 10:11
Target OS: Linux
Domoticz version: 2024.7
Location: Netherlands
Contact:

Re: Earthquake info from KNMI

Post by janpep »

waltervl wrote: Friday 05 July 2024 22:45 In latest Beta dVents logging has been simplified and more on line of normal logging. See for more info the already mentioned link and the new logging dzvents template.
To be honest, I do not understand.
  • You quote your own contributiion of more than two month ago, while for me the "problem" was solved. So it's a bit like an answer to a question that was not asked.
  • You are referring to the latest beta version, which most people probably won't have. It seems correct to me to assume that people are running the latest stable version.
  • In the link you gave, there is also a post that refers to 'latest Beta 2024.4'. I run the stable 2024.4, so I expect that a latest beta should be beyond that number?
  • Then It is not clear to me WHAT has changed.
  • You refer to a template, which I do not see anywhere.
  • And finally: I already reported that the logging "problem" for me was solved after your first explanation ,for which I thank you.
Although this is actually off topic:
At the moment I have two "standard" lines in my scripts.

Code: Select all

--level = domoticz.LOG_INFO
--level = domoticz.LOG_DEBUG
- Sometimes both commented out to prevent unneeded logging.
- Sometimes only the INFO line commented out, to get some basic logging of start and end times.
- Sometimes only the DEBUG line commented out, to debug and see the lines in the script are as...

Code: Select all

dz.log('I want this to be logged when I am debugging', dz.LOG_DEBUG)  
That works perfectly for me. And when this might change in a future version, I will see and adapt to that when needed.
More of this in other (logging) topics please.
Domoticz in Ubuntu virtual machine on Synology DS718+ behind FRITZ!Box.
Using: EvoHome; MELCloud; P1 meter; Z-Stick GEN5; Z-Wave-js-ui; MQTT; Greenwave powernodes 1+6; Fibaro switch, plugs, smoke; FRITZ!DECT 200. Scripts listed in profile interests.
User avatar
waltervl
Posts: 5397
Joined: Monday 28 January 2019 18:48
Target OS: Linux
Domoticz version: 2024.7
Location: NL
Contact:

Re: Earthquake info from KNMI

Post by waltervl »

I just wanted you to inform you of the change in dzvents logging in latest Beta (and upcoming stable)..... Sorry for the misunderstanding. I thought you would appreciate it.
Domoticz running on Udoo X86 (on Ubuntu)
Devices/plugins: ZigbeeforDomoticz (with Xiaomi, Ikea, Tuya devices), Nefit Easy, Midea Airco, Omnik Solar, Goodwe Solar
janpep
Posts: 241
Joined: Thursday 14 March 2024 10:11
Target OS: Linux
Domoticz version: 2024.7
Location: Netherlands
Contact:

Re: Earthquake info from KNMI

Post by janpep »

waltervl wrote: Saturday 06 July 2024 12:46 I thought you would appreciate it.
That is appreciated, but I can not do anything with it right now.
Domoticz in Ubuntu virtual machine on Synology DS718+ behind FRITZ!Box.
Using: EvoHome; MELCloud; P1 meter; Z-Stick GEN5; Z-Wave-js-ui; MQTT; Greenwave powernodes 1+6; Fibaro switch, plugs, smoke; FRITZ!DECT 200. Scripts listed in profile interests.
User avatar
waltervl
Posts: 5397
Joined: Monday 28 January 2019 18:48
Target OS: Linux
Domoticz version: 2024.7
Location: NL
Contact:

Re: Earthquake info from KNMI

Post by waltervl »

I think very soon you can as I feel a new stable is close by.
Domoticz running on Udoo X86 (on Ubuntu)
Devices/plugins: ZigbeeforDomoticz (with Xiaomi, Ikea, Tuya devices), Nefit Easy, Midea Airco, Omnik Solar, Goodwe Solar
Fredom
Posts: 140
Joined: Saturday 19 September 2020 21:02
Target OS: Raspberry Pi / ODroid
Domoticz version: 2022.2
Location: Krimpen aan den IJssel
Contact:

Re: Earthquake info from KNMI

Post by Fredom »

Hi,
Great script and very useful.
Unfortunately I get an error message that I cannot resolve.

Code: Select all

-- 07-05-2024 script by Jan Peppink, https://ict.peppink.nl
-- Based on earlier script found on https://www.domoticz.com/forum/viewtopic.php?t=41380
-- Missed Dutch earthquakes. Modified script to get info from KNMI Aardbevingen RSS.
-- Parse XML result to get info from the most recent of 30 in the list.
-- URL = https://cdn.knmi.nl/knmi/map/page/seismologie/GQuake_KNMI_RSS.xml
-- Function 'getUTCtimediffseconds' expected in global_data.
-- 09-05-2024 directly make use of dz.log instead of the 'logthis' function in global_data.
-- 10-05-2024 Again some adjustments to the log function.
-- 13-05-2024 Added font color for hyperlinks.

--- Your settings ----------------------------------------------------------------
-- First set the used device index numbers and variables you might want to change.
local alertIdx = 133           -- Set to the idx of the Virtual Alert sensor you have to create for this script
local mailto = 'XXXXXX.com' -- Set E-mail adres to sent notification to.
local knmiURL = 'https://cdn.knmi.nl/knmi/map/page/seismologie/GQuake_KNMI_RSS.xml'

-- Define distance for ALERTLEVEL colors
-- From dClose to the maxRadius we get: ALERTLEVEL_GREY
local dClose = 300          -- From distance dCloser to dClose: ALERTLEVEL_YELLOW
local dCloser = 200         -- From distance dClosest to dCloser: ALERTLEVEL_ORANGE (+ eMail notification)
local dClosest = 100        -- From distance 0 to closest: ALERTLEVEL_RED (+ eMail notification)

return {
	on = {
		timer = { 
			'every 5 minutes',
        },
		httpResponses = {
            'knmi-rss'   -- matches callback string below
        }
	},
    logging = {
	    -- Level can be domoticz.LOG_INFO, domoicz.LOG_MODULE_EXEC_INFO, domoticz.LOG_DEBUG, domoticz.LOG_ERROR or domoticz.LOG_FORCE
        level = domoticz.LOG_INFO,
        --level = domoticz.LOG_DEBUG,
    	marker = 'KNMI-',
    },	
	execute = function(dz, triggeredItem)
        -- Set Local environment=================
        local _u = dz.utils       -- Holds subset of handy utilities.
        local _h = dz.helpers     -- Holds the global functions.
        local _d = dz.globalData  -- Holds the global data.

	    -- Set your loccation coordinates from Domoticz settings =================
		local yourLatitude = dz.settings.location.latitude
		local yourLongitude = dz.settings.location.longitude

        -- Use color variable for hyperlink font color
        htmlColor = 'Blue'

        -- Set your alert device index to store the result.
        local alertLevel = dz.ALERTLEVEL_GREY -- Holds the alertLevel (color) to set
        local alertText = ''
		local lastalertText = dz.devices(alertIdx).text   -- Holds string of the previous round.
        
		local lTimediff = 0     -- Calculate diff in seconds between UTC and local time of this event.
		local delString = ""	-- Holds (sub) string to delete.

        -- Local Functions go here =============
		-- Calculate distance using Haversine formula
		local function calculateDistance(lat1, lon1, lat2, lon2)
		    local R = 6371 -- Earth radius in kilometers
		    local dLat = math.rad(lat2 - lat1)
			local dLon = math.rad(lon2 - lon1)
			local a = math.sin(dLat / 2) * math.sin(dLat / 2) + math.cos(math.rad(lat1)) * math.cos(math.rad(lat2)) * math.sin(dLon / 2) * math.sin(dLon / 2)
			local c = 2 * math.atan2(math.sqrt(a), math.sqrt(1 - a))
			local distance = R * c
			return distance
		end

        -- Now start to do something ============
		if (triggeredItem.isTimer) then
			dz.openURL({
			    url = knmiURL,
				method = 'GET',
				callback = 'knmi-rss'
			})	
		end
        
		if (triggeredItem.isHTTPResponse) then
            -- Process the obtained data.
			if (triggeredItem.ok and triggeredItem.isXML) then
			    -- We have something, which looks like this:
                --<rss xmlns:geo="http://www.w3.org/2003/01/geo/wgs84_pos#" xmlns:georss="http://www.georss.org/georss" version="2.0">
                --  <channel>
                --      <copyright>Copyright KNMI</copyright>
                --      <description>KNMI - de laatste 30 registraties van aardbevingen en andere seismo-akoestische bronnen in en rondom Nederland</description>
                --      <title>KNMI - de meest recente registraties van aardbevingen en andere seismo-akoestische bronnen in en rondom Nederland</title>
                --      <item>
                --          <title>2024-05-05, 't Zandt, M=0.3</title>
                --          <description>2024-05-05, 19:14:45, Lat = 53.357, Lon = 6.783, Diepte = 3.0 km, M = 0.3, Plaats = 't Zandt, Author = KNMI, Type = Geinduceerd, Analyse = Reviewed</description>
                --          <geo:lat>53.357</geo:lat>
                --          <geo:lon>6.783</geo:lon>
                --          <georss:point>53.357 6.783</georss:point>
                --          <link>http://www.knmi.nl/nederland-nu/seismologie/aardbevingen/knmi2024ivvz</link>
                --          <guid>knmi2024ivvz</guid>
                --      </item>
                local result_table = triggeredItem.xml
                if type( result_table ) == "table" then
                    dz.log( 'result_table: type = ' .. type(result_table), dz.LOG_DEBUG )
                    -- Get only the info from the first item.

                    -- Get link to page with details.
                    dz.log( result_table.rss.channel.item[1].link, dz.LOG_DEBUG )
                    local qUrl = tostring( triggeredItem.xml.rss.channel.item[1].link )

                    -- The complete description to split up. Put it in a table.
                    dz.log( result_table.rss.channel.item[1].description, dz.LOG_DEBUG )
                    local description_table = _u.stringSplit( result_table.rss.channel.item[1].description, ',' )

                    -- Get time (= UTC time) from the description_table.
                    -- Record 1 = 2024-05-05; Record 2 = 19:14:45 (strip the seconds)
                    local atUTCtime = description_table[1] .. ' ' .. string.sub( description_table[2], 2, 6 )
                    atUTCtime = dz.time.dateToDate( atUTCtime, 'yyyy-mm-dd hh:MM', 'dd-mm-yyyy hh:MM', 0 )
                    dz.log( 'atUTCtime = ' .. atUTCtime, dz.LOG_DEBUG )

                    -- Calculate the Local time.			    
                    local qUnixtime = dz.time.dateToTimestamp( atUTCtime, 'dd-mm-yyyy hh:MM' )
                    lTimediff = _h.getUTCtimediffseconds( qUnixtime )
                    local atLocalTime = dz.time.timestampToDate( qUnixtime, 'dd-mm-yyyy hh:MM', lTimediff )
                    dz.log( 'atLocalTime = ' .. atLocalTime, dz.LOG_DEBUG )

                    -- Record 3 = Lat = 53.357
                    delString = "Lat = "
                    local qLat = tostring(description_table[3]):gsub( delString, "" )
                    dz.log( 'qLat = ' .. qLat, dz.LOG_DEBUG )
			    
                    -- Record 4 = Lon = 6.783
                    delString = "Lon = "
                    local qLon = tostring(description_table[4]):gsub( delString, "" )
                    dz.log( 'qLon = ' .. qLon, dz.LOG_DEBUG )
			    
                    -- Record 5 = Diepte = 3.0 km
                    delString = "Diepte = "
                    local qDepth = tostring(description_table[5]):gsub( delString, "" )
                    dz.log( 'qDepth = ' .. qDepth, dz.LOG_DEBUG )
			    
                    -- Record 6 = M = 0.3
                    delString = "M = "
                    local qMag = tostring( description_table[6]):gsub( delString, "" )
                    dz.log( 'qMag = ' .. qMag, dz.LOG_DEBUG )
			    
                    -- Record 7 = Plaats = 't Zandt
                    delString = "Plaats = "
                    local qPlace = tostring(description_table[7]):gsub( delString, "" )
                    dz.log( 'qPlace = ' .. qPlace, dz.LOG_DEBUG )

                    -- Record 8 = Author = KNMI
                    local qAuthor = description_table[8]
                
                    -- Record 9 = Type = Geinduceerd
                    local qType = description_table[9]
                
                    -- Record 10 = Analyse = Reviewed

                    -- Calculate distance from home location.
                    local distance = calculateDistance( yourLatitude, yourLongitude, qLat, qLon )
                    -- Round the distance to the nearest kilometer
                    local roundedDistance = _u.round( distance, 0 )
				
                    --Set Alertlevel color based on distance.
                    if roundedDistance < dClosest then
                        alertLevel = dz.ALERTLEVEL_RED
                    elseif roundedDistance >= dClosest and roundedDistance < dCloser then
                        alertLevel = dz.ALERTLEVEL_ORANGE
                    elseif roundedDistance >= dCloser and roundedDistance < dClose then
                        alertLevel = dz.ALERTLEVEL_YELLOW
                    else
                        alertLevel = dz.ALERTLEVEL_GREY
                    end
                
                    --Set and format the new alertText
                    local alertText = tostring( atLocalTime .. ' uur in ' .. qPlace .. '\n' .. 'Magnitude: ' .. qMag .. '. Diepte: ' .. qDepth .. '. Afstand: ' .. roundedDistance ..' km.\n' .. '<a href="https://maps.google.com/?q=' .. qLat .. ',' .. qLon .. '" target="_blank"><span style="color: ' ..  htmlColor .. '">Toon locatie</span></a>' .. ' - ' .. '<a href="'  .. qUrl ..  '" target="_blank"><span style="color: ' ..  htmlColor .. '">Toon bron</span></a>' )
                    dz.log( 'LastalertText = ' .. lastalertText, dz.LOG_DEBUG )
                    dz.log( 'NewalertText = ' .. alertText, dz.LOG_DEBUG )
                    
                    -- Only update and send mail when info has changed. and 
                    if alertText ~= lastalertText then
                        -- We have new information, so update the device.
                        dz.devices(alertIdx).updateAlertSensor( alertLevel, alertText )

                        -- Only send email when it comes closer then dCloser
                        if roundedDistance <= dCloser then
                            --Set and format the new mail message
                            local message = tostring('Plaats: ' .. qPlace .. '<br>' ..
                            'Magnitude: ' .. qMag .. '<br>' ..
                            'Diepte: ' .. qDepth .. '.<br>' ..
                            'Lokale Tijd: ' .. atLocalTime .. ' uur.<br>' ..
                            'UTC Tijd: ' .. atUTCtime .. ' uur.<br>' ..
                            'Afstand: ' .. roundedDistance .. 'km.<br>' ..
                            'Coördinaten: ' .. qLat .. ','.. qLon .. '<br>' ..
                            qAuthor .. '<br>' ..
                            qType .. '<br>' ..
                            '<a href="https://maps.google.com/?q=' .. qLat .. ',' .. qLon .. '">Toon locatie</a>' .. '<br>' ..
                            '<a href="' .. qUrl .. '">Toon bron</a>' .. '<br>' )
                            -- Send the mail
                            dz.email( 'Aardbeving ' .. qPlace, message, mailto )
                        end
                    end
                else
                    dz.log( 'No result_table found', dz.LOG_ERROR )
                end
	        else
    			dz.log( 'Item or XML - NOT OK', dz.LOG_ERROR )
		    end
		end
	end
}

Error

Code: Select all

2024-07-06 13:20:01.217 Error: dzVents: Error: (3.1.8) KNMI-: An error occurred when calling event handler Aardbevingen
2024-07-06 13:20:01.217 Error: dzVents: Error: (3.1.8) KNMI-: ...oticz/scripts/dzVents/generated_scripts/Aardbevingen.lua:119: attempt to index a nil value (local '_h')
2024-07-06 13:25:01.435 Error: dzVents: Error: (3.1.8) KNMI-: An error occurred when calling event handler Aardbevingen
2024-07-06 13:25:01.435 Error: dzVents: Error: (3.1.8) KNMI-: ...oticz/scripts/dzVents/generated_scripts/Aardbevingen.lua:119: attempt to index a nil value (local '_h') 
-- That's All --------------------------------------------------
Yours sincerely,
Fred

Rasberry Pi 3B+ - Debian Buster - Domoticz 2022.2
RFLink - RFXCom - Zigbee (CC2531)
P1 Smart Meter - KaKu
janpep
Posts: 241
Joined: Thursday 14 March 2024 10:11
Target OS: Linux
Domoticz version: 2024.7
Location: Netherlands
Contact:

Re: Earthquake info from KNMI

Post by janpep »

As explained earlier, the script expects some items in the global_data script.
That is the the global-place used for functions and persistent variables so that they can be used from several scripts. So it functions as a 'central place'.

So 'local _h' points to: dz.helpers which holds the global functions.

For explanation see: DzVents Wiki page

Place the next functions that are used in the helper section of the global_data script. Create one if it does not exist yet.

Code: Select all

	-- Global helper functions
	helpers = {
		------------------------
		-- Used in t-Alarmeringen, t-Earthquake-KNMI,
	   getUTCtimediffseconds = function(qUnixtime)
			local timezone = os.date('%z', qUnixtime)   -- "+0200"
			local signum, hours, minutes = timezone:match '([+-])(%d%d)(%d%d)'
			local lTimediff = (tonumber(signum..hours)*3600 + tonumber(signum..minutes)*60)		   
			return lTimediff
		end,
		------------------------
		-- Used in t-Earthquake-KNMI, t-Airplanes,
		calculateDistance = function( lat1, lon1, lat2, lon2)
			-- Calculate distance using Haversine formula
			local R = 6371 -- Earth radius in kilometers
			local dLat = math.rad(lat2 - lat1)
			local dLon = math.rad(lon2 - lon1)
			local a = math.sin(dLat / 2) * math.sin(dLat / 2) + math.cos(math.rad(lat1)) * math.cos(math.rad(lat2)) * math.sin(dLon / 2) * math.sin(dLon / 2)
			local c = 2 * math.atan2(math.sqrt(a), math.sqrt(1 - a))
			local distance = R * c
			return distance
		end,
		------------------------
	}
Hope this helps.
Domoticz in Ubuntu virtual machine on Synology DS718+ behind FRITZ!Box.
Using: EvoHome; MELCloud; P1 meter; Z-Stick GEN5; Z-Wave-js-ui; MQTT; Greenwave powernodes 1+6; Fibaro switch, plugs, smoke; FRITZ!DECT 200. Scripts listed in profile interests.
Kedi
Posts: 564
Joined: Monday 20 March 2023 14:41
Target OS: Raspberry Pi / ODroid
Domoticz version:
Location: Somewhere in NL
Contact:

Re: Earthquake info from KNMI

Post by Kedi »

Instead of using;

Code: Select all

math.sin(dLat / 2) * math.sin(dLat / 2)
you can use

Code: Select all

math.sin(dLat / 2)^2
Logic will get you from A to B. Imagination will take you everywhere.
janpep
Posts: 241
Joined: Thursday 14 March 2024 10:11
Target OS: Linux
Domoticz version: 2024.7
Location: Netherlands
Contact:

Re: Earthquake info from KNMI

Post by janpep »

Kedi wrote: Saturday 06 July 2024 16:00 you can use
I am not a mathematician and have just taken the calculation from the mentioned topic https://www.domoticz.com/forum/viewtopic.php?t=41380. And it works.
What is the difference in outcome? To me it looks like it will be the same :-)
Or do you think it will save a lot of time?
Domoticz in Ubuntu virtual machine on Synology DS718+ behind FRITZ!Box.
Using: EvoHome; MELCloud; P1 meter; Z-Stick GEN5; Z-Wave-js-ui; MQTT; Greenwave powernodes 1+6; Fibaro switch, plugs, smoke; FRITZ!DECT 200. Scripts listed in profile interests.
Kedi
Posts: 564
Joined: Monday 20 March 2023 14:41
Target OS: Raspberry Pi / ODroid
Domoticz version:
Location: Somewhere in NL
Contact:

Re: Earthquake info from KNMI

Post by Kedi »

It is more readable/shorter. The opposite of sqrt.
Ofcourse there is no difference in outcome.
But it is your party.... and I wrote 'can'
Logic will get you from A to B. Imagination will take you everywhere.
janpep
Posts: 241
Joined: Thursday 14 March 2024 10:11
Target OS: Linux
Domoticz version: 2024.7
Location: Netherlands
Contact:

Re: Earthquake info from KNMI

Post by janpep »

Here I prefer 'easier for everyone to understand' than 'shorter'.
Domoticz in Ubuntu virtual machine on Synology DS718+ behind FRITZ!Box.
Using: EvoHome; MELCloud; P1 meter; Z-Stick GEN5; Z-Wave-js-ui; MQTT; Greenwave powernodes 1+6; Fibaro switch, plugs, smoke; FRITZ!DECT 200. Scripts listed in profile interests.
Fredom
Posts: 140
Joined: Saturday 19 September 2020 21:02
Target OS: Raspberry Pi / ODroid
Domoticz version: 2022.2
Location: Krimpen aan den IJssel
Contact:

Re: Earthquake info from KNMI

Post by Fredom »

Hi,
I did as you suggested,
I added the function. Unfortunately still the same error message. I am not a programmer, so this is beyond my knowledge.

Code: Select all

-- 07-05-2024 script by Jan Peppink, https://ict.peppink.nl
-- Based on earlier script found on https://www.domoticz.com/forum/viewtopic.php?t=41380
-- Missed Dutch earthquakes. Modified script to get info from KNMI Aardbevingen RSS.
-- Parse XML result to get info from the most recent of 30 in the list.
-- URL = https://cdn.knmi.nl/knmi/map/page/seismologie/GQuake_KNMI_RSS.xml
-- Function 'getUTCtimediffseconds' expected in global_data.
-- 09-05-2024 directly make use of dz.log instead of the 'logthis' function in global_data.
-- 10-05-2024 Again some adjustments to the log function.
-- 13-05-2024 Added font color for hyperlinks.

--- Your settings ----------------------------------------------------------------
-- First set the used device index numbers and variables you might want to change.
local alertIdx = 133           -- Set to the idx of the Virtual Alert sensor you have to create for this script
local mailto = 'XXXXXXXX.com' -- Set E-mail adres to sent notification to.
local knmiURL = 'https://cdn.knmi.nl/knmi/map/page/seismologie/GQuake_KNMI_RSS.xml'

-- Define distance for ALERTLEVEL colors
-- From dClose to the maxRadius we get: ALERTLEVEL_GREY
local dClose = 300          -- From distance dCloser to dClose: ALERTLEVEL_YELLOW
local dCloser = 200         -- From distance dClosest to dCloser: ALERTLEVEL_ORANGE (+ eMail notification)
local dClosest = 100        -- From distance 0 to closest: ALERTLEVEL_RED (+ eMail notification)

return {
	on = {
		timer = { 
			'every 5 minutes',
        },
		httpResponses = {
            'knmi-rss'   -- matches callback string below
        }
	},
    logging = {
	    -- Level can be domoticz.LOG_INFO, domoicz.LOG_MODULE_EXEC_INFO, domoticz.LOG_DEBUG, domoticz.LOG_ERROR or domoticz.LOG_FORCE
        level = domoticz.LOG_INFO,
        --level = domoticz.LOG_DEBUG,
    	marker = 'KNMI-',
    },	
	execute = function(dz, triggeredItem)
        -- Set Local environment=================
        local _u = dz.utils       -- Holds subset of handy utilities.
        local _h = dz.helpers     -- Holds the global functions.
        local _d = dz.globalData  -- Holds the global data.

	    -- Set your loccation coordinates from Domoticz settings =================
		local yourLatitude = dz.settings.location.latitude
		local yourLongitude = dz.settings.location.longitude

        -- Use color variable for hyperlink font color
        htmlColor = 'Blue'

        -- Set your alert device index to store the result.
        local alertLevel = dz.ALERTLEVEL_GREY -- Holds the alertLevel (color) to set
        local alertText = ''
		local lastalertText = dz.devices(alertIdx).text   -- Holds string of the previous round.
        
		local lTimediff = 0     -- Calculate diff in seconds between UTC and local time of this event.
		local delString = ""	-- Holds (sub) string to delete.

         -- Local Functions go here =============
		-- Calculate distance using Haversine formula
--		local function calculateDistance(lat1, lon1, lat2, lon2)
--		    local R = 6371 -- Earth radius in kilometers
--		    local dLat = math.rad(lat2 - lat1)
--			local dLon = math.rad(lon2 - lon1)
--			local a = math.sin(dLat / 2) * math.sin(dLat / 2) + math.cos(math.rad(lat1)) * math.cos(math.rad(lat2)) * math.sin(dLon / 2) * math.sin(dLon / 2)
--			local c = 2 * math.atan2(math.sqrt(a), math.sqrt(1 - a))-
--			local distance = R * c
--			return distance
--		end
	-- Global helper functions
	helpers = {
		------------------------
		-- Used in t-Alarmeringen, t-Earthquake-KNMI,
	   getUTCtimediffseconds = function(qUnixtime)
			local timezone = os.date('%z', qUnixtime)   -- "+0200"
			local signum, hours, minutes = timezone:match '([+-])(%d%d)(%d%d)'
			local lTimediff = (tonumber(signum..hours)*3600 + tonumber(signum..minutes)*60)		   
			return lTimediff
		end,
		------------------------
		-- Used in t-Earthquake-KNMI, t-Airplanes,
		calculateDistance = function( lat1, lon1, lat2, lon2)
			-- Calculate distance using Haversine formula
			local R = 6371 -- Earth radius in kilometers
			local dLat = math.rad(lat2 - lat1)
			local dLon = math.rad(lon2 - lon1)
			local a = math.sin(dLat / 2) * math.sin(dLat / 2) + math.cos(math.rad(lat1)) * math.cos(math.rad(lat2)) * math.sin(dLon / 2) * math.sin(dLon / 2)
			local c = 2 * math.atan2(math.sqrt(a), math.sqrt(1 - a))
			local distance = R * c
			return distance
		end,
		------------------------
	}

  

        -- Now start to do something ============
		if (triggeredItem.isTimer) then
			dz.openURL({
			    url = knmiURL,
				method = 'GET',
				callback = 'knmi-rss'
			})	
		end
        
		if (triggeredItem.isHTTPResponse) then
            -- Process the obtained data.
			if (triggeredItem.ok and triggeredItem.isXML) then
			    -- We have something, which looks like this:
                --<rss xmlns:geo="http://www.w3.org/2003/01/geo/wgs84_pos#" xmlns:georss="http://www.georss.org/georss" version="2.0">
                --  <channel>
                --      <copyright>Copyright KNMI</copyright>
                --      <description>KNMI - de laatste 30 registraties van aardbevingen en andere seismo-akoestische bronnen in en rondom Nederland</description>
                --      <title>KNMI - de meest recente registraties van aardbevingen en andere seismo-akoestische bronnen in en rondom Nederland</title>
                --      <item>
                --          <title>2024-05-05, 't Zandt, M=0.3</title>
                --          <description>2024-05-05, 19:14:45, Lat = 53.357, Lon = 6.783, Diepte = 3.0 km, M = 0.3, Plaats = 't Zandt, Author = KNMI, Type = Geinduceerd, Analyse = Reviewed</description>
                --          <geo:lat>53.357</geo:lat>
                --          <geo:lon>6.783</geo:lon>
                --          <georss:point>53.357 6.783</georss:point>
                --          <link>http://www.knmi.nl/nederland-nu/seismologie/aardbevingen/knmi2024ivvz</link>
                --          <guid>knmi2024ivvz</guid>
                --      </item>
                local result_table = triggeredItem.xml
                if type( result_table ) == "table" then
                    dz.log( 'result_table: type = ' .. type(result_table), dz.LOG_DEBUG )
                    -- Get only the info from the first item.

                    -- Get link to page with details.
                    dz.log( result_table.rss.channel.item[1].link, dz.LOG_DEBUG )
                    local qUrl = tostring( triggeredItem.xml.rss.channel.item[1].link )

                    -- The complete description to split up. Put it in a table.
                    dz.log( result_table.rss.channel.item[1].description, dz.LOG_DEBUG )
                    local description_table = _u.stringSplit( result_table.rss.channel.item[1].description, ',' )

                    -- Get time (= UTC time) from the description_table.
                    -- Record 1 = 2024-05-05; Record 2 = 19:14:45 (strip the seconds)
                    local atUTCtime = description_table[1] .. ' ' .. string.sub( description_table[2], 2, 6 )
                    atUTCtime = dz.time.dateToDate( atUTCtime, 'yyyy-mm-dd hh:MM', 'dd-mm-yyyy hh:MM', 0 )
                    dz.log( 'atUTCtime = ' .. atUTCtime, dz.LOG_DEBUG )

                    -- Calculate the Local time.			    
                    local qUnixtime = dz.time.dateToTimestamp( atUTCtime, 'dd-mm-yyyy hh:MM' )
                    lTimediff = _h.getUTCtimediffseconds( qUnixtime )
                    local atLocalTime = dz.time.timestampToDate( qUnixtime, 'dd-mm-yyyy hh:MM', lTimediff )
                    dz.log( 'atLocalTime = ' .. atLocalTime, dz.LOG_DEBUG )

                    -- Record 3 = Lat = 53.357
                    delString = "Lat = "
                    local qLat = tostring(description_table[3]):gsub( delString, "" )
                    dz.log( 'qLat = ' .. qLat, dz.LOG_DEBUG )
			    
                    -- Record 4 = Lon = 6.783
                    delString = "Lon = "
                    local qLon = tostring(description_table[4]):gsub( delString, "" )
                    dz.log( 'qLon = ' .. qLon, dz.LOG_DEBUG )
			    
                    -- Record 5 = Diepte = 3.0 km
                    delString = "Diepte = "
                    local qDepth = tostring(description_table[5]):gsub( delString, "" )
                    dz.log( 'qDepth = ' .. qDepth, dz.LOG_DEBUG )
			    
                    -- Record 6 = M = 0.3
                    delString = "M = "
                    local qMag = tostring( description_table[6]):gsub( delString, "" )
                    dz.log( 'qMag = ' .. qMag, dz.LOG_DEBUG )
			    
                    -- Record 7 = Plaats = 't Zandt
                    delString = "Plaats = "
                    local qPlace = tostring(description_table[7]):gsub( delString, "" )
                    dz.log( 'qPlace = ' .. qPlace, dz.LOG_DEBUG )

                    -- Record 8 = Author = KNMI
                    local qAuthor = description_table[8]
                
                    -- Record 9 = Type = Geinduceerd
                    local qType = description_table[9]
                
                    -- Record 10 = Analyse = Reviewed

                    -- Calculate distance from home location.
                    local distance = calculateDistance( yourLatitude, yourLongitude, qLat, qLon )
                    -- Round the distance to the nearest kilometer
                    local roundedDistance = _u.round( distance, 0 )
				
                    --Set Alertlevel color based on distance.
                    if roundedDistance < dClosest then
                        alertLevel = dz.ALERTLEVEL_RED
                    elseif roundedDistance >= dClosest and roundedDistance < dCloser then
                        alertLevel = dz.ALERTLEVEL_ORANGE
                    elseif roundedDistance >= dCloser and roundedDistance < dClose then
                        alertLevel = dz.ALERTLEVEL_YELLOW
                    else
                        alertLevel = dz.ALERTLEVEL_GREY
                    end
                
                    --Set and format the new alertText
                    local alertText = tostring( atLocalTime .. ' uur in ' .. qPlace .. '\n' .. 'Magnitude: ' .. qMag .. '. Diepte: ' .. qDepth .. '. Afstand: ' .. roundedDistance ..' km.\n' .. '<a href="https://maps.google.com/?q=' .. qLat .. ',' .. qLon .. '" target="_blank"><span style="color: ' ..  htmlColor .. '">Toon locatie</span></a>' .. ' - ' .. '<a href="'  .. qUrl ..  '" target="_blank"><span style="color: ' ..  htmlColor .. '">Toon bron</span></a>' )
                    dz.log( 'LastalertText = ' .. lastalertText, dz.LOG_DEBUG )
                    dz.log( 'NewalertText = ' .. alertText, dz.LOG_DEBUG )
                    
                    -- Only update and send mail when info has changed. and 
                    if alertText ~= lastalertText then
                        -- We have new information, so update the device.
                        dz.devices(alertIdx).updateAlertSensor( alertLevel, alertText )

                        -- Only send email when it comes closer then dCloser
                        if roundedDistance <= dCloser then
                            --Set and format the new mail message
                            local message = tostring('Plaats: ' .. qPlace .. '<br>' ..
                            'Magnitude: ' .. qMag .. '<br>' ..
                            'Diepte: ' .. qDepth .. '.<br>' ..
                            'Lokale Tijd: ' .. atLocalTime .. ' uur.<br>' ..
                            'UTC Tijd: ' .. atUTCtime .. ' uur.<br>' ..
                            'Afstand: ' .. roundedDistance .. 'km.<br>' ..
                            'Coördinaten: ' .. qLat .. ','.. qLon .. '<br>' ..
                            qAuthor .. '<br>' ..
                            qType .. '<br>' ..
                            '<a href="https://maps.google.com/?q=' .. qLat .. ',' .. qLon .. '">Toon locatie</a>' .. '<br>' ..
                            '<a href="' .. qUrl .. '">Toon bron</a>' .. '<br>' )
                            -- Send the mail
                            dz.email( 'Aardbeving ' .. qPlace, message, mailto )
                        end
                    end
                else
                    dz.log( 'No result_table found', dz.LOG_ERROR )
                end
	        else
    			dz.log( 'Item or XML - NOT OK', dz.LOG_ERROR )
		    end
		end
	end
}
Yours sincerely,
Fred

Rasberry Pi 3B+ - Debian Buster - Domoticz 2022.2
RFLink - RFXCom - Zigbee (CC2531)
P1 Smart Meter - KaKu
Post Reply

Who is online

Users browsing this forum: No registered users and 1 guest