[PYTHON] It is very fast when you receive the Earthquake Early Warning on the strong motion monitor and handle it in JSON.

Overview

--POST JSON from Chrome extension "Strong Motion Monitor" to Python web server --Cook the received JSON and throw it to Discord's Webhook, Slack, etc. (POST) --Fast, cheap, delicious ――How fast is it? The moment you receive the breaking news on the macbook's strong motion monitor, it is output to the Discord channel.

Prerequisites

--The operation has been confirmed on CentOS7 and Python3. --Use the Google Chrome extension "Strong Motion Monitor Extension". --From the above extension, "Send earthquake information" will send JSON to the Python web server.

Background

――We created a mechanism to get tweets from Twitter's earthquake early warning account via IFTTT. The response time varies depending on the server status of Twitter, and it is sharp. In the worst case, it cannot be acquired in a timely manner. ――I want to output and share Earthquake Early Warnings not only to myself but also to the Discord channel. ――My hobby is earthquake monitoring. ――It started to be noisy in 2020, so to collect data.

How to achieve

Data flow image (sorry for the string)

Strong motion monitor Earthquake information Push server → Google Chrome of CentOS7 → Python Web server of CentOS7 → Discord / Slack / Twitter API

CentOS side

--Because it handles GUI, start with runlevel 5 --Google Chrome installation --Install the Chrome extension "Strong Motion Monitor Extension" --I wrote a web server in Python, so I installed Python3. I think Node.js is fine with anything. --Specify "http: // localhost: 8000" for "Send earthquake information" in the settings in the extension

Supplement

--Complicated dependency of rpm package required for installing Google Chrome (related to OS startup with minimal configuration) --The data that flies from the extension is in JSON format. --Quoted from the log as of May 13, 2020.

{
'type': 'eew', #In the case of Earthquake Early Warning, the string type eew
'time': '1589131429000', 
'report': '1', #In the case of the first report, the character string 1 of type String. The final report is a string of type final
'epicenter': 'Iyo Nada', #epicenter
'depth': '60km', #Depth of epicenter
'magnitude': 3.5, #Magnitude indicating the magnitude of the earthquake
'latitude': 33.8, #The two lines here are probably latitude and longitude
'longitude': 132.1, 
'intensity': '2',  #Expected seismic intensity
'index': 2
}

The information I want is mostly String type and Float type, so keep that in mind. For reference, I will also post the log of acceleration detection.

{
'type': 'pga_alert', 
'time': '1589131441839', 
'max_pga': 0.637, 
'new': True, 
'estimated_intensity': 0, 
'region_list': ['Ehime']
}

Python side

It runs as a web server.

from http.server import BaseHTTPRequestHandler, HTTPServer
from urllib.parse import parse_qs, urlparse
import sendToDiscord #This is my own code. I cook in this and POST it to Discord's Webhook.


address = ('0.0.0.0', 8000)

class MyHTTPRequestHandler(BaseHTTPRequestHandler):

	def do_GET(self):

		parsed_path = urlparse(self.path)
		self.send_response(200)
		self.send_header('Content-Type', 'text/plain; charset=utf-8')
		self.end_headers()
		self.wfile.write(b'Hello from do_GET')

	def do_POST(self):

		parsed_path = urlparse(self.path)
		content_length = int(self.headers['content-length'])
		
		sendToDiscord.readJson('{}'.format((self.rfile.read(content_length).decode('utf-8'))))
		
		self.send_response(200)
		self.send_header('Content-Type', 'text/plain; charset=utf-8')
		self.end_headers()
		self.wfile.write(b'Hello from do_POST')

with HTTPServer(address, MyHTTPRequestHandler) as server:
    server.serve_forever()

It's clumsy, but I just added one line to the sample code. The received JSON is poured into the function as it is and processed.

2020/05/19 postscript To @ sirorabi516 I'll paste a part of the throwing code into the Discord webhook.

import json
import requests

webhookUrl = "DISCORD WEBHOOK URL"

'''
Send a message to Discord Webhook
'''
def sendDiscord(msg):

	# Create JSON
	payload = {
	   "content" : "{0}".format(msg)
	}

	'''
It seems better to check the status code in the contents of res and incorporate the retry process
	'''
	# Send to Discord
	res = requests.post(webhookUrl, json.dumps(payload), headers={'Content-Type': 'application/json'})
	return


'''
Create a message by converting the JSON received from the web server into a dictionary
'''
def readJson(jsonData):
	jsonData = json.loads(jsonData)

	'''
Process if it is an Earthquake Early Warning, the first report, and an expected seismic intensity of 3 or higher.
	'''
	
	# get first eew message
	if jsonData.get('type') == 'eew' and jsonData.get('report') == '1' and int(jsonData.get('intensity')) > 2:
		magnitude = float(jsonData.get('magnitude'))

		# get EQ Data
		epicenter = str(jsonData.get('epicenter'))
		depth = str(jsonData.get('depth'))
		intensity = str(jsonData.get('intensity'))

		'''
Output message composition part of discord. If you specify fix, the whole text can be yellow.
		'''
		# add EQ Data
		msg = '''```fix

 Ground earthquake speed report (1st report)

 Earthquake source: {0}
 Expected seismic intensity: {1}
 Standard: M {2}
 Depth: {3}


#### **`'''.format(epicenter, intensity, str(magnitude), depth)`**
```format(epicenter, intensity, str(magnitude), depth)

		sendDiscord(msg)	
		return

	'''
In case of false alarm, pga_alert_Since it seems that cancel is sent, try to detect that as well
	'''
	# Alert Cancel
	if jsonData.get('type') == 'pga_alert_cancel':
		msg = '### Cancel Message ###'
		sendDiscord(msg)
		return

I wrote it like this. I think the last'pga_alert_cancel' is mandatory. Because, in the past, the information "Northern Tokyo Bay seismic intensity 7" flew from the observation point in Tokyo in the first report. When I received it, I panicked, "What? Isn't this the level at which Tokyo will be destroyed!" After all, it is a punch line that it was a false alarm due to the influence of a lightning strike, but disseminating information elsewhere should not cause a strange panic. I also have to tell you that it was a false alarm. Of course for myself.

Notes

--JSON will not fly from the Chrome extension unless you leave do_GET. --When you check the Chrome extension in developer mode, the information destination is something like a health check. --At that time, if you do not return a normal response, you will not be able to receive information.

Finally

For now, I think this method is easy to handle earthquake information for advanced users at a detonation velocity without incurring costs. Since the data is passed in JSON, embed it in the message as you like, There is also an atmosphere that you can pass information to your favorite place, so it seems that you can use it in other ways.

Recommended Posts

It is very fast when you receive the Earthquake Early Warning on the strong motion monitor and handle it in JSON.
POST JSON in Python and receive it in PHP
POST the image with json and receive it with flask
Write a script in Shell and Python to notify you in Slack when the process is finished
How to return the data contained in django model in json format and map it on leaflet