Skip to content

About

NFCカードで工程を打刻するスマホ単体の工数記録PWA(データは端末内のlocalStorageのみ)

Resources

Stars

0 stars

Watchers

0 watching

Forks

Latest commit

 

History

19 Commits

Folders and files

Repository files navigation

工数打刻(スマホ単体版)

Pixel 10 の Chrome だけで動く工数記録アプリ。サーバー不要。 NFCカードをかざして 社員・案件・工程 を打刻し、端末内に保存して集計する。 Google スプレッドシートに送れば、案件ごとの工数をグラフで比較できる。

公開URL: https://schokolade3.github.io/kosu-punch/

ファイル

  • index.html — アプリ本体(打刻・集計・記録修正・マスタ・書き出し)
  • sw.js — オフライン動作用(圏外でも起動できる)
  • manifest.webmanifest / icon.png — ホーム画面アプリ化用
  • gas/Code.gs — Google スプレッドシート側のスクリプト(任意)

セットアップ(スマホ側)

  1. Chrome で公開URLを開く
  2. メニュー →「アプリをインストール」または「ホーム画面に追加」
  3. 端末の設定で NFC を ON にする
  4. 起動後に「読み取り開始」を1回押す(Chromeの仕様でボタン起点が必須)

以後はホーム画面のアイコンから起動。圏外・機内モードでも打刻できる。

カードの考え方

カードは4種類。工程カードは案件をまたいで共通で使い回す(工程は案件ごとに大差ないため)。

種別 枚数の目安 役割
社員 人数分 かざすと「いま打刻する人」が切り替わる
案件 ブランク数枚 かざすと、その人の「いまの案件」が切り替わる
工程 工程数分 かざすと作業の開始/終了。これだけが時間を刻む
休憩 1枚 休憩の開始/終了(集計から控除)

推奨カード: NTAG213 / NTAG215。 登録は不要で、未登録カードをかざすと種別と名前の入力フォームが出る。

案件カードは付け替えて使い回す

案件が終わったら「マスタ」タブでその案件カードの割り当てを別の案件に変更する。 カードを増やさずに運用できる。

過去の記録は打刻した時点の案件のまま変わらない。 打刻イベントに社員・案件を 焼き込んで保存しているため、付け替えても履歴は書き換わらない。

打刻ルール

基本の流れは 社員 → 案件 → 工程。社員と案件は一度かざせば、変えるまで維持される。

操作 意味
社員カード 打刻する人を切り替える
案件カード その人の現在の案件を切り替える
工程カード その工程を開始(別工程が動いていれば自動で切替)
同じ工程カードを再度 その工程を終了
休憩カード 休憩の開始/終了
休憩中に同じ工程カード 休憩終了して作業再開
  • セッションは社員ごとに独立しているので、1台を複数人で共有しても各自の作業が並行して走る
  • 社員をかざす前に工程をかざすと弾かれる(誰の作業か確定しないため)
  • 8秒以内の同じカードの連続読み取りは無視される
  • カードが手元にない時は「カードなしで打刻」から選択できる

画面

  • 打刻 — 現在の社員/案件、経過時間、作業中の人の一覧。作業中は緑、休憩中は琥珀色
  • 集計 — 下記参照
  • 記録 — 打刻の削除・任意時刻への追加(打刻忘れの補正)
  • マスタ — カードの割り当て変更、案件/社員/工程の追加・編集
  • データ — スプレッドシート連携、CSV書き出し、バックアップ

集計で見えること(改善の当たりをつけるため)

表示 読み方
案件別 × 工程内訳 積み上げ棒。どの案件のどの工程が時間を食っているか
予定工数との差 案件に予定hを入れると予実差が出る。赤字案件の原因工程がわかる
工程別の合計(案件横断) 総時間が大きい工程ほど、改善が全体に効く
社員別のばらつき 同じ工程で人による差が大きい=標準化や教育の余地

Google スプレッドシート連携(任意)

端末内だけでも集計できるが、複数端末をまとめる・大きなグラフで見るならこちら。

