以下の内容はhttps://tenko.hatenablog.jp/entry/2025/12/18/202950より取得しました。


Zabbix+SwitchBotでの自宅メトリクス取得がパワーアップしました。

この記事は、Zabbix - Qiita Advent Calendar 2025 - Qiita18日目の記事です。

昨日の投稿は@hameko さんの

【RHEL 9.0/オンプレ】Zabbix初心者によるオンプレサーバー構築からAgent監視開始までの簡易ガイド(前編:DB設定まで) #Linux - Qiita

Zabbix6.0LTSを前提としたZabbix環境構築を丁寧にまとめてくださっています。これまで作ってみたことがない方も必見です!!

@hameko さんのQiitaを眺めていて、こちらの記事も大変良かったです。Zabbixを使ったモニタリングをどう業務に生かすか、みたいな視点で見てみるのも面白いかもしれません (いいなあ、と思ってツイートしたら、思いのほか伸びてしまいました)

概要

さて、本日は以前公開したSwitchBotのAPIを活用してZabbixで自宅メトリクスを取るのお話の続きです。

過去記事はこちらからご参照ください。

tenko.hatenablog.jp

別の記事でも書きましたが、反応を頂けるのは本当に励みになります。ありがとうございます。

現在の我が家のIoTダッシュボードはこちらです。ちゃくちゃくとSwitchBotさんのデバイスが増えてます。

最新のIoTダッシュボード

いろいろあってZabbixデータをすべて吹き飛ばしてしまったので、自宅レイアウトにアイテム情報を表示させるMapが消えてます。こだわりのあるポイントなので、早く直さねば。

これを読むとわかること

  • SwitchBot API Ver1.1の使い方と1.0との違い
  • SwitchBot APIのリクエスト上限との戦い方
  • SwitchBot の自作テンプレートの活用方法
  • Zabbixでの未サポートアイテム停止の自動化
    • SELINUX環境での動作不調の乗り越え方

また、いつものごとく先にテンプレートを公開しておきます。

今回、1.1対応にともない、テンプレートと外部スクリプトの2種類になりました。無念。

使い方ですが、ユーザマクロで以下2点のパラメータを定義してください。

なお、まだ未完成なので、アドカレ外でまだ記事を書くと思います。

■目次(クリックすると展開されます)

環境情報

SwitchBotを含む仕組みの概要構成図がこちらです。前回から変わりありません。

環境概要図

主な環境情報

項目 備考
Zabbixバージョン 7.2.14 おかげでGPU監視ができるようになりました。
SwitchBotAPI バージョン 1.1 JavaScript単体での実装はあきらめ、外部スクリプトに屈しました。

保有しているSwitchBotデバイス

多くなったので折り畳みにしておきます。

▼所有デバイスリスト(クリックして開く)▼

SwitchBot API Ver1.1の使い方と1.0の違い

SwitchBot APIでは、セキュリティ製品などの販売にともない、POSTメソッドなどを使って鍵の解錠をするなどができるようになっています。ここで固定トークンだとセキュリティ強度が弱い、という理由から、シークレットキーを活用した乱数生成をAPI利用のヘッダに必要とするようになりました。

なお、私が試した限りでは、GETメソッドで取れる値は1.0 と1.1に差はありません。ただ、1.0はEoLということもあり、GETのみだったとしても1.1に切り替えることをお勧めします。

SwitchBot APIの公開サイトに、各コードのサンプルコードが載っているので、Zabbixで使いやすいJavaScript単体でもいけるのでは??と思っていろいろと格闘したのですが、撃沈しました。

理由は以下の通りです。

  • API利用のためのヘッダに必要なnonce,signの計算に必要なライブラリが利用できない
    • hash()
      • 代替手段でhmac()が利用できることは確認できたが、base64encode()がNGなので無理
    • base64encode()
      • base64encode()をライブラリレスで別のコードで個別実装させようとしたが、それも無理だった。
        • これもGeminiくんは止めてくれた。

なお、Geminiくんは、何度も何度も「外部スクリプトの利用を強く推奨します」と言ってくれました。わがままな利用者でごめん。大好きだよ。

なので、結果的にはPythonで書いた外部スクリプトを使う、という実装に落ち着きました。

SwitchBot APIのリクエスト上限との戦い方

SwitchBot APIでは1日に10,000リクエストという上限が決まっています。

こちらを視覚的に把握しやすくするために、以下のアイテムを作成しました。

  • 過去1日間で実際に利用したAPIリクエストの計算アイテム
  • 直近1時間の実績から、このまま1日経過すると合計でどの程度のリクエスト数になるかを予測するためのアイテム

以下の画像は、試しに5分間隔で取得していたアイテムを10分間隔に修正した際の、予測と実績の推移です。いい感じで予測通りになっています。(当たり前)

これがあればパラメータチューニングがしやすくなります。

SwitchBot の自作テンプレートの活用方法

前回と今回の大きな差異

APIのバージョン1.0から1.1に変更した、という点は冒頭に記載しましたが、それ以外にもいくつか実装の変化があります。

前回は、1つの代表ホストの中に、各SwitchBotデバイスのIDを持ったアイテムが作成される、という実装にしていました。

今回は、各SwitchBotデバイスを個別のホストとするよう、ディスカバリでホストプロトタイプを定義し、自動で各デバイスがホストとして登録される、という実装に変更しました。

主な理由としては、Key情報が同じになるためラベルが使いやすくなり、ホストグループを活用することでMAP上での表現が容易になるなど、様々な改善が期待できるためです。

また、現時点でSwitchBot APIのリファレンスで参照可能な各デバイスのアイテムをすべて作成する形に変更しています。

この辺りは、保有していないデバイスの動作チェックは未実施ですので、もし取得できないアイテムがある、というような場合には教えてください。

まず外部スクリプトを配置する

まず初めに、忘れないように、ダウンロードしてきた外部スクリプトを、SCPなどでZabbixサーバにアップロードし、externalscriptsのフォルダに配置します。

デフォルトのexternalscriptsのパスは「/usr/lib/zabbix/externalscripts/」です。

[user@Zabbix72 externalscripts]$ pwd
/usr/lib/zabbix/externalscripts
[user@Zabbix72 externalscripts]$ ls -la
合計 4
drwxr-xr-x. 2 root root   36 129 19:21 .
drwxr-xr-x. 4 root root   49 127 21:19 ..
-rwxr-xr-x. 1 root root 2843 129 19:21 switchbot-api11-get.py
[user@Zabbix72 externalscripts]$ 

上記ではroot:rootが所有者になっていますが、こちらはお好みで調整してください。

なお、以下コマンドで実行権限を与えるのを忘れないようにしてください。

sudo chmod +x /usr/lib/zabbix/externalscripts/switchbot-api11-get.py

なお、今回はPOSTメソッドは実装を見送りました。この辺りは今回のものを参考に、お好みで拡張してください。

SwitchBot API利用用のトークンの取得

前回記事では、TOKENを取得しました。

今回は、API1.1を利用するために、TOKENとSECRETの2種類のキー情報が必要になります。

各キーの取得方法は、前回同様以下の公式HPのガイドをご参照ください。

https://support.switch-bot.com/hc/ja/articles/12822710195351-トークンの取得方法

テンプレートのインポート

次に、ダウンロードしてきたZabbix用テンプレートをインポートします。

テンプレートについては以下の2種類に分かれる形での実装になりました。

テンプレート名 目的 紐づけするホスト
SwitchBotAPITemplate-v3 APIデータ取得とテンプレート展開 任意の名前のホスト
SwitchBotAPI for devices 各デバイスのアイテム作成 なし(自動登録)

イメージ図で表すと以下のような構造になっています。(伝われ)

