視覚で伝える時間管理:SwitchBot電球で子供のゲームタイマーを作ってみた

M10i
2025-08-26
2025-08-26

はい、M10iです。
今日はいつもと違う方向から攻めた話題です。

表題通りなんですが・・・子育てされてる皆様。
特に小学生や未就学児童の子をもつ皆様っっっ!
子供のタブレットやゲームの時間ってどうやって管理されてますか??

うちはNintendoSwitchは、みまもり機能でプレイ時間の制限をいれてます。
が、それ以外タブレットなどの閲覧時間って管理が難しいんですよね。

平日は〇時~〇時まではタブレットやゲームOKだよって決めています。
タブレットやゲームOKの時間だと長いのでうちでは「電子モン時間」て呼んでますw

最初は簡単に18時~19時までなどとシンプルだったのですが
子供二人に増え、それぞれが習い事に行くようになるとパターンが複雑化してきました。
火曜日と木曜日は上の子習い事があるから18時半~19時と20時~20:30で・・・
土曜日は下の子の習い事があるから16時~17時は上の子だけ・・・
土日は多めに・・・etc、etc。

パターンを書き出して冷蔵庫に貼ってみたものの、下の子未就学児にはまだ読めない・・・・

そして二人の子供の「次の電子モン時間何時から????」の波状攻撃。


もーーーーーーーー!!!


ってことで、「子供でもわかる視覚情報による時間管理」を考えました!
もともとM10iの趣味でリビングの電球はswitchBotのスマート電球なのでそのまま使いました。

スマート電球とは?

スマート家電の一種でスマホからの操作でオンオフ、色、明るさの変更などが
できるお役立ちアイテムです。アレクサ連携しておくと口頭でオンオフ出来るし色も変えれます。
スケジュール登録もできるので、毎朝7時にオンにする毎晩23時にオフなどしておくと便利です。

では今回何をしたのか?ですがいたって簡単。
視覚情報による時間管理なんて格好つけましたが

「タブレットやスマホ、ゲームOKの時間の間だけ照明の色を変える」

たったこれだけです。
アプリからスケジュール登録できるやんって思うでしょ?アプリは最大5個までです☆
曜日、時間毎にオンオフ入れたら恐ろしい数の登録が必要です・・・足りない・・・。

【SwitchBot】雨が降りそうなときに廊下ライトの色を変えてお知らせする機能を作る
って素敵記事があったのをそのまま参考にしてます。こちらではGitHub Actionsからスケジュール
実施していますが、M10iはラズパイからcronで実施させました。

全体の流れは以下となっています。

  1. APIにアクセスするためのトークンとシークレットキーを取得
  2. デバイスのIDを取得
  3. スマート電球の色を変えるコードをPythonで書く
  4. cronでスケジューリング


では手順です。
最初にアプリの開発者モードからトークンとシークレットkeyを抜き出しておきます。
やり方はちょっと裏技っぽくて好きなのですが、SwitchBotの設定を開き、
アプリのバージョンを10回タップします。
sc1-1
すると隠しメニューの「開発者向けオプション」が表示されます。
(M10iはもう表示しちゃったので出っぱなしですが)
sc2
ここでトークンクライアントシークレットを取得します。

次に、switchbotのデバイスIDを抜き出します。
https://github.com/OpenWonderLabs/SwitchBotAPI#how-to-sign
ここを参考にデバイス一覧を取得します。コードのtokenとsecretの部分に
①のトークンクライアントシークレットを入れて実行します。

# Declare empty header dictionary
apiHeader = {}
# open token
token = 'トークン
# secret key
secret = 'クライアントシークレット
nonce = uuid.uuid4()
t = int(round(time.time() * 1000))
string_to_sign = '{}{}{}'.format(token, t, nonce)

string_to_sign = bytes(string_to_sign, 'utf-8')
secret = bytes(secret, 'utf-8')

sign = base64.b64encode(hmac.new(secret, msg=string_to_sign, digestmod=hashlib.sha256).digest())
print ('Authorization: {}'.format(token))
print ('t: {}'.format(t))
print ('sign: {}'.format(str(sign, 'utf-8')))
print ('nonce: {}'.format(nonce))

#Build api header JSON
apiHeader['Authorization']=token
apiHeader['Content-Type']='application/json'
apiHeader['charset']='utf8'
apiHeader['t']=str(t)
apiHeader['sign']=str(sign, 'utf-8')
apiHeader['nonce']=str(nonce)

