Slide 1

Slide 1 text

個人開発 / IoT / 要件定義 70万円 無人店舗のエアコンをIoT化して、 月 節約した話 〜 ひとりで要件定義・設計・値付けまでやった話 〜 r-sugi X: @rsugi8

Slide 2

Slide 2 text

自己紹介 r-sugi フリーランスエンジニア 個人開発で予約システムを提供・運用 X: @rsugi8 02

Slide 3

Slide 3 text

前提 登場人物は2人だけ 自分(エンジニア) 開発 / 運用 / 保守 / 値付け 間にPdMもチームもいない 相談者(発注者・PO) 店舗事業の責任者 03

Slide 4

Slide 4 text

相談者のビジネス 美容系の無人店舗 × LINE予約 01 02 03 04 入店用のPINを受け取る スマートロックを解錠 この時間を快適に保ちたい 最後まで無人で完結 LINEで事前予約 PINで入室 自分が提供しているもの(toB → toC) オーナーに提供し、利用者(お客さん)が使うLINE 予約・会員管理システム 美容系機器を利用 退室 だから手元にあるもの 全店舗の予約データ = 人がいる時間がわかる 04

Slide 5

Slide 5 text

こういう店舗です 無人の店舗。入室から退室までスタッフは介在しない 予約・入室・利用・退室の流れ(イメージ図) 05

Slide 6

Slide 6 text

経緯 3年で20店舗から90店舗へ 20 3年前 人海戦術で運用 店舗 人海戦術の内訳 → 予約・会員管理のSaaS を提供 90 現在 店舗 大体40の都道府県に1店舗以上 会員登録 予約・クーポン管理 リモートロック 別々のサービスを使い、スタッフが管理画面を行った り来たりしていた 現在 SaaSアプリですべて一元管理できるようになった(+ LINE会員登録) 06

Slide 7

Slide 7 text

相談内容 「無駄にエアコンをONにしていて経費がかさんで いる」 スイッチボットのスケジュールは固定のON/OFFしか組めない。予約に応じて動かしたい。 07

Slide 8

Slide 8 text

空稼働している時間 少し人気のある店舗の予約状況。空白=誰もいないのにエアコンが動いている時間 08

Slide 9

Slide 9 text

新規出店時はさらに大きい 新規出店時。半分以上が空稼働 1日1店舗なら誤差。でも90店舗 × 30日だと? 09

Slide 10

Slide 10 text

要件定義 要望 → 要求 → 要件 電気代を減らしたい 要望 人がいる時だけ稼働させたい / 稼働時間を制限したい 要求 要件 センサー+スマートリモコンでIoT制御、Web管理画面で制御・監視 10

Slide 11

Slide 11 text

作らない判断 落とした要望 北海道 夏でも涼しい 外気温がまるで違う 沖縄 真夏は連日30℃超 要望:地域ごとに x分前ON / y分後OFF を変えたい ↓ 要件から外しました。 結果的に、これが後の設計をかなり楽にしています 11

Slide 12

Slide 12 text

お題 A 13:00〜13:30の予約。 何分前にONにして、 失敗したらどうリトライしますか? 15 秒、考えてみてください

Slide 13

Slide 13 text

与えられた制約 この条件の中で設計する worker:顧客向け画面 worker:管理画面 512MB 512MB 非同期処理用の ワーカーは なし MySQL 1GB × 1インスタンス 2つのworkerが共有=単一障害点 実行基盤 Heroku Scheduler は「10分に1回」 「毎時n分」「毎日h時」の3択のみ 外部依存 SwitchBot API(外部API・頻繁に落ち る、不安定) ビジネス制約 エアコンが動作しないとクレーム率が 高い

Slide 14

Slide 14 text

答え合わせ A リトライは簡易的にした 同じ操作を2回打つ = リトライ相当 ON ON 予約枠 ── 利用中 OFF OFF 本来ここでON 念のためもう一度 この30分だけ動いていればいい 本来ここでOFF 念のためもう一度 12:40 12:50 13:00 – 13:30 13:50 14:00 操作が冪等だから成立する 14

Slide 15

Slide 15 text

運用設計 線を引いた先は、人間が引き取る 2回とも失敗したら? ↓ 自動では諦める ↓ 運営スタッフが Slack を見て手で対応 容認してもらった範囲 特定の店舗で機器がオフライン→送信失敗になりがち。これはカバーできないと伝えて容認しても らった 「1回の失敗までは吸収する。それ以上は対応しない」と決めたので 15

Slide 16

Slide 16 text

お題 B これをリリースする前に、 どんな懸念を洗い出しますか? 15 秒、考えてみてください

Slide 17

Slide 17 text

懸念 ① 共有DBを巻き込む 顧客向け画面 管理画面バッチ MySQL 1GB 1インスタンスを共有 10分に1回、管理画面側のバッチがDBを叩く ↓ N+1やスロークエリが起きると顧客向け画面まで巻き込 む 対応 クエリ2本で取得し、配列操作で解決 事故ったら1日吹き飛ぶな、と思いながら書いた 17

Slide 18

Slide 18 text

懸念 ②③ ログとAPI異常 懸念 ② ログ肥大 (1ヶ月3万レコード) 対応 保存1ヶ月+バッチ削除 懸念 ③ SwitchBot API の異常 対応 想定外ステータスで運営スタッフにSlack通知 18

Slide 19

Slide 19 text

施策前後の比較 70万円 月 削減(50店舗時点) 現在は90店舗なので、 効果はさらに大きい 19

Slide 20

Slide 20 text

お題 C この機能、 いくらで請求しますか? 15 秒、考えてみてください

Slide 21

Slide 21 text

答え合わせ C 価値ベースで値付けした 工数ベース かかった時間 × 単価 価値ベース 生み出した価値に対する対価 「月x万円の経費削減が見込まれるので、 この機能追加で x万円 をいただきたいです」 21

Slide 22

Slide 22 text

ただし、前提があります 削減額を事前に試算できた 予約データを持っていたので空稼働時間が計算できた 効果検証は電気代の実額を見た 予測ではなく実測で答え合わせできている 断られたこともある 毎回通るわけではない 交渉相手は3年付き合いのあるPOひとり。初回の取引でいきなりできる話ではない 22

Slide 23

Slide 23 text

まとめ 1 2 3 作らない判断も設計のうち 40近い都道府県に散らばっていても固定値。1年運用できている 制約は前提として引き受ける 10分刻みのcron 2本でリトライは実現できる。線を引いた先は人間が引き取る toBの機能追加は売上か経費削減に紐づく 紐づくなら価値ベースで値付けできる 23