Page 1 of 1

Python Script: Earthquake Notification

Posted: Friday 20 October 2017 10:06
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?