1. Remove your current script aardbevingen. You mixed everything in there.
2. Open a new DZvents script. Remove the template data and then paste the following in there. It holds the global helper functions.
I cleared it from content that has nothing to do with the current script.
Tip. Never only paste and run code. Read the comments. Try to understand what it does, before it is running FORMAT C:

Save it with the name: global_data
Code: Select all
-- 05-01-2023: Script created by Jan peppink, https://ict.peppink.nl
-- This scripts holds all the globally persistent variables and helper functions
-- See the documentation in the wiki
-- NOTE: THERE CAN BE ONLY ONE global_data SCRIPT in your Domoticz install.
----------------------------------------------------------------------------------
return {
------------------------------------------
-- Global persistent data
data = {
-- Global variables below here.
},
------------------------------------------
-- 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,
------------------------
}
}
-- That's All --------------------------------------------------
A. Change IDX number and Email.
B. Save it as Aarbevingen-KNMI or what you want.
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.
-- 21-05-2024 Sometimes error on local atUTCtime = description_table[1] .. ' ' .. string.sub( description_table[2], 2, 6 )
-- bad argument #1 to 'sub' (string expected, got nil); However - Manually never seen.
--- Your settings ----------------------------------------------------------------
-- First set the used device index numbers and variables you might want to change.
local alertIdx = 99999 -- 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 2 minutes', -- Only for testing.
'at *:02',
'at *:07',
'at *:12',
'at *:17',
'at *:22',
'at *:27',
'at *:32',
'at *:47',
'at *:52',
'at *:57',
},
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( 'URL details = ' .. 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( 'Full description string = ' .. 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)
dz.log( 'String 1 = "' .. description_table[1] .. '" en String 2 = "' .. description_table[2] .. '"', dz.LOG_DEBUG )
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]
dz.log( 'qAuthor = ' .. qAuthor, dz.LOG_DEBUG )
-- Record 9 = Type = Geinduceerd
local qType = description_table[9]
dz.log( 'qType = ' .. qType, dz.LOG_DEBUG )
-- 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, 0 )
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 --------------------------------------------------