1. スプレッドシートを用意する

  1. 新しいスプレッドシートを作る
  2. 拡張機能 → Apps Script を開く
  3. gas/Code.gs の中身を貼り付けて保存
  4. プロジェクトの設定 → スクリプト プロパティ → SHARED_TOKEN に推測されにくい文字列を設定
  5. デプロイ → 新しいデプロイ → 種類「ウェブアプリ」
    • 次のユーザーとして実行: 自分
    • アクセスできるユーザー: 全員
  6. 発行されたウェブアプリの URL を控える

2. アプリ側に設定する

「データ」タブに URL と SHARED_TOKEN を入力して保存。「今すぐ同期」で送信される。 「打刻時に自動同期」を ON にすると、打刻のたびに送られる。

URL とトークンは端末内(localStorage)にのみ保存され、リポジトリには含まれない。 このリポジトリは公開されているため、コードに直接書き込んではいけない。

3. できるシート

シート 内容
events 打刻の生ログ(id で重複排除。同じものを再送しても二重にならない)
sessions 作業のかたまり(開始・終了・休憩・正味)
summary_案件x工程 案件×工程のピボット + 積み上げ棒グラフ、予定h と差
summary_工程 工程別の案件横断合計
summary_社員x工程 工程ごとの社員別・1回あたり平均

集計シートは同期のたびに作り直される。手を入れるなら別シートにコピーしてから。

通信について

圏外のときは端末に貯まり、次の同期でまとめて送られる。送信済みの id を端末が 覚えているので、途中で切れても二重計上しない。端末で打刻を削除すると、次の 同期でシート側からも消える。

M5Dial 版(スマホ不要の据置端末)

作業場に置きっぱなしにできる打刻専用端末。M5Dial の内蔵 RFID でカードを読み、 Wi-Fi で直接スプレッドシートに送る。スマホもブラウザも要らない。

  • dial/main.py — M5Dial 用アプリ(MicroPython)
  • tools/dial_setup.py — PC からアプリと接続設定を書き込むツール

導入

  1. M5Dial を USB で PC に繋ぐ(COM ポートを掴んでいるものは閉じておく)
  2. py -3.9 tools/dial_setup.py を実行し、GAS の URL とトークンを入力する (トークンは伏せ字入力。端末の /flash/kosu_cfg.json にのみ保存される)
  3. 再起動後、Wi-Fi 接続 → 時刻合わせ → マスタ取得 まで自動で走る

Wi-Fi の認証情報は本体の NVS(ssid0/pswd0)から読むので、UIFlow2 で 一度設定してあれば入力は不要。

メモリの制約(ここを外すと通信できなくなる)

ESP32-S3 の ESP-IDF ヒープは TLS と取り合いになる。mbedTLS は合計 40KB 前後を 要求するが、次の3つのどれかを踏むと足りず ENOMEM で通信できなくなる。 いずれも実機で計測して確認した。

罠 失うヒープ 対処
ソースのまま /flash/main.py に置く 65KB .mpy に事前コンパイルし /flash/libs/kosu.mpy に置く
M5 を import してから Wi-Fi を張る 45KB Wi-Fi を先に張り、あとで load_ui() を呼ぶ
ntptime で時刻を合わせる 19KB GAS 応答の Date ヘッダで合わせる

tools/dial_setup.py はこの3つを踏まないように書き込む。手で入れ替えるときは /flash/main.py を import kosu の1行だけにすること。

なお ソフトリブート(Ctrl-D)では ESP-IDF ヒープが解放されない。開発中に 繰り返すと枯渇して誤診のもとになるので、計測は machine.reset() で行う。

boot.py を外してある

この端末では UIFlow2 の起動処理(/flash/boot.py)を /flash/boot_uiflow.py に 退避してある。startup() がネットワークを張るぶんヒープを消費し、アプリが 自前で張る Wi-Fi と二重になるため。打刻専用機なので UIFlow2 のクラウド接続は 使わない。

UIFlow2 で開発し直したくなったら戻せる。

import os; os.rename('/flash/boot_uiflow.py', '/flash/boot.py')

元のアプリも /flash/main_demo.py(機能デモ) と /flash/main_uiflow.py (ブロックプログラム) に残してある。

起動ログ

heap ... の行は意図的に出している。TLS が通らなくなったときに、どの段階で ヒープを失ったかが分かるようにするため。シリアルにしか出ないので実運用の 邪魔にはならない。

Wi-Fi の接続先を変える(本体+スマホ)

引っ越しやルータ交換で接続先を変えるとき、PC を繋がずに設定できる。 SSID は本体のダイヤルで選び、パスワードだけスマホから入力する。 240x240 の丸画面で文字入力をさせないための作り。

  1. 本体の側面ボタンを長押し → 周囲の SSID 一覧が出る
  2. ダイヤルで接続先を選び、押して決定(「やめる」で中止)
  3. 本体が設定用の電波を出す。画面に出る 3 つを使う
    • Wi-Fi 名: kosu-dial
    • パスワード: 画面の8桁(端末ごとに固定)
    • URL: http://192.168.4.1
  4. スマホをその Wi-Fi に繋ぎ、ブラウザで上記 URL を開く
  5. パスワードを入れて「保存して接続」 → 本体が再起動して接続する
  6. スマホは元の Wi-Fi に戻す

設定用の電波は WPA2 で保護してある。開放にすると近くの誰でも設定画面を 触れてしまうため。5分間なにも来なければ自動で閉じる。

一度繋がった接続先はパスワードを覚える。 端末の /flash/kosu_wifi.json に 新しい順で最大8件残る(リポジトリには入らない)。

  • 一覧では覚えている接続先が先頭に緑で出て、下に「記憶済」と表示される。 選ぶだけでその場で繋がり、スマホも再起動も要らない
  • 保存したパスワードで繋がらなければ(ルータ側で変えたなど)、 そのまま上の手順 3 に進んで入力し直せる
  • 起動時にいつもの接続先が見つからなければ、覚えている他の接続先を探して自動で繋ぐ。 起動後も 5 分ほど繋がらない状態が続くと同じことをする (スキャン中の数秒は止まるので、直前 20 秒に打刻があれば見送る)

接続できないときも打刻は続く。 起動時に繋がらなくても設定画面には入らず、 30秒ごとに裏で接続を試し続ける。繋がった時点で溜まった打刻がまとめて送られる。 (実機では、起動時の待ち時間に間に合わず数十秒後に繋がることがあった)

カードの割り当て

未登録のカードをかざすと、その場で割り当て画面になる。

  1. ダイヤルを回して 社員 / 案件 / 工程 / 休憩 を選び、側面ボタンで決定
  2. 続けて名前の一覧が出るので、回して選んで決定
  3. 割り当ては端末に保存され、次の同期でスプレッドシートの cards シートにも記録される

名前の一覧はスプレッドシートの master_employees / master_processes / projects から取得する。まだ空なら、これらのシートに手で行を足す(id と name の2列)。 スマホ版を使っていれば、打刻に出てきた社員・工程が自動で拾い上げられる。

画面

外周リングの色が状態を表す。灰=待機 / 緑=作業中 / 琥珀=休憩中 / 青=割り当て中。 中央に工程名、その下に案件名と経過時間。左上に ONLINE +3 のように未送信件数が出る。

側面ボタンを押すと手動で同期する。作業中は約60秒ごとに自動で送られる。

通信について

圏外でも打刻は /flash/kosu_queue.jsonl に貯まり、繋がったときに送られる。 送信できた分だけキューから消えるため、途中で切れても二重計上しない。

GAS は POST を 302 で返し、結果は Location への GET で受け取る仕様のため、 アプリはリダイレクトを GET で追っている(POST で追うと 405 になる)。

注意

データはこのスマホの中にある。Chromeのサイトデータを削除すると記録も消える。 週に1度「データ」タブからバックアップを保存し、ドライブ等に置いておくこと (スプレッドシート連携をしていれば、そちらにも残る)。

社員別の集計は、標準化や教育の材料として使うことを想定している。個人の評価に 転用すると打刻の正確さが失われやすいので、運用の取り決めは事前に共有しておくこと。

更新するとき

index.html を直したら、sw.js のキャッシュ名(const C)も必ず上げる。 上げないと端末が古い画面を表示し続ける。

About

NFCカードで工程を打刻するスマホ単体の工数記録PWA(データは端末内のlocalStorageのみ)

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages