WordPressにbokehのグラフをのせる(備忘録)

bokeh、pandas-bokehはインタラクティブなグラフを作成することができるが、これをWordPressに添付するのも割と簡単であったので、のせておきます。

1.bokehグラフのhtmlコードを取得する

bokehのプログムをrunさせるとrunさせたディレクトリにhtmlファイルが生成されます。これをIDE(私はVisualStudioCode)で開いて、クリップボードにコピーする。

2.WordPressにコピーする

ブロック挿入ツールのウィジェット中に「カスタムHTML」があるので、これを選択し、ダイアログ中にコピーしたhtmlをペーストして、出来上がり

プレビューすると、しっかりbokehのグラフを表示することができます。マウスでドラッグやピンチもできます。

Bokeh Plot

MySQLデータをpandas-bokehでグラフ化(備忘録)

毎日暑いので、エアコンの効いた部屋でノンビリPCいじってます。今日は、先日サーバーを入れ替え、自宅温度などをESP32からMySQLに取り込み、これをグラフ化するところまで備忘録にしておきます。

必要モジュールのインストール

今回はpandas-bokehとsqlalchemyをインストールしました。それぞれpipを用いてインストールします。

pip install pandas-bokeh
pip install sqlalchemy

全体のコードは以下のとおりです。

import pandas as pd
import sqlalchemy as sa
import pandas_bokeh

user='esp32'
password='*******'
host='192.168.1.**'
db='esp_data'
port=3306

url = f'mysql+pymysql://{user}:{password}@{host}:{port}/{db}?charset=utf8'
engine = sa.create_engine(url,echo=False)

query = "select reading_time,temp from SensorData order by reading_time desc limit 1000"
#query="select * from SensorData order by reading_time desc limit 10"
df = pd.read_sql(query,con=engine,index_col='reading_time')
#print(df)

df.plot_bokeh()

たったこれだけのコードです。16行目のindex_col=’reading_time’でX座標が時間軸になり、ソートはdescですが、プロットするときは経時的に描画されます。

Bokeh Plot

MySQLクライアント接続設定(備忘録)

サーバーにMySQLを入れた際にターミナル接続は可能なのに、クライアントソフトからの接続ができなかったため、cnfファイルの変更備忘録。

cnfファイル /etc/mysql/mysql.conf.d/mysqld.conf

bind-address = 192.168.1.51 #デフォルトは127.0.0.1
mysqlx-bind-address = 192.168.1.51 #デフォルトは127.0.0.1

sudo service mysql restart でMySQLをリスタートし、アプリで確認。無事アクセスできました。

ESP32 BME680で測定したデータをMariaDBにとばす その2

先日BME680のデータをMariaDBに飛ばしましたが、スタンドアロンで自動測定できるようにプログラムを更新しました。また、Wi-Fiに接続している際にLEDを点灯させることとしました。ピン4番にプルアップ抵抗を介してLEDを接続します。

左上にLEDをつけていますWi-Fi接続で点灯します。

以下がプログラムです。ブートした際に自動的に走らせるために、プログラム名はmain.pyにしてあります。

この通りWi-Fiに接続するとLEDがともります。phpMyAdminで確認すると10秒おきにデータが蓄積していきます。

ESP32 複合センサBME680で測定したデータをMariaDBにとばす

先日仕入れたBME680を用いて温度、湿度、気圧、ガス濃度を測定してMariaDBに飛ばして記録したいと思います。今回のプログラムです。先にWi-Fiにつないでからrunさせます。

実行結果です。

C:\Users\>ampy -p com3 run c:\micropython\posttest8.py
Warning: I2C(-1, ...) is deprecated, use SoftI2C(...) instead
Temperature: 17.36
Humidity: 54.01
Pressure: 1019.21
Gas: 56.24
"temp=17.36 , hum=54.01 , pres=1019.21, gas=56.24"New record created successfully
Temperature: 17.35
Humidity: 54.14
Pressure: 1019.22
Gas: 54.43
"temp=17.35 , hum=54.14 , pres=1019.22, gas=54.43"New record created successfully
Temperature: 17.41
Humidity: 54.15
Pressure: 1019.24
Gas: 53.23
"temp=17.41 , hum=54.15 , pres=1019.24, gas=53.23"New record created successfully
Temperature: 17.48
Humidity: 54.03
Pressure: 1019.2
Gas: 52.34
"temp=17.48 , hum=54.03 , pres=1019.2, gas=52.34"New record created successfully

Aborted!

しっかりと10秒おきにDBに記録されています。

次回はプログラムを見直し、単独で自動運転できるようにします。

ESP32 複合センサBME680

先日お知らせしたBME680による温湿度気圧、ガス濃度の分析です。