jsonのレスポンスが返ってきますのでスマート電球のデバイスIDを控えます。

{
 "statusCode": 100,
 "body": {
 "deviceList": [
 {
 deviceId: 'XXXXXXXXXXXX',
   deviceName: 'スマート電球 5A',
   deviceType: 'Color Bulb',
   enableCloudService: true,
   hubDeviceId: 'XXXXXXXXXXXX' 
 }
 ]
 },
 "message": "success"
}

これでAPIを呼ぶためのアイテムが整ったので以下コード。

electric_time.py(色を変える)

formatter = "[%(levelname)-8s] %(asctime)s %(name)-12s %(message)s"
logging.basicConfig(level=logging.INFO, format=formatter)
logger = logging.getLogger(__name__)

load_dotenv(".env")

ACCESS_TOKEN = os.environ["SWITCHBOT_ACCESS_TOKEN"]
SECRET = os.environ["SWITCHBOT_SECRET"]
DEVICE_ID =os.environ["SWITCHBOT_DEVICE_ID"]

API_BASE_URL = "https://api.switch-bot.com"

def generate_sign(token: str, secret: str, nonce: str = "") -> tuple[str, str, str]:
    """SWITCH BOT APIの認証キーを生成する"""
    t = int(round(time.time() * 1000))
    string_to_sign = "{}{}{}".format(token, t, nonce)
    string_to_sign = bytes(string_to_sign, "utf-8")
    secret = bytes(secret, "utf-8")
    sign = base64.b64encode(
        hmac.new(secret, msg=string_to_sign, digestmod=hashlib.sha256).digest()
    )
    return (str(t), str(sign, "utf-8"), nonce)

def post_command(
    device_id: str,
    command: str,
    parameter: str = "default",
    command_type: str = "command",
):
    """指定したデバイスにコマンドを送信する"""
    t, sign, nonce = generate_sign(ACCESS_TOKEN, SECRET)
    headers = {
        "Content-Type": "application/json; charset: utf8",
        "Authorization": ACCESS_TOKEN,
        "t": t,
        "sign": sign,
        "nonce": nonce,
    }
    url = f"{API_BASE_URL}/v1.1/devices/{device_id}/commands"
    body = {"command": command, "parameter": parameter, "commandType": command_type}
    data = json.dumps(body)

    try:
        logger.info(data)
        r = requests.post(url, data=data, headers=headers)
        logger.info(r.text)

    except requests.exceptions.RequestException as e:
        logger.error(e)

    return r

# 色変え
def change_light():
    post_command(DEVICE_ID, "setBrightness", str(100))
    post_command(DEVICE_ID, "setColor", f"{127}:{0}:{127}")

change_light()

setBrightnessで100%の明るさ、setColorでRGB指定の色変更。コードでは紫です。
拝借コードそのまんまですね!コードを変えて外から色を渡せるようにしてもいいですね。

color_reset.py(色を戻す)

def turn_on_light():
    post_command(DEVICE_ID , "setBrightness", str(100))
    post_command(DEVICE_ID , "setColorTemperature","2700")

turn_on_light()

setColorではなくてsetColorTemperatureでテンプレートにある「暖色」に設定しています。
うちのでデフォ色がこれなのですがsetColorじゃ戻らなくてちょっと迷子になったw

スケジューリング

cronとは?

cron(クロン) は、
LinuxやUNIXで「決まった時間に自動でコマンドを実行する仕組み」です。

さきほど作ったPythonファイルをラズパイ(※linux系のサーバならなんでも良い)において
crontabでスケジュールを設定。読み方は以下を参考に。

  • フォーマット: 分 時 日 月 曜日 コマンド
フィールド
0–59 30(30分)
0–23 14(14時)
1–31 15(日付15日)
1–12 8(8月)
曜日 0–7(0と7は日曜) 1(月曜)


実際はこんな感じですね。
開始時間になったら色を変えるPythonファイルを呼び出し、

終了時間になったら色を戻すPythonファイルを呼び出すだけです。

sc3

おわりに

実際の点灯中とリセット時

Bulb1-1

こんな感じです。
子供達は色が変わるとそれぞれが急いでゲームやタブレットを開始しますw
実際M10i自身がヘッドフォンつけてゲームしててもゲーム時間の終わりに気づくので
案外視覚効果って大事だなーっと思ったM10iでした☆

ではではっ

参考文献
【SwitchBot】雨が降りそうなときに廊下ライトの色を変えてお知らせする機能を作る