Python Script: Earthquake Notification

Python and python framework

Moderator: leecollings

Post Reply
febalci
Posts: 331
Joined: Monday 03 July 2017 19:58
Target OS: NAS (Synology & others)
Domoticz version:
Contact:

Python Script: Earthquake Notification

Post by febalci »

I happen to live in a very active earthquake zone. Fortunately, the magnitudes are not so high, but enough to make you scare. Everytime an earthquake happens; i call family members and friends, make sure they are alright, and then go into web to check the magnitude and epicenter of the eq. Almost always, i m too late to check it, that the government web site is flooded with requests and goes into timeout. So i made a python script to check the government eq website periodically (every 5 minutes with cronjob), and feed a Domoticz Alert Sensor with the information. Please note that this website is a local one and you might need to change several things in the script, i just wanted to post a sample for it.

The Website Map:
Image

IOS Domoticz Screenshot:
Image

Script:

Code: Select all

#!/usr/local/bin/python3
# -*- coding: utf-8 -*-
import csv
import json
import urllib.request
from haversine import haversine
from json2html import *
import base64
import datetime

#Domoticz Server Settings
domoticzserver="192.168.1.20:8080"
domoticzusername = "username"
domoticzpassword = "password"
base64str = ('%s:%s' % (domoticzusername, domoticzpassword)).replace('\n', '')
base64string = base64.b64encode(base64str.encode('utf-8'))
log_to_file = False
device="XX" #Device IDX of Alert Sensor
domoticzurl = "http://" + domoticzserver + "/json.htm?type=devices&rid=" + device

# My Home Coordinates
myHome = [XX.XXXXX,XX.XXXXX]

# Check Earthquakes Within radius in km.
radius = 200

# Check Magnitude; discard magnitudes under minMagnitude (radius 100 km) , get magnitudes over maxMagnitude (Location free)
maxMagnitude = 4.5
minMagnitude = 3.5

#Domoticz log file
def log(message):
    print (message)
    if log_to_file == True:
        logfile = open('EQ_Check.log', "a")
        logfile.write(datetime.datetime.now().strftime("%H:%M:%S") + message + "\n")
        logfile.close()

def domoticzrequest (url):
    headers = { "Authorization" : "Basic %s" % base64string }
    req = urllib.request.Request(url, headers = headers)
    with urllib.request.urlopen(req) as response:
        return response.read()

def domoticzstatus():
    json_crack=domoticzrequest(domoticzurl)
    json_cra=json_crack.decode()
    json_object = json.loads(json_cra)
    getvalue = 0
   # Search the device in JSON list
    if json_object["status"] == "OK":
        getvalue = json_object["result"][0]["Data"]
    else:
        print (datetime.datetime.now().strftime("%H:%M:%S") + "- Error. Could not find device idx in Domoticz response.")
    return getvalue

log (datetime.datetime.now().strftime("%H:%M:%S") + "- script started.")
# Get CSV file from web page 
response = urllib.request.urlopen("http://www.deprem.gov.tr/earthquake/eventfile?lastDay=1&m1=0&type=1&lang=tr")
# Correct the encoding of the CSV
gpsTrack = response.read().decode('WINDOWS-1254')
# Set up CSV reader and process the header line
csvReader = csv.DictReader(gpsTrack.splitlines(),fieldnames= ('EventID', 'Ajans', 'Tarih', 'Enlem', 'Boylam', 'Derinlik', 'Rms', 'Tip', 'Buyukluk', 'Ulke', 'Il', 'Ilce', 'Koy', 'Diger', 'Yer'), restval='-')
next(csvReader,None)

# Make an empty list
coordList = [] 
orderedrow = OrderedDict()
# Loop through the lines in the string
for row in csvReader:
    lat = row["Enlem"] #Lat
    lon = row["Boylam"] #Lon
    mag = row["Buyukluk"] #Magnitude
    # UTC time conversion
    aa = haversine (myHome,[float(lat),float(lon)])
    row.update({'Uzaklık':"{0:.2f}".format(aa)}) #Distance to myHome
    row["Tarih"] = str(row["Tarih"])[:-1] # DateTime, Remove Z char    
    
    orderedrow["Tarih"] = row["Tarih"] #Date
    orderedrow["Buyukluk"] = row["Buyukluk"] #Magnitude
    orderedrow["Uzaklık"] = row ["Uzaklık"] #Distance
    orderedrow["Tip"] = row ["Tip"] #Type
    orderedrow["Il"] = row ["Il"] #City
    orderedrow["Ilce"] = row ["Ilce"] #County
    orderedrow["Yer"] = row ["Yer"] #Location
    orderedrow["Diger"] = row ["Diger"] #Other
    if haversine (myHome,[float(lat),float(lon)]) < radius: #Check radius and magnitude
        if float(mag) > minMagnitude:   
            coordList.append(orderedrow.copy())
    elif float(mag) > maxMagnitude:
        coordList.append(orderedrow.copy())

# Write HMTL table from the JSON for the filtered earthquakes
temphtml = json2html.convert(json = json.dumps(coordList))        
temphtml = '<meta charset="UTF-8">\n<style>\nth, td {text-align: left;padding: 2px;}body {background-color: white;}tr:nth-child(even){background-color: #f2f2f2}\n</style>\n' + temphtml
if not coordList:
    sys.exit()
a = json.dumps(max(coordList, key=lambda ev: ev['Buyukluk']), ensure_ascii=False, indent=4)
a1 = json.loads(a)

if (len(coordList)) != 0: #If List is not empty
    with open('/volume1/web/json/deprem.html', 'w', encoding='utf-8') as html_file:
        html_file.write(temphtml)
    with open('/volume1/web/json/depremmax.json', 'w', encoding='utf-8') as f:
        json.dump(max(coordList, key=lambda ev: ev['Buyukluk']), f, ensure_ascii=False, indent=4)
        quoted_info = urllib.parse.quote(a1["Buyukluk"]+","+a1["Tarih"]+","+a1["Uzaklık"]+","+a1["Yer"]+","+a1["Il"]+","+a1["Ilce"])
        if float(a1["Buyukluk"]) < 3:
            magnitude="0"
        elif float(a1["Buyukluk"]) < 4:
            magnitude="1"
        elif float(a1["Buyukluk"]) < 5:
            magnitude="2"
        elif float(a1["Buyukluk"]) < 6:
            magnitude="3"
        else:
            magnitude="4"
        currentstatus = domoticzstatus()
        unquoted_info=urllib.parse.unquote(quoted_info)
        if (unquoted_info != currentstatus):
            domoticzrequest("http://" + domoticzserver + "/json.htm?type=command&param=udevice&idx=" + device + "&nvalue=" + magnitude + "&svalue=" + quoted_info)
    with open('/volume1/web/json/depremlist.json', 'w', encoding='utf-8') as f:
        json.dump(coordList, f, ensure_ascii=False, indent=4) 
I couldn't find any home use "Seismograph" product; but as far as i see, there's a "Seismograph/Tamper Mode" for products like Fibaro FGMS-001 Sensor and the Aeon Labs MultiSensor 6. Is there anyone who happens to have experience on these products as "Seismograph" usage?
Post Reply

Who is online

Users browsing this forum: No registered users and 1 guest