「体調が悪い」だけ見ていても足りなかった。HTML + PowerShellで「元気すぎる」も検知するセルフモニタリングアプリを作った
はじめに
以前から、自分の体調を管理するためのアプリを自作して使っていました。
睡眠時間や疲労感などを毎日記録して、
- 疲れている
- 気分が落ちている
- 睡眠が減っている
- 仕事がしんどくなっている
といった変化を見つけるためのものです。
それなりに記録もしていたので、
これを使っていれば、大きく体調を崩す前に気づけるだろう
と思っていました。
しかし、実際には体調を崩し、療養することになりました。
そこで改めて振り返ってみると、以前の体調管理アプリにはかなり大きな設計上の欠陥がありました。
「体調が悪くなる方向」しか監視していなかったことです。
今回、自分に最初に起きていた変化は、
疲れて動けない
気分が落ちる
仕事が進まない
ではありませんでした。
むしろ逆でした。
活動量が増える
頭の回転が速くなる
自信が出る
仕事がどんどん進む
という状態から始まっていました。
当時の自分からすると、
「かなり調子がいい」
としか見えませんでした。
むしろ、
最近かなり仕事ができているな
くらいに考えていました。
でも振り返ってみると、そのあと、
活動性が高まる
↓
仕事をさらに抱える
↓
頭が休まらなくなる
↓
緊張が強くなる
↓
苛立ちが増える
↓
疲弊する
という流れに入っていました。
ここで問題だったのは、単に「元気だったこと」ではありません。
普段とは明らかに違うレベルまで活動性が上がっていたのに、それを体調の変化として認識していなかったことです。
そして以前の自作アプリも、
悪化 = 異常
元気 = 正常
という考え方だったため、この変化を異常として検知できませんでした。
これが今回セルフモニタリングツールを作り直した一番大きな理由です。
もう一つ問題がありました。
忙しくなるほど、体調管理アプリの記録を忘れることです。
複数案件や突発対応が増えてくると、
仕事
仕事
仕事
仕事
↓
体調記録はあとで
となります。
つまり、
忙しくなる
↓
体調管理が重要になる
↓
忙しいので記録を忘れる
↓
データがなくなる
↓
異常を検知できない
という構造になっていました。
そこで今回は、
- 悪くなる方向だけでなく、上がりすぎる方向も監視する
- 記録しなくなったこと自体も監視する
という2つを大きな設計方針にしました。
それが今回作ったセルフモニタリングツール Sentinel です。
Sentinelとは
Sentinelは、自分の状態を記録して、
「下がりすぎ」だけでなく「上がりすぎ」も見る
セルフモニタリングツールです。
さらに、アプリ本体とは別にWindows側へ監督役を置き、
記録しなくなったこと自体も検知します。
構成としては比較的小さく、
HTML
+
JavaScript
+
localStorage
+
PowerShell
+
Windows タスクスケジューラ
+
cmd
で動いています。
サーバーやDBは使用していません。
ソースコード
個人情報や個人の体験に依存する初期文言を一般化した公開版を、GitHubで公開しています。
GitHub: konnichiwa-akira/sentinel-self-monitoring
現在の公開リポジトリに含めているのは、ブラウザだけで動く Sentinel.html と使い方の手引きです。
この記事で説明するPowerShellの監督役やWindowsの自動化スクリプトは、個別環境への依存が大きいため、現時点の公開版には含めていません。
以前の体調管理アプリでは「下方向」しか見ていなかった
以前のアプリで監視していたのは、主にこちらでした。
睡眠が減った
疲労が増えた
気分が落ちた
仕事ができなくなった
図にすると、
通常
|
|
-----------------------
| |
不調 活性化
↑ ↑
監視する 見ていない
という感じです。
これは普通に考えると、それほど不自然ではありません。
「体調を崩す」と聞くと、
元気がなくなる
疲れる
寝られない
動けなくなる
方向を想像しやすいからです。
しかし、自分の場合はそうではありませんでした。
一番見逃していたのが「活性化」だった
今回の振り返りで、一番重要だったのがここです。
体調を崩す前の自分には、
活動量が増える
思考が速くなる
自信が強くなる
仕事を次々処理する
他人への指摘が増える
といった変化がありました。
でも当時は、
活動量が増える
↓
仕事が進む
↓
調子がいい
と解釈していました。
頭の回転が速くなっても、
思考が速い
↓
いつもより仕事ができる
↓
調子がいい
です。
さらに、他人への苛立ちが増えていても、
当時は、
以前より問題点に気づけるようになった
くらいに考えていました。
つまり、
異常を異常として認識できていませんでした。
これがかなり厄介でした。
「元気」と「活性化」は同じものとして扱わない
そこでSentinelでは、
元気だから正常
とは判定しません。
見るのは、
「普段の自分と比べてどうか」
です。
例えば普段、
活動量 3
思考速度 3
自信 3
くらいの人が、
数日間、
活動量 5
思考速度 5
自信 5
となっていた場合、
本人の感覚としては、
絶好調
かもしれません。
でもSentinelでは、
普段よりかなり上振れている
という別の見方をします。
ここが以前のアプリとの大きな違いです。
Sentinelでは「活性化」と「不調」を分けて数える
Sentinelでは状態を大きく、
活性化
不調
の2方向に分けています。
活性化側
例えば、
活動量が増えている
思考の速さが上がっている
自信が上がっている
焦りが増えている
頭が休まらない
仕事の抱え込みが増えている
といった変化です。
不調側
一方、
疲労
緊張
だるさ
集中の乱れ
生活・仕事の機能低下
などはこちらです。
画面上ではイメージとして、
活性化 3 / 不調 0
のように見ます。
あるいは、
活性化 0 / 不調 4
ということもあります。
さらに、
活性化 2 / 不調 3
という両方が出ている状態もあります。
Sentinelではこれを単純な一本の「体調スコア」に潰さず、別々に残します。
なぜ活性化を別にしたのか
例えば、
活動量が高い
思考が速い
自信がある
という3項目だけを見ると、
普通の健康管理アプリではプラス評価になりそうです。
でも、
睡眠が減っている
休憩を取らない
仕事をどんどん増やす
頭が休まらない
まで同時に起きていた場合は、意味が変わってきます。
だからSentinelでは、
元気そうか
ではなく、
普段の自分と比べて
どの方向にズレているか
を見るようにしました。
ベースラインを作る
そのために、最初の一定期間をベースラインとして記録します。
例えば、
睡眠
疲労
緊張
活動量
思考の速さ
苛立ち
などです。
普段の自分
↓
ベースライン
↓
現在の自分
↓
差分を見る
という構造です。
一般的な人の正常値ではなく、
自分の通常状態との比較
を重視しています。
活性化は1日だけでは判断しない
当然ですが、
今日は仕事が進んだ
だけで警告されても困ります。
そこでSentinelでは、一定期間の変化も見ています。
例えば、
活動量
思考速度
自信
焦り
などが、
1日だけ高い
のではなく、
2週間かけて上がり続けている
場合も検知します。
イメージとしては、
3 3 3 3 4 4 4 4 4 5 5 5 5 5
のような変化です。
本人は毎日少しずつ変わるため気づきにくいですが、
時系列で見るとかなり違います。
この「変化の傾き」を見る機能も入れました。
「前回と同じ経路」に入っていないかも見る
さらに今回の振り返りでは、
単純に状態が悪化したのではなく、
活性化
↓
緊張
↓
苛立ち
↓
疲弊
という順番がありました。
そこでSentinelでは、
活性化優位
↓
数日継続
↓
緊張・疲弊側へ移行
した場合も別に見ています。
つまり、
今日どうだったか
だけではなく、
最近どういう経路を通っているか
も見るようにしました。
SEだと「活性化」を見逃しやすいと感じた
これは今回かなり考えた部分です。
SEの仕事では、
障害対応
問い合わせ
突発作業
複数案件
締切
リリース
設計
レビュー
資料作成
などが重なる場面があります。
そして、一時的に処理能力が上がっていると、
仕事としてはむしろうまく回ってしまいます。
いつもより仕事が進む
↓
周囲から評価される
↓
さらに仕事を引き受ける
↓
まだ処理できる
↓
さらに増やす
ということもあります。
自分の場合、
「仕事ができなくなる」より前に、「仕事ができすぎているように感じる期間」がありました。
ここはかなり重要でした。
「まだ仕事ができているから大丈夫」が必ずしも安全側ではなかった
以前の自分は、
仕事ができている
↓
問題なし
と考えていました。
しかし今は、
仕事ができている
だけでは判定材料として足りないと考えています。
例えば、
最近妙に仕事が進む
休憩しなくても平気に感じる
次々仕事を引き受けている
頭の中がずっと仕事モード
以前より他人に苛立つ
帰宅後も仕事の思考が止まらない
睡眠時間が少しずつ短くなっている
といったものが同時に起きているなら、
少なくとも、
絶好調だから問題なし
だけではなく、
普段の自分と違いすぎないか
を見るようにしています。
ただし、記録アプリには根本的な弱点がある
ここまで作っても、まだ問題があります。
Sentinelを開かなければ動きません。
Sentinelを開く
↓
記録
↓
判定
↓
警告
なので、
Sentinelを開かない
だけですべて止まります。
そして実際、
仕事が忙しくなるにつれて記録を忘れることがありました。
そこで発想を変えました。
記録がないこと自体をデータにします。
「記録していない」ことも状態変化として扱う
Sentinelでは、
記録なし
を単なる入力ミスとして扱いません。
例えば、
記録のない日がある
↓
データとして残す
2日続く
↓
記録が途切れていると判定
さらに続く
↓
監督役が介入
という形です。
これは、
ちゃんと記録しろ
と自分を責めるためではありません。
むしろ、
忙しくて記録できない
という状態そのものが、
現在の余裕のなさを表している可能性があります。
そのためSentinelでは、
未記録は失敗ではなくデータ
として扱います。
PowerShellで「監督役」を作った
Sentinel.htmlだけでは、ブラウザを閉じると何もできません。
そこで別プロセスとして、
Sentinel_監督役.ps1
を作りました。
Windowsのタスクスケジューラから定期的に実行します。
朝
昼
夕方
夜
終業
のタイミングで状態を確認します。
構成はこうです。
Windows
│
├─ スタートアップ
│ ↓
│ Sentinel.html
│
├─ タスクスケジューラ
│ ↓
│ Sentinel_監督役.ps1
│
├─ 終業.cmd
│
└─ Sentinel.html
│
└─ sentinel-status.json
↓
Sentinel_監督役.ps1
HTMLとPowerShellは直接通信させない
Sentinel本体とPowerShellは直接通信させていません。
Sentinel側が、
sentinel-status.json
という小さな状態ファイルを書き出します。
PowerShell側はそれを読みます。
詳細な体調記録をPowerShellへ渡す必要はないため、
詳細記録
↓
localStorage
と、
監督に必要な最低限の状態
↓
sentinel-status.json
↓
PowerShell
を分離しています。
記録しないほど介入を強くする
監督役は段階的に動きます。
記録なし
↓
Sentinelを開く
まだ記録なし
↓
画面通知
さらに続く
↓
強い通知
長期間続く
↓
相談用メールの下書きを作る
単純なリマインダーではなく、
未記録期間に応じて介入レベルを変える
ようにしています。
警告を無視することも設計対象にした
もう一つあります。
正しい警告が出ても、自分が行動するとは限りません。
例えば、
今日は残業しない
と表示されても、
でも今日だけは仕方ない
となる可能性があります。
次の日も、
今日だけ
になるかもしれません。
そこで、
警告した
だけではなく、
必要な対応を実行した
ところまで記録します。
一定期間対応しない状態も、別のトリガーになります。
一部の条件は自分だけで解除できない
以前、
自分では調子がいいと思っていた
こと自体が問題だったため、
一部の状態は、
でも自分では大丈夫
だけで解除できるようにはしていません。
イメージとしては、
if (強い警戒状態が続く) {
相談が必要な状態として扱う;
}
if (必要な対応が実行されていない) {
相談が必要な状態として扱う;
}
です。
「相談した方がいいかもしれません」ではなく、
事前に決めた条件を満たしたら、
次の行動へ進む
という考え方です。
終業そのものも仕組みに入れた
毎日、
Sentinelを忘れず開こう
と考えるだけでは続かなかったため、
終業.cmd
も作りました。
普通のシャットダウンの代わりに使います。
仕事終了
↓
終業.cmd
↓
Sentinel
↓
記録
↓
シャットダウン
という流れです。
アプリを、
思い出したら使うもの
ではなく、
仕事を終える手順
に組み込みました。
完全オフラインにした
扱うデータの性質上、Sentinel本体は外部通信を行わない構成にしています。
Sentinel.html
↓
JavaScript
↓
localStorage
です。
サーバーもDBもありません。
グラフもSVGで描画しています。
localStorageなのでバックアップも必要
当然ですが、
ローカルだから絶対安全
というわけではありません。
例えば、
ブラウザデータ削除
PC故障
別ブラウザを使用
環境変更
などではデータを失う可能性があります。
そのため、
バックアップ
暗号化バックアップ
復元
復元テスト
も実装しています。
レポートは相手によって内容を変える
保存したデータを全員へ見せる構成にもしていません。
現在は、
本人
上司
産業医
保健師
人事
向けに表示する内容を変えています。
例えば上司向けなら、
業務負荷
必要な調整
合意事項
を中心にします。
保存する情報と、
共有する情報
は別物として扱っています。
自己テストも入れた
判定条件が増えてきたため、HTML内部に自己テストも入れました。
例えば、
正常状態では警告しない
ベースライン不足時に
確定判定しない
活性化条件を検知する
強制条件が成立すれば動く
未実行の対応を検知する
などです。
現在は29件あります。
HTML 1ファイルの個人ツールですが、
状態判定が増えると普通に回帰テストが必要になりました。
ファイル構成
手元で運用している全体構成は以下です。
Sentinel/
│
├─ Sentinel.html
│ └─ アプリ本体
│
├─ Sentinel_セットアップ.cmd
│ └─ スタートアップ・週次タスク登録
│
├─ Sentinel_監督役.ps1
│ └─ 未記録・未対応を検知
│
├─ Sentinel_監督役セットアップ.cmd
│ └─ 監督役をタスクスケジューラへ登録
│
└─ 終業.cmd
└─ 終業時の記録
なお、GitHubで公開している匿名版は Sentinel.html、Sentinel_使い方と運用.html、README.md、LICENSE、.gitignore の5ファイルです。
PowerShellやcmdは個別のWindows環境・運用ルールに依存するため、現在は設計の説明のみとしています。
Node.jsなどは不要です。
WindowsとEdgeまたはChromeを使う構成です。
同じように働いているSEの方へ
この記事を書こうと思った理由の一つです。
Qiitaを見ているSEの中には、
複数案件がずっと並行している
障害対応が続いている
突発作業が増えている
休日も仕事を考えている
最近妙に仕事が進む
休憩を取らなくても平気に感じる
以前よりイライラする
でも仕事自体はできている
という方もいるかもしれません。
もちろん、これだけで何かを判断できるわけではありません。
ただ、自分の場合は、
仕事ができなくなった
より前から変化が始まっていました。
しかもその期間を、
絶好調
だと思っていました。
以前は、
調子が悪くない
↓
大丈夫
でした。
今は、
普段の自分と比べてどうか
を見るようにしています。
仕事ができていることと、
無理なく安定して働けていることは、
必ずしも同じではないのだと思います。
作ってみて一番変わった考え方
最初は、
正しく体調を判定する
ことが最重要だと思っていました。
でも、作り直してみると、それだけでは足りませんでした。
必要だったのは、
記録する
↓
上下両方向の変化を検知
↓
警告する
↓
行動する
↓
行動しなければ検知
↓
記録しなくなっても検知
まで含めた仕組みでした。
そして一番大きかったのは、
「悪くなったときだけが異常ではない」
と考えるようになったことです。
今後
GitHub公開用の匿名版は公開できたので、今後は、
- PowerShell監督役の汎用化と、公開範囲の検討
- 個人設定の外部ファイル化
- 初期設定の簡略化
- テスト追加
- バックアップ改善
- データ移行改善
- 判定ロジックの継続的な見直し
などを進める予定です。
公開版の更新は、GitHubリポジトリで管理します。
まとめ
以前から体調管理アプリを自作していました。
しかし実際に体調を崩して振り返ってみると、
一番大きな問題は、
「悪くなる方向しか見ていなかった」
ことでした。
実際には、その前に、
活動量が上がる
思考が速くなる
自信が上がる
仕事を増やす
という活性化側の変化がありました。
しかし本人も以前のアプリも、
元気 = 正常
として扱っていました。
そこでSentinelでは、
不調
+
活性化
+
仕事の負荷
+
長期的な変化
+
前回と似た遷移
+
未記録
+
必要な対応の未実行
まで見るようにしました。
技術的には、
HTML
+
JavaScript
+
localStorage
+
PowerShell
+
Windows タスクスケジューラ
という小さな構成です。
今回作りたかったのは、高機能な健康管理サービスではありません。
「自分では大丈夫だと思っているときにも、普段との違いを機械側から指摘してくれる仕組み」
です。
さらに、自分がその仕組み自体を使わなくなった場合にも、
記録していない
という事実を検知します。
同じように、
仕事が忙しくなっている方、
最近少し無理をしている気がする方、
今は働けているけれど以前と何か違うと感じる方、
再び大きく体調を崩さないためにセルフモニタリングを考えている方、
そして単純に、
「人間が運用をサボる前提でシステムをどう作るか」
に興味がある方にも、設計の一例として参考になればと思います。
※ Sentinelは医療機器ではなく、診断・治療・就業可否を判断するためのものではありません。個人の記録をもとに状態の変化を確認し、あらかじめ決めた行動を実行するための補助ツールとして作成しています。


