NODE-REDでIoT — その2 データ収集

それでは、次にnode-redを使用してmodbus通信関連のデモ機の構築を進めて行きます。
自宅に遊び倒したラズパイ3BとセンサーBME680がありますので、これを使用して、室温、湿度、気圧、ガス濃度を定期的に採取してこれをNODE-REDで収集し、modbusにてデータをネットワーク内に流します。
まずは、BME680のデータを採取する工程ですが、NODE-REDでもnode-red-contrib-bme680-rpiという、ノードがあるのですが、イマイチデータを取れないため、pythonにて無理やりデータをPOSTして、これを取り込みます。
まずはBME680用のライブラリをインストールします。

sudo pip3 install bme680

次にデータ収集スクリプトを作成します。

import bme680
import time
import requests
import json

# センサー初期設定
try:
    sensor = bme680.BME680(bme680.I2C_ADDR_PRIMARY) # 0x76の場合
except (RuntimeError, IOError):
    sensor = bme680.BME680(bme680.I2C_ADDR_SECONDARY) # 0x77の場合

# フィルター設定(値を安定させる)
sensor.set_humidity_oversample(bme680.OS_2X)
sensor.set_pressure_oversample(bme680.OS_4X)
sensor.set_temperature_oversample(bme680.OS_8X)
sensor.set_filter(bme680.FILTER_SIZE_3)

# Node-REDの待ち受けURL
url = "http://127.0.0.1:1880/sensor-data"

print("データ送信を開始します...")

try:
    while True:
        if sensor.get_sensor_data():
            # データの整形
            payload = {
                "temperature": round(sensor.data.temperature, 2),
                "humidity": round(sensor.data.humidity, 2),
                "pressure": round(sensor.data.pressure, 2),
                "gas": round(sensor.data.gas_resistance, 2)
            }
            
            # Node-REDにPOST送信
            try:
                response = requests.post(url, json=payload)
                print(f"送信成功: {payload}")
            except Exception as e:
                print(f"送信エラー: {e}")

        time.sleep(5) # 5秒おき

except KeyboardInterrupt:
    print("停止します")

このファイルを、/home/sensor_project/bme680_to_nodered.pyに保存します。
systemdに登録します
sudo nano /etc/systemd/system/bme680_sensor.serviceに記載します。

[Unit]
Description=BME680 to Node-RED Gateway Service
After=network.target

[Service]
User=****
WorkingDirectory=/home/****/sensor_project/
ExecStart=/usr/bin/python3 /home/****/sensor_project/bme680_to_nodered.py
Restart=always
RestartSec=5

[Install]
WantedBy=multi-user.target

systemdに読み込ませる

sudo systemctl daemon-reload

自動起動化を有効化、起動

sudo systemctl enable bme680_sensor.service
sudo systemctl start bme680_sensor.service

サービスの有効状態を確認

