FitbitのWeb APIで睡眠を振り返る😴
この記事は 日本システム技研 - Qiita Advent Calendar 2025 - Qiita の3日目の記事です📅
私はFitbitを数年前から愛用しています⌚ FitbitのWeb APIを使用すると睡眠データ等が取得できますので、それを使用して睡眠を振り返ってみたいと思い、まずはお試しで触ってみました!その時の備忘録です!😴
FitbitのWeb APIを使用するときの参考になればうれしいです!
やること
- FitbitのWeb APIへアクセスするための認証情報を取得
- 取得した睡眠データを表示するWebアプリを開発(生成AIを使用)
- 睡眠を振り返る
FitbitのWeb APIへアクセスするための認証情報を取得
これはFitbitのDeveloperサイトから取得できます!
上記のURLにアクセスしログイン→「MANAGE MY APPS」のタブを選択→「+Register a new app」を選択

アプリの登録ページが開くので必要な情報を入力し登録(今回はお試しで一次的なものなのでWebサイトはlocalhostとしていますがお勧めしません)

Client ID、Client Secretが取得でき、Webアプリで使用します

取得した睡眠データを表示するWebアプリを開発(生成AIを使用)
Webアプリは「Github Copilot(Agentモード | モデルは「Claude Sonnet 4.5」)」で作成しました(Next.js/TypeScript)
ソースはこちら → GitHub - peacemaker07/fitbit-app
起動( npm run dev )しアクセスするとログインページが表示されるのでログインを行う

アクセス許可のページが表示されるので許可を行う

検索ページが表示されました!よさそうです🙌

睡眠を振り返る
使用しているWeb API(※)の仕様を参照すると「期間上限が100日(Maximum range: 100 days)」となっています
このため、3ヶ月ごと取得してみました!
⚠️ ちなみに、1時間の上限リクエスト数が「150」なので注意!
Rate Limiting
The Fitbit API has rate limiting in place to protect the service from abuse. Developers can make up to 150 requests per hour per user. If the ?rate limit is exceeded, the API will respond with a 429 Too Many Requests status code.
1月から3月末(左から2023年、2024年、2025年)

4月から6月末(左から2023年、2024年、2025年)

7月から9月末(左から2023年、2024年、2025年)

10月から12月末(左から2023年、2024年、2025年)

