FlaskでWebで表示できるようになったが、Webアプリ側を開発しないとリッチなUI表示ができなくなっているので、簡単にリッチなUIができるGrafanaを使用して可視化をできるようにする。
アプリケーション全体像
Flaskとの違いとしては、OPC‐UA serverから直接データベースのmysqlに書き込むようになり、フロントエンドのWebAppは独立したコンテナとした。
Docker Composeの設定
まず、Docker Composeを使って複数のコンテナを設定します。1つは温度データを取得するためのコンテナ(temperature-sensor
)、もう1つはデータベースのためのコンテナ(mysql
)、そしてGrafanaを使用してデータを可視化するコンテナ(grafana
)です。
version: '3'
services:
temperature-sensor:
build:
context: .
dockerfile: sensor.Dockerfile
networks:
- tempnet
mysql:
image: mysql:5.7
environment:
MYSQL_ROOT_PASSWORD: example
MYSQL_DATABASE: temperature_db
networks:
- tempnet
volumes:
- mysql_data:/var/lib/mysql
grafana:
image: grafana/grafana
ports:
- "3000:3000"
networks:
- tempnet
volumes:
- grafana_data:/var/lib/grafana
volumes:
mysql_data:
grafana_data:
networks:
tempnet:
温度データ取得コンテナの設定
temperature-sensor
コンテナは、ダミーの温度データを生成し、MySQLデータベースに保存します。
Dockerfile (sensor.Dockerfile
)
FROM python:3.9-slim
RUN pip install opcua pymysql
COPY sensor.py /app/sensor.py
CMD ["python", "/app/sensor.py"]
温度センサースクリプト (sensor.py
)
from opcua import Server
import pymysql
import random
import time
server = Server()
server.set_endpoint("opc.tcp://0.0.0.0:4840/freeopcua/server/")
namespace = server.register_namespace("TemperatureSensorNamespace")
objects = server.get_objects_node()
temperature_obj = objects.add_object(namespace, "TemperatureSensor")
temperature = temperature_obj.add_variable(namespace, "Temperature", 0)
temperature.set_writable()
db = pymysql.connect(host="mysql", user="root", password="example", database="temperature_db")
server.start()
print("OPCUA Server Started")
try:
while True:
temp = random.uniform(20.0, 25.0)
print(f"New Temperature: {temp}")
temperature.set_value(temp)
cursor = db.cursor()
cursor.execute("INSERT INTO temperatures (value) VALUES (%s)", (temp,))
db.commit()
time.sleep(2)
except KeyboardInterrupt:
print("Server Stopped")
finally:
server.stop()
db.close()
テーブルの作成
MySQLデータベース内に必要なテーブルを作成します。
MySQLコンテナに接続し、テーブルを作成
docker-compose up -d mysql
docker exec -it <mysql_container_id> mysql -u root -p
MySQLシェルで以下のコマンドを実行します:
USE temperature_db;
CREATE TABLE temperatures (
id INT AUTO_INCREMENT PRIMARY KEY,
value FLOAT NOT NULL,
timestamp TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
Grafanaの設定
GrafanaのWebインターフェースにアクセスします。ブラウザでhttp://localhost:3000のURLを開きます
初期設定のユーザー名とパスワードは admin/admin
です。ログイン後にパスワード変更を求められます。
データソースを追加します。Grafanaの左サイドバーから「設定 (Configuration)」 > 「データソース (Data Sources)」を選択し、「データソースを追加 (Add data source)」ボタンをクリックします。
「MySQL」を選択し、以下の情報を入力します:
- Host:
mysql:3306
- Database:
temperature_db
- User:
root
- Password:
example
「Save & Test」ボタンをクリックして、接続が成功することを確認します。
ダッシュボードの作成
Grafanaのトップページに戻り、「+」アイコンをクリックし、「Dashboard」 > 「新しいパネル (New panel)」を選択します。
クエリセクションで、データソースとして先ほど追加したMySQLデータソースを選択し、以下のクエリを入力します
SELECT
timestamp AS "time",
value
FROM temperatures
画面右上にあるTime SeriesをStatに変更することで時系列的変化と最新データを表示できるようにする
ダッシュボードを変更してみると数値データと時系列データを分離することもできます。
結論
これで、PythonとOPCUA、Grafanaを使用して温度データをリアルタイムに可視化する環境が整いました。各アプリケーションをコンテナにすることで、可用性、保守性が増えました。Grafanaを使用することで、リッチなUIが簡単に作成することができました。
今回は温度データの可視化のみでしたが、他にも閾値を設けることでアラートも出すことができるようになったりするので、今後はやってみたいと思います。
他にも、一日あたりの生産量と進捗率を組み合わせて、スケジュールの変更の助けにもなるかもしれません。
コメント