SCLは21ピン、SDAは23ピンにつなぎました。

今回は秋月電子のセンサを用いていますが、同じようにAdafruitでも同様のセンサキットを用意しており、GithubにてMicroPython用に用意されているAdafruithttps://github.com/robert-hh/BME680-Micropythonのモジュールを用います。

まずはモジュールです。

このモジュールを用いますと簡単に測定できます。Adafruitで用意しているテスト用プログラムを使用し、毎度のプルアップをソフト的に行います。

あっという間に出来上がりです。

C:\Users\>ampy -p com3 run c:\micropython\bmetest.py
Warning: I2C(-1, ...) is deprecated, use SoftI2C(...) instead
15.30285 45.3333 1031.108 269211
15.31457 45.40735 1031.111 116460
15.33859 45.47064 1031.105 124723

次回はこれを用いて、DBにつなぎます。

ESP32からMariaDBにデータをとばす

センサからのデータもとれるようになり、Wi-Fiにつながり、NTPで時計の補正もできるようになりました。

IoTを進める中で必要なのはデータベースにひたすらデータを放り込み、その中で、異常のあるデータをいかに早く見つけ出すかが重要になります。このため、今回はデータベースにMariaDBを用い、ESP32からデータをPHPにPOSTしデータベースに取り込む一連の流れを紹介します。

まずはデータベースを作成します。MariaDBのインストールその他は省略しまして、既にesp_dataというデータベースを作成してあるところから始めます。phpMyAdminを使用してデータベース中にSensorDataというテーブルを作ります。次のSQL文をphpMyAdminのSQLクエリを実行し、テーブルを作ります。今回テストの都合でMACadd列は省略してあります。

CREATE TABLE SensorData (
    id INT(6) UNSIGNED AUTO_INCREMENT PRIMARY KEY,
//    MACadd VARCHAR(30) NOT NULL,
    value1 VARCHAR(10),
    value2 VARCHAR(10),
    value3 VARCHAR(10),
    reading_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
)

テーブルが出来上がったら、適当にデータを入れてみます。

INSERT INTO SensorData(value1, value2, value3) VALUES (12.3,23.4,35.3)

実行を押すとSQL文が実行され、行が挿入されます。ここまで確認したら、次はMicroPython上でjsonを用いたPOST文を作成します。

MicroPythonではpythonで使用するjsonとrequestsの頭にuをつける形になります。この形でpostできます。

次にデータを受けるphp側を作成します。

コマンドラインからampyを用いて上記MicroPythonのプログラムを走らせた結果が次です。

C:\Users\>ampy -p com4 run c:\micropython\posttest.py
New record created successfully

phpMyAdminで確認しても新しいレコードが挿入されています。

 編集 コピー削除 削除1712.323.435.32021-02-25 19:35:51

ESP32 時計まわり

ESP32をWi-Fiにてネットワークにつなぎましたので、次は時計まわりを整備します。

ESP32にはリアルタイムクロック(RTC)が実装されていますので、まずはどのような反応が出るか見ます。

>>> from machine import RTC
>>> rtc=RTC()
>>> rtc.datetime()
(2000, 1, 1, 5, 0, 2, 41, 237515)

2000年1月1日ですね。これでは時計として使えませんので、NTPサーバーに接続して現在時刻(UTC)に合わせます。

>>> import ntptime
>>> ntptime.settime()
>>> rtc.datetime()
(2021, 2, 22, 0, 22, 6, 52, 654317)

2021年2月22日22時6分52秒ですか、4個目の0は多分曜日を表しており月曜日、654317は・・・

>>> import utime
>>> utime.localtime()
(2021, 2, 22, 22, 16, 34, 0, 53)

utimeでローカルタイム表示で見てみましょう。

2021年2月22日22時16分34秒月曜日、年内の通算日数53日目(31+22=53)これはUTCですので、JSTに合わせます。

>>> utime.mktime(utime.localtime())
667355194
>>> utime.mktime(utime.localtime())+(9*3600)
667387595
>>> utime.localtime(utime.mktime(utime.localtime())+(9*3600))
(2021, 2, 23, 9, 26, 38, 1, 54)

9時間進めますutime.mktime()関数でローカルタイムを秒数の整数に戻します。この整数にJSTは9時間進んでいますので9時間×3600秒を足してあげます。この整数をutime.localtime()関数で時間に戻します。すると2021年2月23日9時26分38秒火曜日54日経過と日本時間に変更できました。

全体のプログラムです

実行経過です。

C:\Users\>ampy -p com4 run c:\micropython\timetest1.py
network config: ('192.168.11.25', '255.255.255.0', '192.168.11.1', '192.168.11.1')
2021/2/23 9:39:41