結果
- 大体、平均睡眠時間は3年間通して6時間くらいで安定している
- 凸凹は平日が短めで週末を長く寝ているから(^^;
- あまりよろしくなさそう。。。
- ちょっとわかりづらいですが、床上時間と睡眠時間の差が大きいところは休日
- これはベッドの上で休日は動画みていたりするので。。。(ちょっとした楽しみ)
結果として、新しい発見があったというよりは、普段の生活習慣が数値で表されて納得した感じ📝 今後、他要素(睡眠スコア?天気?他)と組み合わせて再検証してみると面白いかも🥱
Sigfoxデバイスの初回通信時に回線停止日を設定してみる
この記事は 日本システム技研 - Qiita Advent Calendar 2025 - Qiita 2日目の記事です!
個人的にSigfox Backend Cloudを触っています。そのなかで、Sigfox回線を使用しているデバイスの初回通信時に回線停止日の設定を行いたいと思い、そのときにやったことの備忘録です。
Sigfox Backend Cloudを利用しているひとの参考になればうれしいです🙏
Sigfoxとは|IoTネットワーク「Sigfox」|KCCS
Sigfoxとは
- Sigfox(シグフォックス)はフランスのUnaBiz SAS社が各国のオペレーターを通じて提供しているLPWA(0G)ネットワーク
- 低価格・低消費電力・長距離伝送が特長で、一定間隔で通信をしたい用途に適していると思います(農業用ハウスの室温を一定間隔で送信するなど)
Sigfox Backend CloudではSigfox回線のデバイス管理やAPI連携、Callback機能で特定のイベント発生時に別クラウド(AWS、Azure等)へデータ転送等できます。ブラウザから各操作、設定等行えます
どうやって実現するか
今回はSigfox Backend CloudにあるCallback機能を使用して実現します
⚠️ まだ未完成のため、Webアプリケーションサーバ側、Sigfox Backend Cloud側ともに途中経過になりますのでご了承を 🙏
構成
Sigfoxを始めよう|Sigfoxとは|IoTネットワーク「Sigfox」|KCCS
上記ページの「Callback」の図を引用

やること
Webアプリケーションサーバ側
- Basic認証を使用したWebAPIを作成
- このWebAPIのなかで回線停止日を設定
- ⚠️ 認証方法に関しては今後変更する可能性があります
Sigfox Backend Cloud
- 「Event configuration」にある「Custom callback」を使用
- 「Event Type」の「Receive first payable message」が初回通信時なので、このイベント発生時にWebアプリケーションサーバ側のWebAPIを呼び出す
Basic認証を使用したWebAPIを作成
WebAPIを作成
WebフレームワークはDjangoを使用しているので、今回はDjango Rest Frameworkを使用します
BasicAuthenticationを使用することで実現ができます。- Sigfox Backend CloudからPOSTでリクエストされるので
postとします
・・・
from rest_framework import views, status
from rest_framework.response import Response
from rest_framework.authentication import BasicAuthentication
from rest_framework.permissions import IsAuthenticated
・・・
class SigfoxCallbackAPIView(views.APIView):
"""
Sigfox Backend Cloudからのコールバックを受け取るAPIビュー
Basic認証を使用してSigfoxからの初回通信の対象メッセージを受信
https://support.sigfox.com/docs/receive-first-payable-message
"""
authentication_classes = [BasicAuthentication]
permission_classes = [IsAuthenticated]
def post(self, request, *args, **kwargs):
"""
Sigfoxからのコールバックデータを受信
Expected payload from Sigfox:
{
"device": "device_id",
"time": "unix_timestamp",
"data": "payload_data",
・・・
}
"""
logger.info(f"Received Sigfox callback: {request.data}")
# シリアライザでバリデーション
serializer = SigfoxCallbackSerializer(data=request.data)
if not serializer.is_valid():
logger.error(f"Validation error: {serializer.errors}")
return Response(
{"detail": "Invalid payload", "errors": serializer.errors},
status=status.HTTP_400_BAD_REQUEST
)
validated_data = serializer.validated_data
device_id = validated_data.get('device')
# デバイスの存在確認
try:
sigfox_device = SigfoxDevice.objects.get(imsi=device_id)
device = Device.objects.get(imsi=sigfox_device.imsi)
except (SigfoxDevice.DoesNotExist, Device.DoesNotExist):
logger.warning(f"Device not found: {device_id}")
return Response(
{"detail": f"Device {device_id} not found"},
status=status.HTTP_404_NOT_FOUND
)
・・・
ブラウザからAPIにアクセスしてみると認証を求められることを確認 👍️

それと疎通確認として以下のコードでアクセスしusername、passowrdが存在するユーザーの時にViewが実行されることを確認 👍️
import requests
from requests.auth import HTTPBasicAuth
response = requests.post(
'http://127.0.0.1:8000/api/sigfox/callback/',
auth=HTTPBasicAuth('username', 'password'),
data={'device': '12345'}
)
print(response)
回線停止日の設定
こちらはSigfox Backend Cloudが提供するAPIを使用します
- Unsubscribe multiple devices
- ※APIの利用方法はこちらを参照
上記のAPIをWebAPIからリクエストして、該当の端末の回線停止日を設定します
リクエストのPayloadはこのようなかたち 📝
{
"data": [
{
"id": "12345", # sigfox回線を利用しているデバイスの端末ID
"unsubscriptionTime": 1534165000000 # 回線停止日時(UnixTime形式)
}
]
}
リクエスト用に作成したメソッドはこちら
class SigfoxApi:
api_base_url = "https://api.sigfox.com/v2"
・・・
def request_devices_bulk_unsubscribe(self, unsubscribes, sigfox_api_user_key_name, sigfox_api_password_key_name):
"""
https://support.sigfox.com/apidocs#operation/deviceBulkUnsubscribe
"""
path = "/devices/bulk/unsubscribe"
# リクエストのPayload形式に変更
data = {
"data": [
{
"id": unsubscribe[0],
"unsubscriptionTime": unsubscribe[1],
} for unsubscribe in unsubscribes
]
}
headers = {
"Content-Type": "application/json" # JSON形式を指定
}
return self._post(path, [認証情報], data=json.dumps(data), headers=headers)
・・・
def _post(self, path, auth, data=None, json_param=None, headers=None):
if not auth:
raise Exception("No auth")
response = requests.post(
f"{self.api_base_url}{path}", data, json_param, headers=headers, auth=auth)
response.raise_for_status()
return response
・・・
「Event configuration」にある「Custom callback」を使用
この「Event configuration」を使用すると、特定のイベントが発生したときのcallbackを登録できます。
今回使用する「初回通信」以外にもcallbackを登録できるイベントがいくつかあります。
設定を行う
- Sigfox Backend Cloudにログインします
- Login
- ※ ログインするには、Sigfox回線を使用した端末の購入が必要です
- ※ Sigfoxを始めよう|Sigfoxとは|IoTネットワーク「Sigfox」|KCCS
- 上段にある「DEVICE TYPE」を選択
- DEVICE TYPE一覧が表示されるので、「Name」列の該当のDEVICE TYPEを選択
- 「EVENT CONFIGURATION」を選択
- 右上の「new」を選択
- 「Custom callback」を選択するとcallbackの設定ページが表示されます
イベント(Event type)と通知方法(Channel)などを選択、設定します
- Event type:Receive first payable message
- Channel:URL
- Url pattern:https://・・・/api/sigfox/callback/ (作成したWebAPIのエンドポイント)
- Headers
- Content type:application/json
- Body:{"time":"{time}", "severity":"{severity}", "sourceId":"{sourceId}", "sourceType":"{sourceType}", "eventType":"{eventType}", "deviceTypeId":"{deviceTypeId}", "groupId":"{groupId}", "deviceInfo":"{deviceInfo}", "deviceMessageTime":"{deviceMessageTime}"}

「OK」で設定完了です!
補足:「ユーザ名:パスワード」のbase64エンコードしたものの出し方
Djangoのカスタムコマンドで作成しました
コードは以下です!
import base64
from django.core.management.base import BaseCommand
class Command(BaseCommand):
"""
python manage.py generate_basic_auth <username> <password>
"""
help = 'Generate Base64 encoded credentials for Basic Authentication'
def add_arguments(self, parser):
parser.add_argument('username', type=str, help='Username for authentication')
parser.add_argument('password', type=str, help='Password for authentication')
def handle(self, *args, **options):
username = options['username']
password = options['password']
# username:password の形式で結合
credentials = f"{username}:{password}"
# Base64エンコード
encoded_credentials = base64.b64encode(credentials.encode('utf-8')).decode('utf-8')
# 結果を出力
self.stdout.write(self.style.SUCCESS(f'Authorization Header: Basic {encoded_credentials}'))
実行はこんな感じ
$ python manage.py generate_basic_auth [username(ユーザ名)] [password(パスワード)]
参考
参考になればうれしいです!
AmplifyでPythonのfunctionを追加したけど2回目のpushができない😇
AmplifyでPythonのfunctionを追加し amplify push をして、プログラムを修正後、もう一度、 amplify push したらエラーがでてpushできなかったときの対処方法の備忘録📝
環境
エラー内容
$ amplify push ✖ There was an error pulling the backend environment dev. 🛑 ENOENT: no such file or directory, stat '/xxxx/react-ts-workspace-amplified/amplify/.temp/#current-cloud-backend/function/samplePythonFunction/.venv/bin/python'
#current-cloud-backend 内にPythonの仮想環境の .venv があり、その中にシンボリックリンクがあることが悪さをしているらしい。
#current-cloud-backend は現在のクラウド状態が格納されている。
対処方法
Pipenvの2つの環境変数を .env に記載し対処
- プロジェクト配下に仮想環境を配置するか指定できる環境変数:PIPENV_VENV_IN_PROJECT
- 仮想環境の独自の配置場所を指定できる環境変数: WORKON_HOME
Amplifyでは「PIPENV_VENV_IN_PROJECT」がデフォルトで「true」になっているようなので、 amplify push を行うと作成したfunction配下に仮想環境( .venv )が作成される

これが #current-cloud-backend にはいってしまう。
このため、 Pipenvの.env の自動読み込み機能を利用するため .env を Pipfile と同じ場所に配置し以下を記載
PIPENV_VENV_IN_PROJECT=false WORKON_HOME=../../../../.venvs
- .envの記載内容の補足
PIPENV_VENV_IN_PROJECTがtrueのままだとWORKON_HOMEが有効にならなかった- このため
PIPENV_VENV_IN_PROJECTをfalseに設定し - 仮想環境の配置場所を
#current-cloud-backendに含まれない場所に変更

無事、2回目以降も amplify push できるようになりました🙌
懸念点
ただ、この方法だとPythonのfunctionが複数になった場合、仮想環境が被ってしまうので、 amplify/backend/function とは別の場所でPipfileを統一した方がよさそう
補足:エラーが出た場合の復帰方法
こちら参考にさせていただきました!ありがとうございます🙏
以下ページの「amplify pushができなくなったら」です!
SORACOM Beamのプラットフォームバージョン変更ではまなったこと
「プラットフォームバージョン 201509 は 2022 年 8 月 1 日にサポートを終了します」ということで少し遅くなってしまいましたが「201912」に変更したところエラーがでたのでその備忘録です!(ちなみにちゃんと以下ドキュメントを読んでいればはまらなかった・・・)
プラットフォームバージョンを変更
SORACOMコンソールで該当グループのBeamのプラットフォームバージョンを「201912」に変更し保存

他設定はこんな感じ
- 転送先
- 証明書 (key と cert) を利用しています
エラー
データをBeamに送ったところ以下エラーが発生
{
"time": xxxxxxxxxxxxx,
"service": "Beam",
"resourceType": "Subscriber",
"resourceId": "xxxxxxxxxxxxxxx",
"body": {
"message": "[MQTT] Destination error mqtt://xxxxx.iot.ap-northeast-1.amazonaws.com:8883: Cannot parse protocolId"
}
}
原因
以下ちゃんと記載があるのに、転送先プロトコルを「MQTT」のまま変更していませんでした😇
「201509」のときに転送先プロトコルを「MQTT」にしていましたが、証明書 (key と cert) を利用していたので、「MQTTS」で接続してくれていたんですね!今回、プラットフォームバージョンを変更したことにより「MQTT」で接続するようになりエラーが発生したようです📝
プラットフォームバージョン 201509 においては、証明書 (key と cert) を利用している場合、転送先に接続するプロトコルの設定に関わらず MQTTS プロトコルで転送先に接続されます。プラットフォームバージョン 201912 においては、証明書の利用有無に関わらず、転送先に指定されたプロトコルで接続します。転送先のプロトコルが正しく設定されているかを事前に確認ください。
リファレンス: 制限事項と注意事項 | SORACOM Beam | ソラコムユーザーサイト - SORACOM Users
対処
SORACOMコンソールで該当グループのBeamの転送先プロトコルを「MQTTS」に変更したところ無事解決🙌

(ちなみに、別アカウントではプラットフォームバージョンを変更しても特にエラーがでなかったのでそちらとBeamの設定を比較したところ気がつきました(^^; )
Notionで進捗状況を可視化してみる
スケジュール管理するときに、予定日、開始日、終了日を入力しいちいち状況を「着手中」とか「完了」とか変更するのがめんどいし、遅れているのかオンスケなのかわからない・・・
なのでNotionのpropertyにある Formula を使って日付を入力すると現状の進捗状況が自動で切り替わるようにしてみました🙌
前提
- ちゃんと動きを確認していないところもあるので想定外の動きをするかもです。。。了承を🙏
- Notinoの説明については割愛させてください🙏
property: Formulaについて
ExcelやGoogle Sheetsの関数と同じような機能です。合計値や様々な値の算出が可能です。
詳細はこちら!
このように prop("[property名]") でpropertyの値を参照できたり、分岐やいろいろな関数等が用意されています🙌
完成イメージはこちら
予定、開始日、終了日により 状態 と 状況 がかわります👀

※ 進捗バー、進捗率は「おまけ」で説明します🙏
作成していきましょう!
まずは各propertyを用意
| 名前 | タイプ | 内容 |
|---|---|---|
| 状態 | Formula | empty(prop("終了日")) ? (empty(prop("開始日")) ? "" : "👨💻") : "🔚" |
| 状況 | Formula | if(empty(prop("終了日")) == false, "🔚", if(start(prop("予定")) > now(), if(empty(prop("開始日")) == false, "🆒", ""), if(empty(prop("開始日")), "🔥", if(end(prop("予定")) < now(), "🔥", "✅")))) |
| 予定 | Date | 予定日を入力。 End date をONにしてrangeで設定。 |
| 開始日 | Date | 該当のタスクに着手開始した日を入力 |
| 終了日 | Date | 該当のタスクが完了した日を入力 |
状態 と 状況 の判定については以下を参照
状態の判定について

状況の判定について

完成したもの
おまけ
進捗バー、進捗率については以下を参考に作成させてもらいました🙏
ただ、進捗率により進捗バーを変更するようにした簡易版です!
【Notion】進捗を可視化したガントチャートの作成手順 - Qiita
property
| 名前 | タイプ | 内容 |
|---|---|---|
| 進捗バー | Formula | slice("▓▓▓▓▓▓▓▓▓▓", 0, prop("進捗率") * 10) + slice("░░░░░░░░░░", 0, 10 - prop("進捗率") * 10) |
| 進捗率 | Number | Number format を Percent に設定 |
完成したもの
Let's Enjoy Notion🙌
Flutterインストール📝 to Mac
自分のMacに以下サイトを参考にFlutterをインストールしたときの備忘録📝
環境
インストール
Get the Flutter SDK
Intel用のFlutter SDKファイル(zip)をダウンロードし解凍
解凍したファイルはホームディレクトリ配下に以下のように配置
$ cd $ cd Documents $ mkdir development $ cd development $ pwd /Users/chino/Documents/development # 解凍したファイルを移動 $ mv ~/Downloads/flutter ./ $ ls -la total 0 drwxr-xr-x 3 chino staff 96 7 24 10:49 . drwx------@ 58 chino staff 1856 7 24 10:49 .. drwxr-xr-x@ 27 chino staff 864 7 14 05:40 flutter
Flutterのパスを設定
$ vi ~/.zshrc # 以下を追記し保存 --- # flutter export FLUTTER_HOME="$HOME/Documents/development/flutter" export PATH="$PATH:$FLUTTER_HOME/bin" ---
Run Flutter Doctor
flutterの doctor というコマンドでFlutterに必要な開発環境が準備できているか確認できるので実行💻
$ flutter doctor
╔════════════════════════════════════════════════════════════════════════════╗
║ Welcome to Flutter! - https://flutter.dev ║
║ ║
║ The Flutter tool uses Google Analytics to anonymously report feature usage ║
║ statistics and basic crash reports. This data is used to help improve ║
║ Flutter tools over time. ║
║ ║
║ Flutter tool analytics are not sent on the very first run. To disable ║
║ reporting, type 'flutter config --no-analytics'. To display the current ║
║ setting, type 'flutter config'. If you opt out of analytics, an opt-out ║
║ event will be sent, and then no further information will be sent by the ║
║ Flutter tool. ║
║ ║
║ By downloading the Flutter SDK, you agree to the Google Terms of Service. ║
║ Note: The Google Privacy Policy describes how data is handled in this ║
║ service. ║
║ ║
║ Moreover, Flutter includes the Dart SDK, which may send usage metrics and ║
║ crash reports to Google. ║
║ ║
║ Read about data we send with crash reports: ║
║ https://flutter.dev/docs/reference/crash-reporting ║
║ ║
║ See Google's privacy policy: ║
║ https://policies.google.com/privacy ║
╚════════════════════════════════════════════════════════════════════════════╝
Running "flutter pub get" in flutter_tools... 10.3s
Doctor summary (to see all details, run flutter doctor -v):
[✓] Flutter (Channel stable, 3.0.5, on macOS 12.4 21F79 darwin-x64, locale ja-JP)
[✗] Android toolchain - develop for Android devices
✗ Unable to locate Android SDK.
Install Android Studio from: https://developer.android.com/studio/index.html
On first launch it will assist you in installing the Android SDK components.
(or visit https://flutter.dev/docs/get-started/install/macos#android-setup for detailed instructions).
If the Android SDK has been installed to a custom location, please use
`flutter config --android-sdk` to update to that location.
[!] Xcode - develop for iOS and macOS (Xcode 13.4.1)
✗ CocoaPods not installed.
CocoaPods is used to retrieve the iOS and macOS platform side's plugin code that responds to your
plugin usage on the Dart side.
Without CocoaPods, plugins will not work on iOS or macOS.
For more info, see https://flutter.dev/platform-plugins
To install see https://guides.cocoapods.org/using/getting-started.html#installation for instructions.
[✓] Chrome - develop for the web
[!] Android Studio (not installed)
[✓] VS Code (version 1.69.1)
[✓] Connected device (2 available)
[✓] HTTP Host Availability
! Doctor found issues in 3 categories.
以下がまだ準備できていなかった
- Android toolchain - develop for Android devices
- Xcode - develop for iOS and macOS (Xcode 13.4.1)
- →CocoaPodsがインストールされていない⚠
CocoaPodsのインストール
To install see https://guides.cocoapods.org/using/getting-started.html#installation for instructions.
ということなのでCocoaPods Guides - Getting Startedを参照しインストール👀
$ sudo gem install cocoapods
パスを設定
$ vi ~/.zshrc # 以下を追記し保存 --- export GEM_HOME=$HOME/.gem export PATH=$GEM_HOME/bin:$PATH ---
もう一度、 doctor を実行!
$ flutter doctor
Doctor summary (to see all details, run flutter doctor -v):
[✓] Flutter (Channel stable, 3.0.5, on macOS 12.4 21F79 darwin-x64, locale ja-JP)
[✗] Android toolchain - develop for Android devices
✗ Unable to locate Android SDK.
Install Android Studio from: https://developer.android.com/studio/index.html
On first launch it will assist you in installing the Android SDK components.
(or visit https://flutter.dev/docs/get-started/install/macos#android-setup for detailed instructions).
If the Android SDK has been installed to a custom location, please use
`flutter config --android-sdk` to update to that location.
[✓] Xcode - develop for iOS and macOS (Xcode 13.4.1)
[✓] Chrome - develop for the web
[!] Android Studio (not installed)
[✓] VS Code (version 1.69.1)
[✓] Connected device (2 available)
[✓] HTTP Host Availability
! Doctor found issues in 2 categories.
Xcodeについては準備完了🙆
Android関連のインストール
(or visit https://flutter.dev/docs/get-started/install/macos#android-setup for detailed instructions).
ということなのでmacOS install | Flutterを参照しセットアップ!
まずはAndroid Studioをインストール
インストール後、Android Studioを起動し初期セットアップも完了
再び doctor を実行!
flutter doctor
Doctor summary (to see all details, run flutter doctor -v):
[✓] Flutter (Channel stable, 3.0.5, on macOS 12.4 21F79 darwin-x64, locale ja-JP)
[!] Android toolchain - develop for Android devices (Android SDK version 33.0.0)
✗ cmdline-tools component is missing
Run `path/to/sdkmanager --install "cmdline-tools;latest"`
See https://developer.android.com/studio/command-line for more details.
✗ Android license status unknown.
Run `flutter doctor --android-licenses` to accept the SDK licenses.
See https://flutter.dev/docs/get-started/install/macos#android-setup for more details.
[✓] Xcode - develop for iOS and macOS (Xcode 13.4.1)
[✓] Chrome - develop for the web
[✓] Android Studio (version 2021.2)
[✓] VS Code (version 1.69.1)
[✓] Connected device (2 available)
[✓] HTTP Host Availability
! Doctor found issues in 1 category.
✗ cmdline-tools component is missing
macOS install | FlutterのページでAndroid Studioの初期セットアップ時にインストールされると記載があったがなぜかインストールされず。。。一応、 sdkmanager を実行してみたが command not found になってしまった・・・
このため、こちらのDownload Android Studio & App Tools - Android Developersからzipファイルをダウンロードできるようなのでダウンロード、解凍してSDK配下に配置
# SDK配下に移動 $ cd /Users/chinoyuuji/Library/Android/sdk # ダウンロードして解凍したcommand-toolsをsdk配下に配置 $ sudo mv ~/Downloads/cmdline-tools ./
SDKの場所はAndroid Studioを起動し確認しました


sdkmanagerのパスを設定
$ vi ~/.zshrc # 以下を追記し保存 --- # Android export ANDROID_USER_HOME="/Users/chinoyuuji/Library/Android" export ANDROID_HOME="$ANDROID_USER_HOME/sdk" export ANDROID_CMDLINE_TOOLS="$ANDROID_HOME/cmdline-tools" export PATH="$PATH:$ANDROID_CMDLINE_TOOLS/bin" ---
sdkmanagerの最新をインストール
$ sdkmanager --install "cmdline-tools;latest" The operation couldn’t be completed. Unable to locate a Java Runtime. Please visit http://www.java.com for information on installing Java.
JAVAがインストールしていなかったので、http://www.java.comからjavaをインストールしてから再度、コマンドを実行
$ sdkmanager --install "cmdline-tools;latest" Error: Could not determine SDK root. Error: Either specify it explicitly with --sdk_root= or move this package into its expected location: <sdk>/cmdline-tools/latest/
SDKのパスを指定が必要だったので指定して再実行!
$ sdkmanager --install "cmdline-tools;latest" --sdk_root=/Users/chinoyuuji/Library/Android/sdk [=======================================] 100% Unzipping... cmdline-tools/lib/RE
できたみたいなので、 doctor で出力されていたもうひとつのコマンドを実行(すべて「y」で承諾)
$ flutter doctor --android-licenses ・・・ All SDK package licenses accepted
再び、 doctor を実行👀
$ flutter doctor Doctor summary (to see all details, run flutter doctor -v): [✓] Flutter (Channel stable, 3.0.5, on macOS 12.4 21F79 darwin-x64, locale ja-JP) Checking Android licenses is taking an unexpectedly long time...[✓] Android toolchain - develop for Android devices (Android SDK version 33.0.0) [✓] Xcode - develop for iOS and macOS (Xcode 13.4.1) [✓] Chrome - develop for the web [✓] Android Studio (version 2021.2) [✓] VS Code (version 1.69.1) [✓] Connected device (2 available) [✓] HTTP Host Availability • No issues found!
No issues found! になり準備完了🙌
TWELITEをいじってみる(センサデータをみてみる)
この記事は↓の続きになります!
今回は、TWELITE DIPにセンサを繋いで、MONOSTICKで受信したセンサデータをみてみます!
こちらのページが参考になりますが、スイッチサイエンスで購入したBME280は配線が違うため、あわせて記載していきます📝
前提
センサデータをみてみる
準備
ハード側
配線はこちら

- 抵抗は10kΩを使用
- BME280についてはこちらも参考になります
- Fritzingのパーツはこちらからダウンロード
ソフトの書き換え、設定の編集・変更
手順としては無線タグアプリ (App_Tag) - MONO-WIRELESS.COMをMONOSTICK、TWELITE DIPに書き込み、設定等をインタラクティブモードで編集・設定します!
- TWELITE DIPに子機用の「App_Tag_EndDevice_Input」を書き込み
- MONOSTICKにOTAでTWELITE DIP側の設定を変更する「App_Tag_EndDevice_Input_OTA」を書き込み
- インタラクティブモードで子機用の設定を行う
- 子機(TWELITE DIP)の設定を変更
- MONOSTICKでデータを受信するための「App_Tag_Parent_MONOSTICK」を書き込み
TWELITE DIPに子機用の「App_Tag_EndDevice_Input」を書き込み
- TWELITE DIPをTWELITE R2に装着して、PCとUSB接続
- ⚠⚠⚠差し込む方向を間違えるとTWELITE DIP側が壊れてしまう可能性があるので注意!⚠⚠⚠
- TWELITE STAGEを起動
- シリアルポートは「TWELITE R2」を選択
- 「アプリ書き換え」⇒「TWELITE_APPSビルド&書換」⇒「App_Tag」⇒「App_Tag_EndDevice_Input」を選択
- ⇒アプリがTWELITE DIPに書き込まれます
- 書き込みが完了したら、TWELITE STAGEを終了させて、TWELITE R2もPCから外し、TWELITE DIPをブレッドボードに装着する
- ブレッドボード装着後、まだ電源はいれない!
MONOSTICKにOTAでTWELITE DIP側の設定を変更する「App_Tag_EndDevice_Input_OTA」を書き込み
- MONOSTICKをPCとUSB接続
- TWELITE STAGEを起動
- シリアルポートは「MONOSTICK」を選択
- 「アプリ書き換え」⇒「TWELITE_APPSビルド&書換」⇒「App_Tag」⇒「App_Tag_EndDevice_Input_OTA」を選択
- ⇒アプリがMONOSTICKに書き込まれます
インタラクティブモードで子機用の設定を行う
次にインタラクティブモードで子機に設定する内容を編集します
- 上記の続き
- TWELITE STAGEの「インタラクティブモード」を選択
- 設定を変更する
- 「b」キーでUART baundを変更:115200
- 「o」キーでOption Bitsを変更:0x00010001
- 「d」キーでSleep Durを変更(ms):60000(※ 1分ごと送信するようにする)
- 「w」キーでSensor Waitを変更(ms):30
- 「m」キーでSensor Modeを変更:0x39
- 「p」キーでParameterを変更:0
- 「Shift + S」キーで設定を保存
各設定の詳細はこちらを参照
無線タグアプリ インタラクティブモード - MONO-WIRELESS.COM
子機(TWELITE DIP)の設定を変更
上記に引き続き、TWELITE STAGEを起動したままで、子機に電源をいれて、以下のように表示されれば、TWELITE DIP側に設定が反映されたことになるようです!
SUCCESS [TWELITE DIPのED]

⚠障害物などに弱いので、なるべくMONOSTICKとTWELITE DIPを近い距離にして、TWELITE DIPの電源をいれてください⚠
MONOSTICKでデータを受信するための「App_Tag_Parent_MONOSTICK」を書き込み
- MONOSTICKをPCとUSB接続
- TWELITE STAGEを起動
- シリアルポートは「MONOSTICK」を選択
- 「アプリ書き換え」⇒「TWELITE_APPSビルド&書換」⇒「App_Tag」⇒「App_Tag_Parent_MONOSTICK」を選択
- ⇒アプリがMONOSTICKに書き込まれます
センサデータを確認!📈
TWELITE STAGEを起動して、シリアルポートは「MONOSTICK」を選択をすると1分ごと、センサデータを確認できます!🙌
- tm: 温度(100倍されているので、22.44℃)
- hu: 湿度(こちらも100倍されているので、39.08%)
- at: 気圧(975hPa)
::rc=80000000:lq=183:ct=0018:ed=82015460:id=0:ba=3180:a1=1138:a2=0689:tm=2244:hu=3908:at=0975
Pythonで確認してみる
Raspberry PiにMONOSTICKを装着すると /dev/ttyUSBx として認識されます
$ ls -la /dev/ttyUSB* crw-rw---- 1 root dialout 188, 0 3月 19 23:19 /dev/ttyUSB0
Pythonでserial関連のライブラリをインストールします
$ pip3 install pyserial
コードはこんな感じ
import serial
import time
ser = serial.Serial('/dev/ttyUSB0', 115200)
while True:
time.sleep(1)
recv_list = ser.readline().decode('utf-8').split(':')
if len(recv_list) < 13:
# いったん、受信データの要素数で不要なデータ時は出力しないようにする
continue
print(recv_list)
実行すると以下のように受信したデータを確認できます🙌
$ python3 app_tag_loop.py ['', '', 'rc=80000000', 'lq=159', 'ct=0002', 'ed=8201C109', 'id=0', 'ba=3190', 'a1=0916', 'a2=0612', 'tm=2270', 'hu=4060', 'at=0975\r\n']
Let's Enjoy センシング!!!!!!!! 📊



