Skip to content

Instantly share code, notes, and snippets.

@tkych
Last active December 22, 2015 17:58
Show Gist options
  • Save tkych/6509285 to your computer and use it in GitHub Desktop.
Save tkych/6509285 to your computer and use it in GitHub Desktop.
Radiation Monitor for Fukushima Daiichi Nuclear Power Station: fetch the monitoring data from http://www.tepco.co.jp/en/nu/fukushima-np/f1/images/2013monitoring/f1-mp-tcnew-e.zip, and output data as sparkline.
;;;; Last modified: 2013-09-10 22:13:59 tkych
;; Author: Takaya OCHIAI <https://github.com/tkych>
;; This software is released under Public License.
;;====================================================================
;; Radiation Monitor for Fukushima Daiichi Nuclear Power Station
;;====================================================================
;;
;; Usage:
;; ------
;; * (fukushima-monitor:watch)
;; =>
;; Date: 2013-09-09
;; Radiation Dose Rate(microSv/h) At the Main Gate
;; ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁
;;
;; * (fukushima-monitor:watch :detail? t)
;; =>
;; Date: 2013-09-09
;; Radiation Dose Rate(microSv/h) At the Main Gate
;; 0 500 1000
;; ˫------------------+-------------------˧
;; 15: 0:00 ▋
;; 15: 0:30 ▋
;; 15: 1:00 ▋
;; ~~~~~~~~~~~~~~~~~~omitting from 1:30-22:30~~~~~~~~~~~~~~
;; 15: 22:00 ▋
;; 16: 22:30 ▋
;; 15: 23:00 ▋
;; 15: 23:30 ▋
;; Note:
;; -----
;;
;; * If the rate is too high, DON'T PANIC!
;;
;; 1. You should check the scale. try (fukushima-monitor:watch :detail? t).
;; * 1 [Sv] = 1,000 [mSv] = 1,000,000 [microSv]
;; * An average person over one normal day received 10 microSv
;; as background dose.
;; * This rate is at the Main Gate of Fukushima Daiichi Nuclear Power Station.
;; Currently, that area is off limit to public.
;; c.f. http://en.wikipedia.org/wiki/Sievert
;; http://en.wikipedia.org/wiki/Background_radiation
;; 2. Probably it is a bug, so you should check the web page,
;; http://www.tepco.co.jp/en/nu/fukushima-np/f1/index-e.html
;;
;; * If nothing is printing, DON'T PANIC!
;;
;; 1. Probably it is a bug, so you should check the web page,
;; http://www.tepco.co.jp/en/nu/fukushima-np/f1/index-e.html
;; 2. Probably monitoring data url is changed. Check the url,
;; http://www.tepco.co.jp/en/nu/fukushima-np/f1/images/2013monitoring/f1-mp-tcnew-e.zip
;;--------------------------------------------------------------------
(in-package :cl-user)
(eval-when (:compile-toplevel :load-toplevel :execute)
(ql:quickload '(:cl-spark :drakma :zip :cl-ppcre)))
(defpackage #:fukushima-monitor
(:use :cl)
(:export #:*monitoring-data-url*
#:watch))
(in-package #:fukushima-monitor)
;;--------------------------------------------------------------------
(defparameter *monitoring-data-url*
"http://www.tepco.co.jp/en/nu/fukushima-np/f1/images/2013monitoring/f1-mp-tcnew-e.zip")
(defun generate-tmp-file-name ()
(format nil "./TMP-fukushima-monitor-~D.zip" (get-universal-time)))
(defun watch (&key (detail? nil) (inf 0) (sup 1000))
(let ((tmp-zip-file (generate-tmp-file-name)))
(unwind-protect
(progn
;; Generate zip file
(with-open-file (out tmp-zip-file
:direction :output
:if-does-not-exist :create
:if-exists :supersede
:element-type '(unsigned-byte 8))
;; Fatch zip file
(let ((input
(handler-case
(drakma:http-request *monitoring-data-url* :want-stream t)
(error (c)
(RETURN-FROM watch (format t "Fetch Fail: [~S]" c))))))
;; Stream to zip file
(let ((buf (make-array 4096 :element-type '(unsigned-byte 8))))
(loop
:for pos := (read-sequence buf input)
:while (plusp pos)
:do (write-sequence buf out :end pos)))))
;; Zip file to data-string
(let ((data-string nil)
(csv-file-name nil))
(zip:with-zipfile (z tmp-zip-file)
(zip:do-zipfile-entries (name entry z)
(when (search "tmp" name) ;"tmp" means Temporary Monitoring Post
(setf data-string
(flexi-streams:octets-to-string
(zip:zipfile-entry-contents entry)))
(setf csv-file-name name))))
;; parse data-string
(if data-string
(let ((data nil)
(times nil)
(title nil))
(cl-ppcre:do-register-groups (time rate)
(".*?,(.*?),.*?,(.*?),.*?
" data-string)
(when (stringp rate)
(let ((num (parse-integer rate :junk-allowed t)))
(if num
(progn
(push num data)
(push time times))
(setf title rate)))))
(format t "~& Date: ~A~A"
(cl-ppcre:regex-replace-all
"(\\d\\d\\d\\d)(\\d\\d)(\\d\\d)\\d\\d"
(cl-ppcre:register-groups-bind (date)
("f1-tmp-(.*?)-e.csv" csv-file-name)
date)
"\\1-\\2-\\3")
(if detail?
(cl-spark:vspark (reverse data)
:labels (loop
:for d :in (reverse data)
:for tm :in (reverse times)
:collect (format nil "~A: ~5,,,@A" d tm))
:inf inf :sup sup
:title title)
(format nil "~% ~A~%~A"
title
(cl-spark:spark (nreverse data)
:inf inf :sup sup)))))
(RETURN-FROM watch (format t "Zip-file parse Fail.")))))
(when (probe-file tmp-zip-file)
(delete-file tmp-zip-file)))))
;;====================================================================
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment