電力の消費が増える夏や冬には、電力使用率や節電のお願いをニュースなどで見かけることがあると思います。
この「電力使用率」ですが、1時間ごとの実績値がWebサイト上でCSVデータとして公開されていることをご存じでしょうか?
そこで今回は、「電力使用率が基準値を超えていたら節電を促すメッセージをSlackに投稿するフロー」をつくってみました。
電力使用率の実績値は、東京電力パワーグリッド株式会社様から公開されている「でんき予報」(https://www.tepco.co.jp/forecast/) の電力使用状況データ(CSVデータ)を利用しております。
処理全体の流れ
処理の流れは、以下のようにしました。
- でんき予報のサイトからCSVデータを取得する
- そのCSVデータから、最新の実績値が入った1行を抽出する
- 抽出したデータを使って、Slackに投稿するメッセージを生成する
- Slackに投稿する
Slack側の設定
あらかじめSlack側でAppを作成しておく必要があります。
今回は、「でんき予報bot」という名前でAppを作成しました。
設定手順
NOTE:Slack側の仕様変更により手順が変わる場合がありますのでご了承ください。
1. https://api.Slack.com/apps にアクセスし、Create New App ボタンを押します。
2. From scratch を選択します。
3. App Name にApp名を入力します。今回は「でんき予報bot」としました。Pick a workspace to develop your app in では、投稿先のチャンネルを含むワークスペースを選択します。
4. Create App ボタンを押します。
5. Basic Information の画面が表示されます。
6. Premissionsを押します。
7. Scopes を設定します。スコープには「chat:write」「files:write」の2つの設定を入れておく必要があります。前者はテキストメッセージの投稿のため、後者は画像の投稿のために必要です。
8. 左のメニューにある App Home を押します。
9. Your App’s Presence in Slack 内の App Display Name にある Edit ボタンを押します。
10. Add App Display Name の画面が開きます。Display Name (Bot Name) と Default username を入力します。
11. Add ボタンを押します。
12. 左のメニューにある Basic Information を押します。
13. ページの下のほうにある Display Information から、必要に応じて Short description に説明文を書いたり、Add App Icon からアイコン画像を登録したりもできます。
14. ページの上のほうにある、Install to Workspace ボタンを押します。
15. アクセス許可を求められるので、「許可する」を押します。
16. このあとの手順(ASTERIA Warp側のコネクション設定)で必要になるので、OAuth & Permissions のページにある Bot User OAuth Token の内容をコピーしておきます。
以上でSlack側の設定は完了です!
ASTERIA Warp側の設定
ASTERIA Warp側は、以下のような設定を実施しました。
コネクションの設定
フローを作る前に、Slackと接続するためのコネクションを以下の設定で新規作成しました。
「APIトークン」には、Slack側の Bot User OAuth Token の内容をペーストし、「チャンネル」には、投稿先のチャンネル名を設定してあります。
作成したフロー
フローはこのような内容になりました。
でんき予報サイトからCSVデータを取得する処理
この処理は、HTTPGetコンポーネントでCSVデータのURLを指定するだけで実現できました。
なお、接続先にはコネクションは使用せず、「URL」プロパティに「プロパティ式」を使って次の内容を指定しました。
https://www.tepco.co.jp/forecast/html/images/juyo-d1-j.csv?${uuid.toString("")}
ファイル名の後ろにクエリパラメータとしてUUIDを追加してあるのがポイントです。 ( ?${uuid.toString("")} の部分)
これは、完全に同じURLで複数回アクセスすると途中の経路でキャッシュされた古いデータが返ってくる可能性があるため、ユニークなURLを生成してキャッシュを回避するために追加しました。
CSVデータの中から必要なデータを取得する処理
この処理は、データレイアウトが若干複雑でしたので、以下のステップ①②③に分けて実現しました。
ステップ①:15行目から24行分を取得
ステップ②:使用率(%)の実績値が入っているレコードだけを抽出
ステップ③:「最後の1行」だけを抽出
図:データレイアウト
その3段階のデータをフィルタリングするステップを、4種類の方法を組み合わせて実現しています。詳しく見ていきましょう。
ステップ①:15行目から24行分を取得
・HTTPGetコンポーネントのストリームのプロパティで、15行目から読み取るように設定しました。
(フィルタリング方法1:CSVデータ取得時に、先頭から何行かを読み飛ばす方法)
・1つ目のRecordFilterコンポーネントで、24行分のレコードを抽出するように設定しました。
(フィルタリング方法2:ストリームのデータから、行数指定で必要な部分だけ抽出する方法)
ステップ②:使用率(%)の実績値が入っているレコードだけを抽出
・2つ目のRecordFilterコンポーネントを次のように設定しました。
(フィルタリング方法3:条件式を指定して、合致するデータとそうでないデータに振り分ける方法)
ステップ③:「最後の1行」だけを抽出
・RecordLoopコンポーネントとLoopEndコンポーネントを組みあわせて実現しました。
(フィルタリング方法4:1行ずつループをまわして、LoopEndの「出力形態」を「最後のストリーム」にすると、最後の1行だけが取得できるというテクニック)
メッセージを生成する処理
この処理は、マッパーの中で処理を作りました。
CSVから取得した値をembed関数に差し込んで、メッセージのテキストを生成する仕組みです。
電力使用率の基準値はフロー変数で管理していますので、変更したくなったら簡単に変えることができます。今回は、基準値を92(%)に設定しました。
各マッパー関数の設定は、次のようにしました。
ExtractString1:
「検索文字列」には半角コロン(:)を設定。
Embed1(上):
「データ」には
${input1} ${input2}時台の電力使用率は ${input3}% でした。
を設定。
Embed2(下):
「データ」には
供給力 ${input1}万kW、実績値 ${input2}万kW、予測値 ${input3}万kW。情報提供元: https://www.tepco.co.jp/forecast/
を設定。
Greater1:
Concat1:
BoolIf1:
Slackへ投稿する処理
今回作ったフローは、Slackへのテキストの投稿に加えて、電力使用率が基準値を超えていたときは「節電のお願い」を画像でも投稿するという仕組みにしました。
これを実現するためにSlackアダプターを使ったのですが、Slackアダプターには2種類のコンポーネントがあり、以下のような仕様になっています。
・SlackPostコンポーネント:テキストのみの投稿が可能
・SlackUploadコンポーネント:テキストと画像の両方を含む投稿が可能(画像ファイルの指定が必須)
SlackUploadコンポーネントでの画像ファイルの指定が必須ですので、画像が不要な場合にはSlackPostコンポーネントを使う必要があります。そのため今回のフローでは、基準値を超えているか(=画像が必要か不要か)をマッパー内で判定した結果を使って、BranchStartコンポーネントで処理を分岐させました。
BranchStart1:
SlackPost1:
「メッセージ」プロパティは、プロパティ式(右端の歯車アイコン)で設定してあります。文字列ではありません。文字列として「${flow.get(“メッセージ”)}」と設定した場合は、その「${flow.get(“メッセージ”)}」の文字列自体がSlackに投稿されてしまいますので、注意が必要です。
SlackUpload1:
上記と同様に、こちらも「メッセージ」プロパティはプロパティ式で設定してあります。一方、「アップロードファイルパス」プロパティは、固定のファイル名を指定しているだけなので、文字列で設定してあります。
スケジュール設定
サーバ負荷にも配慮して1時間に1回(毎時6分)に設定しました。 また、夜間は電力使用率が下がるので、8時~20時までの間だけ動くように設定しました。
フローの実行結果
フローを実行すると、このようにSlackに投稿されました!
このときは基準値を超えていたようで、設定通り画像つきで投稿されました。
電力使用率が92%未満になったタイミングでは、テキストのみで投稿されました。これも設定通りですね。
まとめ
今回、Web上からのデータ取得・加工・Slack通知までの流れを、簡単に実現することができました。
細かく見ていきますと、
・CSVファイルから必要な範囲の行だけを抽出
・CSVデータの「最後の1行」だけを抽出
・Embed関数を使った、文字列へのデータの埋め込み
・取得した数値を用いた条件分岐
・投稿内容によるSlackコンポーネントの使い分け
といった方法・テクニックのサンプルにもなっています。
この記事を読んでくださった皆様の、フロー開発のヒントになりましたら幸いです。