ESP32 ネットワーク接続

今回はESP32をWi-Fi接続してみました。

Wi-Fi接続は結構簡単で、MicroPython DocのESP32用クイックリファレンスhttps://micropython-docs-ja.readthedocs.io/ja/latest/esp32/quickref.htmlに詳しく書かれています。今回はこれをそっくり踏襲します。

まずはTera Term上でコマンドでの反応を見ます。

>>> wlan = network.WLAN(network.STA_IF)   #Wi-Fiをステーションモードにします
>>> wlan.active(True)             #アクティブ化確認します
True
>>> wlan.connect('essid','password')     #essidにはつなぐWi-Fiのessidを、passwordにはパスワードを入れます
>>> print('network config:',wlan.ifconfig()) #Wi-Fi接続のコンフィギュレーションをプリントします、ipアドレス、サブネット、ゲートウェイアドレス、DNSアドレス
network config: ('192.168.11.25', '255.255.255.0', '192.168.11.1', '192.168.11.1')
>>>
>>> wlan.scan()                 #Wi-Fiの電波のスキャンをします
[(b'Buffalo-G-****', b'4=\xc4\xc3\x17\x98', 11, -41, 3, False), (b'rs500m-e17ec9-1', b'\x10KF\xe1~\xcc', 6, -67, 3, False), (b'rs500m-e17ec9-2', b'\x12KF\xe1~\xcc', 6, -69, 3, False), (b'TOBU_Free_Wi-Fi', b'\x00\x14\x06(\x191', 1, -84, 0, False), (b'aterm-36fa28-g', b'\x10f\x82M\xd2\x08', 8, -85, 4, False), (b'SPWH_H33_129E8B', b'0\xa1\xfa\x12\x9e\x8b', 2, -86, 4, False)]
>>>

これで、Wi-Fiへの接続ができることを確認しました。実際のプログラムではクイックリファレンスにあるように、関数で定義して、つなげばオッケーです。

ampyを使用してプログラムを走らせると、以下のような結果になります。

C:\Users\>ampy -p com4 run c:\micropython\wifitest.py
connecting to network...
network config: ('192.168.11.25', '255.255.255.0', '192.168.11.1', '192.168.11.1')

温度センサADT7410を用いた温度測定

前回のDHT11から、時間がたちましたが、ブレッドボードに乗っていたADT7410を用いて、温度測定をしてみたいと思います。DHT11はワンワイヤーで、ESP32自体でライブラリをもっていたので楽でしたが、ADT7410ではしっかりとメーカーの仕様を読んでおかないといけません。

メーカーのアナログデバイシスのホームページから、資料をダウンロードします。https://www.analog.com/media/en/technical-documentation/data-sheets/ADT7410.pdfの12~13ページに書いてありますが、13ビットでの測定では0x00から2バイト拾って、くっつけて、うしろの3ビット分を切ると言う作業が必要になります。

今回はsclを18ピンにsdaを19ピンに設定しました。ADT7410もプルアップが必要なので、まずはプルアップします。

>>> from machine import SoftI2C, Pin
>>> p18 = Pin(18, Pin.IN, Pin.PULL_UP)
>>> p19 = Pin(19, Pin.IN, Pin.PULL_UP)

その後softi2cでデータを読み込みます。

>>> data = SoftI2C(scl = Pin(18), sda = Pin(19), freq = 10000).readfrom_mem(0x48, 0x00, 2)

ここで、2バイト分のデータを見てみます。

>>> print(data[0])
10
>>> print(data[1])
224

10進数でプリントされるので、2進数でプリントさせます。

>>> print(bin(data[0]))
0b1010
>>> print(bin(data[1]))
0b11100000

data[0]は00001010、data[1]は11100000となってます。data[0]を左に8ビットずらしてdata[1]をつなげます。

>>> print(bin(data[0]<<8 |data[1]))
0b101011100000

0000101011100000となりました。右側3ビットは不要ですから、右に3ビットずらします。

>>> print(bin((data[0]<<8 |data[1]) >>3))
0b101011100

0000101011100になりました。10進数に治すと、

>>> print(((data[0]<<8 |data[1]) >>3))  # temp=print(((data[0]<<8 |data[1]) >>3))
348

これを13ビットですから、資料にあるとおり16で割ります。

>>> print(((data[0]<<8 |data[1]) >>3)/16)
21.75

これで温度21.75度が出てきました。

このセンサではマイナスになるとファーストビットに1が立つので、13ビットで1000000000000は10進数で4096ですから、tempがこの数より大きい場合はマイナスの温度になるのでtemp=temp-8192とすればOKです。例フルビット1111111111111は10進数で8191ですから、8191-8192=-1これを16で割って-0.0625度となります。