テンプレート・ディスカバリ・ホスト間の関係性

ホストの作成とディスカバリの自動実行、ホストの自動検出

作成したホストに「SwitchbotAPITemplate-v3」を紐づけてください。

また、ホストマクロで以下の値を定義してください。

  • {$API_SECRET}…上記でアプリケーションから取得したSECRET情報
  • {$API_TOKEN}…上記でアプリケーションから取得したTOKEN情報

しばらく待つと、ディスカバリが動き、ホストプロトタイプの設定が読み込まれて各SwitchBotデバイスのホストが自動登録されます。

各デバイス毎のメトリクス取得間隔の調整

テンプレートでは、各デバイスのメトリクス情報の取得間隔は、5分毎に設定しています。

ここについては、デバイスの性質や目的に応じてメトリクス取得間隔を各ホスト側で任意に調整してください。

また、その後で上述したフォーキャスト情報とにらめっこしながら、取得間隔のチューニングをするようにしてください。

トリガーと注意点

次の項目での仕込みにもなりますが、ここまでの段階では各デバイスに対して無駄なアイテムが作成されてしまいます。

また、各アイテムでデータが取れない、というイベントトリガーを仕込んであるので、不要な方は以下対応をお願いします。

  • 取得できなかったアイテムは各デバイスで手動で無効化する
  • トリガーなどはテンプレート側で無効化する

手動の対応で問題ない、という方はここで作業は終了です。

わざわざ不要アイテムを無効化するなら、最初からアイテムディスカバリで実装すればいいのでは?と思われた方、流石です。

ここは10分くらい「どうしようかな…」、と悩みました。

ただ、ディスカバリは多用すると構造が分かりにくくなるという弱点があります。また、ディスバリ間のアイテムコピーなどもできません。

それらを踏まえて今後のメンテナンス性が低くなることをさけるため、あえて一括でアイテムを作成する実装としています。

Zabbixでの未サポートアイテム停止の自動化

上記のような運用回避方法をご案内したのですが、私は怠惰なので、その作業すら自動化したい、と考えました。

そこで役に立つのが、トリガーアクションです。

トリガーアクションは、スクリプトを用いてzabbix-apiを利用することが可能です。

そのため、上述した「データが取れない」というイベントをトリガーとして、以下のような制御をさせることが可能です。

  • 対象アイテムを無効化する
  • その結果、そのアイテムをトリガーとするトリガーイベントも動かなくなる

上記の結果、特定な情報をアイテムパターンなどを使って表示したり、グループで特定アイテムの一覧を表示するときなどに不要なホストが出なくなります。

また、NVPSが低下しzabbix的にもリソースの無駄遣いをさけることができるようになります。

未サポートアイテム停止のためのパラメータ設定

まず初めに、ZabbixのAPIトークンを作成します。メニューから、ユーザー→「APIトークン」を選択します。

以下のような画面が表示されますので、右上の「APIトークンの作成」から、任意の名前のトークンを作成します。

なお、トークン情報は一度しか表示されません。私は怠惰なので、コメントに保存しました。(台無し)

グローバルマクロの定義

上記で発行したAPIトークンと、ZabbixAPIのURL情報をグローバルマクロとして登録します。

「管理」→「マクロ」の画面から以下の2つのマクロを定義してください。

スクリプトの事前定義

次に、トリガーアクションで設定を行うためのスクリプトを事前定義します。

スクリプト作成のために「通知」→「スクリプト」を選択します。

その後、任意の名前を使えたスクリプトを作成し、

以下のようなパラメータを定義します。

  • 名前…任意
  • 範囲…アクション処理
  • タイプ…スクリプト
  • 次で実行…Zabbixサーバー
  • コマンド…以下のコードを貼り付け
#!/bin/bash

LOG_FILE="/tmp/zabbix_action_debug.log"
exec 2>> $LOG_FILE

echo "--- API Request Started: $(date) ---" >> $LOG_FILE