sudo systemctl status bme680_sensor.service
● bme680_sensor.service - BME680 to Node-RED Gateway Service
Loaded: loaded (/etc/systemd/system/bme680_sensor.service; enabled; pr>
Active: active (running) since Wed 2026-04-15 19:03:56 JST; 3 weeks 2 >
Invocation: 38ab551302044856abae85c8db00c824
Main PID: 1141 (python3)
Tasks: 1 (limit: 756)
CPU: 39min 21.059s
CGroup: /system.slice/bme680_sensor.service
└─1141 /usr/bin/python3 /home/suga777/sensor_project/bme680_to>

そうすると、データが出始めてきます。

temperature: 24.87
humidity: 41.39
pressure: 1011.13
gas: 12535991.79

長くなってきましたので、今日はここまで。

NODE-REDでIoT インストール編

三菱のPLCのデータをオンラインで収集する目的で、いろいろ探していたところ、NODE -REDでmodbusプロトコルとMCプロトコルが使用できるということで、色々試してみました。

まずは、テストとして、手持ちのラズパイ02Wに入れてみました。インストールは公式に準じて、入れています。

bash <(curl -sL https://raw.githubusercontent.com/node-red/linux-installers/master/deb/update-nodejs-and-nodered)

インストールには若干時間がかかりますが、焦らずに待ちます。

Running Node-RED install for user **** at /home/**** on debian


This can take 20-30 minutes on the slower Pi versions - please wait.

  Stop Node-RED                       ✔
  Remove old version of Node-RED      ✔
  Remove old version of Node.js       ✔   
  Install Node v22.22.2               ✔   v22.22.2   Npm 10.9.7
  Clean npm cache                     ✔
  Install Node-RED core               ✔   4.1.8
  Move global nodes to local          -
  Npm rebuild existing nodes          ✔
  Install extra Pi nodes              ✔
  Add shortcut commands               ✔
  Update systemd script               ✔
                                      

Any errors will be logged to   /var/log/nodered-install.log
All done.
You can now start Node-RED with the command  node-red-start
  or using the icon under   Menu / Programming / Node-RED
Then point your browser to localhost:1880 or http://{your_pi_ip-address}:1880

Started :  2026年  4月 10日 金曜日 17:59:35 JST 
Finished:  2026年  4月 10日 金曜日 18:16:22 JST
 
**********************************************************************************
 ### WARNING ###
 DO NOT EXPOSE NODE-RED TO THE OPEN INTERNET WITHOUT SECURING IT FIRST
 
 Even if your Node-RED doesn't have anything valuable, (automated) attacks will
 happen and could provide a foothold in your local network
 
 Follow the guide at https://nodered.org/docs/user-guide/runtime/securing-node-red
 to setup security.
 
 ### ADDITIONAL RECOMMENDATIONS ###
  - Remove the /etc/sudoers.d/010_pi-nopasswd file to require entering your password
    when performing any sudo/root commands:
 
      sudo rm -f /etc/sudoers.d/010_pi-nopasswd
 
  - You can customise the initial settings by running:
 
      node-red admin init
 
**********************************************************************************
 

Node-RED Settings File initialisation
=====================================
This tool will help you create a Node-RED settings file.

✔ Settings file · /home/****/.node-red/settings.js

Share Anonymouse Usage Information
==================================
✔ Node-RED can notify you when there is a new version available.
This ensures you keep up to date with the latest features and fixes.
This requires sending anonymised data back to the Node-RED team.
It does not include any details of your flows or users.
For full information on what information is collected and how it is used,
please see https://nodered.org/docs/telemetry
 · No, do not send my usage data

User Security
=============
✔ Do you want to setup user security? · Yes
✔ Username · ****
✔ Password · ********
✔ User permissions · full access
✔ Add another user? · No

Projects
========
The Projects feature allows you to version control your flow using a local git repository.

✔ Do you want to enable the Projects feature? · No

Flow File settings
==================
✔ Enter a name for your flows file · flows.json
✔ Provide a passphrase to encrypt your credentials file · 

Editor settings
===============
✔ Select a theme for the editor. To use any theme other than "default", you will need to install @node-red-contrib-themes/theme-collection in your Node-RED user directory. · default


✔ Select the text editor component to use in the Node-RED Editor · monaco (default)

Node settings
=============
✔ Allow Function nodes to load external modules? (functionExternalModules) · Yes


Settings file written to /home/****/.node-red/settings.js

今回はインストールには、ログにある通り約20分かかりました。途中ハングアップしてるかと思うくらいです。

では起動してみましょう

node-red-pi --max-old-space-size=256
10 Apr 18:22:50 - [info] 

Welcome to Node-RED
===================

10 Apr 18:22:50 - [info] Node-RED バージョン: v4.1.8
10 Apr 18:22:50 - [info] Node.js  バージョン: v22.22.2
10 Apr 18:22:50 - [info] Linux 6.12.75+rpt-rpi-v8 arm64 LE
10 Apr 18:22:51 - [info] パレットノードのロード
10 Apr 18:22:58 - [info] 設定ファイル: /home/****/.node-red/settings.js
10 Apr 18:22:58 - [info] コンテキストストア : 'default' [module=memory]
10 Apr 18:22:58 - [info] ユーザディレクトリ : /home/****/.node-red
10 Apr 18:22:58 - [warn] プロジェクトは無効化されています : editorTheme.projects.enabled=false
10 Apr 18:22:58 - [info] フローファイル     : /home/****/.node-red/flows.json
10 Apr 18:22:58 - [info] flow ファイルを作成します
10 Apr 18:22:58 - [warn] 暗号化されていないクレデンシャルを使用
10 Apr 18:22:58 - [info] サーバは http://127.0.0.1:1880/ で実行中です
10 Apr 18:22:58 - [info] フローを開始します
10 Apr 18:22:58 - [info] フローを開始しました

ブラウザでhttp://127.0.0.1:1880/にアクセスすると、ログイン画面が出ます。

先に登録したユーザー名とパスワードを入力すると、本体の画面が出てきます。

左の列にノード欄、真ん中がフローシート、右の列が情報欄になります。
今後、簡単なプログラムを通して、解説していきたいと思います。

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