Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Start IoT with WordPress

Start IoT with WordPress

IoT using REST API and custom post type of WordPress. Presented at WordCamp Haneda (4F Room A).

IKEDA, Yuriko

April 20, 2019
Tweet

More Decks by IKEDA, Yuriko

Other Decks in Technology

Transcript

  1. AQSF SGTTe Q?t jbnp CS Q? J AQSF SGTT 

    8PSE$BNQ)BOFEB ஑ాඦ߹ࢠ
  2. _ QRVNCS TOCNN EQORV GST Q/ AG IJ S EG

    3BTQCFSSZ1J Y"3.()[ H = 3BTQCFSSZ1J ;FSP8 "3.()[ H = "SEVJOP "3..)[ H = NJDSPCJU "3..)[ H = &418300. "3..)[ H =
  3. 8J'J ()[ (CQT #-& ()[ .CQT (-5& .ʙ()[ ໿.CQT -18"

    ʙ.)[ LCQT ;JH#FF ()[ ೔ຊ ,CQT A SGNGTT GEJPQNQI
  4. A i t : : P G A FC C

    IUUQEFNPXQBQJPSHXQKTPOXQWQPTUT {"id":1,
 "date":"2017-05-23T06:25:50",
 "date_gmt":"2017-05-23T06:25:50",
 "guid":{"rendered":"http:\/\/demo.wp-api.org\/?p=1"},
 "modified":"2017-05-23T06:25:50",
 "modified_gmt":"2017-05-23T06:25:50",
 "slug":"hello-world",
 "status":"publish",
 "type":"post",
 "link":"https:\/\/demo.wp-api.org\/2017\/05\/23\/hello-world\/",
 "title":{"rendered":"Hello world!"},
 "content":{"rendered":"<p>Welcome to...
  5. x w i 1PFRQ P T IUUQEFNPXQBQJPSHXQKTPOXQWQPTUT IUUQEFNPXQBQJPSHXQKTPOXQWNFEJB IUUQEFNPXQBQJPSHXQKTPOXQWUZQFT IUUQEFNPXQBQJPSHXQKTPOXQWDPNNFOUT

    IUUQEFNPXQBQJPSHXQKTPOXQWUBYPOPNJFT IUUQEFNPXQBQJPSHXQKTPOXQWVTFST ৄࡉ鱴IUUQKBXQBQJPSHࢀর
  6. x w G GPFRQ P add_action( 'rest_api_init', function () {

    register_rest_route( 'anything/v1', '/get', array( 'methods' => 'GET', 'callback' => 'get_anything_awesome', ) ); } ); function get_anything_awesome() { $data = array('result' => 'great data'); return new WP_REST_Response( $data, 200 ); }
  7. OCMG $ git clone https://github.com/ hzeller/rpi-rgb-led-matrix $ cd rpi-rgb-led-matrix $

    make -C examples-api-use $ cd utils $ make led-image-viewer
  8. 0GOQ $ cd example-api-use $ sudo ./demo \
 --led-gpio-mapping=adafruit-hat \

    --led-no-hardware-pulse \ --led-chain=4 -L \
 -D 0
  9. x w -FF GPF RQ P add_action( 'rest_api_init', function ()

    { register_rest_route( 'wapuu/v1', '/set/(?P<id>\d+)', array( 'methods' => 'POST', 'callback' => 'set_wapuu_image', 'args' => array( 'id' => array( 'validate_callback' => function($param, $request, $key) { return is_numeric( $param ); } ), ), ) ); register_rest_route( 'wapuu/v1', '/get', array( 'methods' => 'GET', 'callback' => 'get_wapuu_image', ) ); } );
  10. t CWG& G OCIG PVODGS function set_wapuu_image( $data ) {

    $id = $data['id']; update_post_meta( 60, 'wapuu-image', $id ); $data = array( 'id' => $id ); return new WP_REST_Response( $data, 200 ); } function get_wapuu_image() { $id = get_post_meta( 60, 'wapuu-image'); $data = array( 'id' => $id ); return new WP_REST_Response( $data, 200 ); }
  11. - p G OCIG PVODGS api="http://example.net/wp-json/wapuu/v1/get" def img_number(): try: html

    = urllib.urlopen( api ).read() except: return None data = json.loads(html) return data['id']
  12. e t c G S WG OCIG D PVODGS image_dir

    = "~/wapuu/" viewer = "~/rpi-rgb-led-matrix/utils/led-image-viewer" opt = " --led-daemon --led-gpio-mapping=adafruit-hat" +\ " --led-no-hardware-pulse --led-chain=4 -L" prev = None while True: time.sleep(2) number = img_number() if number is None: continue files = glob.glob(image_dir+number+"-*.png") if len(files) < 1: continue if files[0] == prev: continue if prev is not None: kill_img() commands.getstatusoutput("sudo "+viewer+opt+files[0]) prev = files[0]
  13. j t c ?VSP QHH OCIG JGP EJCPIG pattern =

    r"^ *(\d+) .*/led-image-viewer" def kill_img (): id = [] ps_list = commands.getoutput('ps awx') for process in ps_list.split("\n"): match = re.match(pattern, process) if not match: continue id.append(match.group(1)) commands.getoutput("sudo kill "+" ".join(id))
  14. GNGE CIG <form method="post" action="/wp-json/wapuu/v1/set/001"> <div>[caption id="attachment_40" align="alignleft" width="150"] <img

    src="/wp-content/uploads/ 2017/09/001-original-150x150.png" alt="001" width="150" height="150" class="size-thumbnail wp-image-40" /> Original (WordCamp 2011 Fukuoka)<br> <button type="submit" value="001">
 Submit</button> [/caption]</div></form>
  15. GCTVSG GORGSC VSG&JVO F from sense_hat import SenseHat sense =

    SenseHat() temp = sense.get_temperature() print("Temperature: %s C" % temp) humi = sense.get_humidity() print("Humidity: %s %%rH" % humi)
  16. h /QPWGS P Q F TEQOHQS PFG 0.81Td +0.01H(0.99Td -14.3)

    +46.3 Td: Temp (℃) H: Humidity ฏԺ ೤ؾ͋Γ
  17. /VT QO QT ? RG J RT &&EQFG QSFRSGTT QSI&RQT

    B RG add_action( 'init', 'create_fever_log_type' ); function create_fever_log_type() { register_post_type( 'fever_log', array( 'labels' => array( 'name' => __( 'Fever' ), 'singular_name' => __( 'Fever' ) ), 'public' => true, 'has_archive' => true, ) ); }
  18. HGSWGSBNQI RG 鲷鲜鳀鳣
 QPTU@UJUMF ˡ ෆշࢦ਺ EJTDPNGPSUJOEFY ຊจ QPTU@DPOUFOU ˡ

    Թ౓ ࣪౓ UFNQ IVNJEJUZ ߋ৽೔࣌ QPTU@EBUF ˡ ଌఆ೔࣌ EBUFUJNF
  19. x w -FF GPF RQ P add_action('rest_api_init', function () {

    register_rest_route('fever/v1', '/log/', array( 'methods' => 'POST', 'callback' => 'log_fever_value', ) ); register_rest_route('fever/v1' '/history/', array( 'methods' => 'GET', 'callback' => 'get_fever_history', ) ); } );
  20. t "( 7QI GOR JVO F function log_fever_value() { $obj

    = json_decode($_POST); $t = $obj['temp']; $h = $obj['humi']; $data = array(); if (! is_numeric($t) || ! is_numeric($h) ) { return new WP_REST_Response($data, 400); } $json=json_encode(array('temp'=>$t,'humi'=>$h)); $discomf = $t*0.81+$h*($t*0.99-14.3)*0.01+46.3;
  21. t ") 7QI GOR JVO F $post = array( 'post_type'

    => 'fever_log', 'post_name' => 'fever_log', 'post_content' => $json, 'post_title' => $discomf, ); $post_ID = wp_insert_post($post); if (! $post_ID ) { return new WP_REST_Response($data, 500); } $data['post_ID'] = $post_ID; return new WP_REST_Response($data, 200); }
  22. t m a"( GCF F TEQOHQS PFG GT function get_fever_history()

    { $num = 360; $args = array ( 'post_type' => 'fever_log', 'numberposts' => $num, 'offset' => 0, 'orderby' => 'date', 'order' => 'ASC', ); $posts = get_posts($args);
  23. t m a") GCF F TEQOHQS PFG GT $data =

    array(); foreach ( $posts as $p ) { setup_postdata( $p ); $data[] = array( 'date' => get_the_date('Y/m/d H:i:s'), 'discomfort' => floatval(get_the_title()), ); } return new WP_REST_Response($data,200); }
  24. & R LTQP&HGWGS&W(&J T QS [ {"datetime":"2018\/06\/01 22:25:11", "discomfort":83.0214384153}, {"datetime":"2018\/06\/01

    22:25:35", "discomfort":83.3682958288}, {"datetime":"2018\/06\/02 09:12:00", "discomfort":82.3637111865} ]
  25. t GPF GOR&JVO F #!/usr/bin/python api="http://example.net/wp-json/fever/v1/log" import requests from sense_hat

    import SenseHat sense = SenseHat() temp = sense.get_temperature() humi = sense.get_humidity() env = '{"temp":%f, "humi":%f}' % (temp, humi) response = requests.post(api, env, headers={'Content-Type': 'application/json'} )
  26. h GPF RGS QF ECNN $ crontab -e */5 *

    * * * /home/pi/log-env.py {"temp":30.190403, "humi":41.724270}
  27. C E ? 7 <html><head> <script type="text/javascript" src="dygraph.js"> </script> <link

    rel="stylesheet" src="dygraph.css" /> </head> <body> <div id="graphdiv"></div> <script type="text/javascript"> g = new Dygraph( document.getElementById("graphdiv"), // CSV data. ); </script> </body> </html>
  28. RQT BEQP GP <div id="graphdiv"></div> <script type="text/javascript"> g = new

    Dygraph( // containing div document.getElementById("graphdiv"), // CSV or path to a CSV file. "Time,Fever\n" + "2018-06-02 10:15:07,77.258414\n" + "2018-06-02 10:16:08,77.554262\n" + "2018-06-02 10:17:10,77.680172\n" + "2018-06-02 10:18:02,77.825666\n" + "2018-06-02 10:20:04,78.359325\n" + "2018-06-02 10:25:03,79.242797\n" ); </script>
  29. ஑ాඦ߹ࢠ http://www.yuriko.net/ @lilyfanjp J RT && TN FGTJCSG PG &

    N N HCP& QSFRSGTT Q J RT &&I JVD EQO&N N HCPLR& QSFHGT) ( TCORNG