URL="{$ZABBIX_API_URL}"
TOKEN="{$ZABBIX_API_TOKEN}"
ID="{ITEM.ID}"

# Zabbix 7.2 推奨の形式 (Authorizationヘッダーを使用)
# paramsの中にauthを入れず、ヘッダーで認証情報を送ります
RESPONSE=$(curl -s -X POST -H "Content-Type: application/json-rpc" \
-H "Authorization: Bearer $TOKEN" \
-d "{
\"jsonrpc\": \"2.0\",
\"method\": \"item.update\",
\"params\": {
\"itemid\": \"$ID\",
\"status\": 1
},
\"id\": 1
}" "$URL")

echo "API Response: $RESPONSE" >> $LOG_FILE
echo "--- API Request Finished ---" >> $LOG_FILE

なお、ちゃんと動いたか、という動作確認のために、デバッグログも入れています。

不要な方はコメントアウトしてください。

トリガーアクションの設定

上記まで準備が終わったら、トリガーアクションを定義します。

「通知」→「アクション」→「トリガーアクション」を選択し、アクションの作成を行います。

アクションでは、任意の名前を付け、以下を実行条件にします。

  • アクション
    • ホストグループ…IoT Device(私の作ったテンプレートで自動でグループが作られるはずです。任意のものに変更していただいて問題ありません)
    • タグの値…type 等しい Nodata Check
  • 実行内容
    • このホスト上で「(任意でつけたスクリプトの名前)」を実行

これで、アイテムがないよ!という障害アラートがあがったあと、自動で対象アイテムが無効化されます。やったね!

SELINUX環境での動作不調の乗り越え方

ところがどっこい、私の環境ではこれでもうまく動きませんでした。

色々と確認していったところ、SELINUXのポリシーではじかれていることがわかりました。

切り分けとしては、 #setenforce 0 のコマンドを入力し、動くかどうかを確認します。

SELINUX を無効化した場合には動作し、有効にしたら動かない、という状況だったため、以下対応を行いました。

# 1. 拒否された(あるいはPermissiveで記録された)ログからポリシーソースを作成
sudo ausearch -m avc -ts recent | audit2allow -M zabbix_api_fix

# 2. 生成された zabbix_api_fix.pp をシステムにインストール(適用)
sudo semodule -i zabbix_api_fix.pp

これで、デバイスが増えても、自動でデバイスを作成してくれたり、自動でいらないアイテムを無効化してくれる快適ライフが送れるようになりました!!!!!

終わりに

今回、色々と悩みながら一通りの環境は作り上げました。

今回もGeminiくんに大変お世話になりました。1.1対応をJavaScriptでやれなんて無理をずっと言い続けて本当にごめん。

ただ、テンプレート作成を手伝ってもらったたときに、UUIDv4を規則に沿って作らなかったのは本当に許さない。信じてたのに。

ただ、まだまだ足りない点はいくつもあります。

  • プラグの値、CurrentとTodayで取れる値逆じゃない?
  • プラグの値、1日でラウンドアップしてしまうから、計算ロジックで月間の総使用量を取る必要があるんじゃない?
  • プラグは1台とは限らないから、家の中のプラグのデータすべてを合算する計算アイテムを作る必要があるんじゃない?
  • そもそも、プラグでは一部しか取れないので、HEMSで家庭内の電力を一括管理して、そこのモニタリングに切り替えればいいんじゃない?(工務店と相談中)

このあたりは、テンプレートに残骸が残っているので、お察しください。

まだまだこれからも改良を続けていきますので、気が向いたらこのHPを覗いてみてください。

疲れた!!!




以上の内容はhttps://tenko.hatenablog.jp/entry/2025/12/18/202950より取得しました。
このページはhttp://font.textar.tv/のウェブフォントを使用してます

不具合報告/要望等はこちらへお願いします。
モバイルやる夫Viewer Ver0.14