{
  "schema_version": "1.0",
  "experiment_id": "AIEL-2026-0001",
  "title": {
    "en": "SwitchBot Plug Mini (JP) OpenAPI v1.1 stale-status behavior and layered reporting verification",
    "ja": "SwitchBot Plug Mini (JP) OpenAPI v1.1のstale状態と段階別報告メカニズムの検証"
  },
  "status": "COMPLETED",
  "timestamps": {
    "created_at": "2026-08-22T12:19:00+09:00",
    "started_at": null,
    "observed_at": null,
    "completed_at": "2026-08-19T18:30:00+08:00",
    "published_at": "2026-08-22T12:42:52+09:00",
    "last_verified": "2026-08-19T18:30:00+08:00",
    "updated_at": "2026-08-22T13:01:12+09:00"
  },
  "objective": {
    "summary_en": "Determine the meaning and update behavior of electrical status fields returned by SwitchBot OpenAPI v1.1 for Plug Mini (JP), and determine whether long stale intervals are a client-side defect, a device/cloud failure, or intentional reporting behavior.",
    "summary_ja": "SwitchBot Plug Mini (JP)のOpenAPI v1.1が返す電気量フィールドの意味と更新挙動を確認し、長時間同値が返るstale区間がクライアント実装不具合、機器・クラウド異常、または意図された報告仕様のいずれかを判定する。",
    "success_criteria": [
      {"id": "SC-001", "description_en": "Characterize the OpenAPI update behavior using repeatable logging and independent client paths.", "description_ja": "再現可能なログと独立した取得経路を用いてOpenAPI更新挙動を特徴付ける。"},
      {"id": "SC-002", "description_en": "Establish whether long stale intervals are consistent with an intentional SwitchBot reporting mechanism or indicate a fault.", "description_ja": "長時間stale区間がSwitchBotの意図された報告メカニズムと整合するか、故障を示すかを確定する。"}
    ],
    "partial_success_criteria": [],
    "failure_criteria": []
  },
  "scope": {
    "included": ["SwitchBot Plug Mini (JP)", "SwitchBot OpenAPI v1.1 device status endpoint", "Python short-interval and one-minute logging", "Google Apps Script five-minute logging", "SwitchBot app detail-screen refresh observations", "Manufacturer support/development-team response concerning reporting thresholds"],
    "excluded": ["Publication of credentials, account identifiers, device identifiers, MAC addresses, order numbers, email addresses, or household-identifying data"],
    "limitations": ["The original experiment note retained the experiment date but not exact timestamps for most observations; unknown times are therefore null rather than fabricated.", "The exact firmware version was not retained.", "The manufacturer response verified the layered reporting mechanism, but two follow-up technical questions remained unanswered at backfill time.", "Raw logger files were not found in the repository during backfill; only summarized observations in the legacy Markdown note are available."]
  },
  "environment": {
    "hardware": [{"role": "target_device", "manufacturer": "SwitchBot", "model": "Plug Mini (JP)", "revision": "Device body marking 2442 was reported to manufacturer support; its interpretation as a hardware revision is unverified.", "serial_number_public": false, "notes": "Device-specific identifiers are intentionally withheld."}],
    "software": [
      {"name": "Python diagnostic logger", "version": null, "role": "OpenAPI status logging"},
      {"name": "Google Apps Script", "version": null, "role": "five-minute OpenAPI status logging"},
      {"name": "mitmproxy", "version": null, "role": "mobile-app traffic observation"},
      {"name": "SwitchBot mobile app", "version": null, "role": "detail-screen refresh observation"}
    ],
    "firmware": [{"device_model": "Plug Mini (JP)", "version": null, "verification_status": "UNKNOWN"}],
    "network": {"type": "internet_cloud_api", "ip_addresses_redacted": true, "protocols_observed": ["HTTPS"], "notes": "The app-associated OpenAPI refresh was also observed with Bluetooth disabled and with phone Wi-Fi disabled while using cellular data."},
    "environmental_conditions": []
  },
  "hypotheses": [
    {"id": "H-001", "statement_en": "The long stale intervals are caused by a client-side cache or scheduling defect in Google Apps Script or Python.", "statement_ja": "長時間stale区間はGoogle Apps ScriptまたはPython側のキャッシュ・スケジューリング不具合により生じる。", "status": "NOT_SUPPORTED", "created_at": null, "evidence_refs": ["O-003"]},
    {"id": "H-002", "statement_en": "Plug Mini uses change-of-value / layered reporting so the cloud snapshot may remain unchanged until load changes beyond a threshold.", "statement_ja": "Plug Miniはchange-of-value型の段階別報告を行い、負荷変化がしきい値を超えるまでクラウド上の状態スナップショットが更新されない。", "status": "SUPPORTED", "created_at": null, "evidence_refs": ["O-002", "O-003", "SRC-001"]},
    {"id": "H-003", "statement_en": "Opening the SwitchBot app detail screen causes a device-specific synchronization outside the normal layered reporting path.", "statement_ja": "SwitchBotアプリの詳細画面を開くと、通常の段階別報告とは別に対象デバイス固有の状態同期が実行される。", "status": "UNTESTED", "created_at": null, "evidence_refs": ["O-004", "O-005", "O-007"]}
  ],
  "actions": [
    {"id": "A-001", "type": "api_logging", "description": {"en": "Collected OpenAPI status responses at short and long intervals.", "ja": "OpenAPI statusレスポンスを短周期・長周期で取得した。"}, "actor": {"type": "HUMAN", "role": "operator"}, "state": "EXECUTED", "executed_at": null, "result_refs": ["O-001", "O-002", "O-003"]},
    {"id": "A-002", "type": "device_reset", "description": {"en": "Reset the Plug Mini as requested by manufacturer support; stale behavior persisted.", "ja": "メーカーサポートの依頼に従いPlug Miniをリセットしたが、stale挙動は継続した。"}, "actor": {"type": "HUMAN", "role": "operator"}, "state": "EXECUTED", "executed_at": "2026-08-13T13:54:00+08:00", "result_refs": ["O-006"]},
    {"id": "A-003", "type": "manufacturer_inquiry", "description": {"en": "Submitted the observed behavior to SwitchBot support for investigation.", "ja": "観測挙動をSwitchBotサポートへ提出して調査を依頼した。"}, "actor": {"type": "HUMAN", "role": "operator"}, "state": "EXECUTED", "executed_at": "2026-08-12T04:36:00+08:00", "result_refs": ["SRC-001"]}
  ],
  "observations": [
    {"id": "O-001", "timestamp": null, "description_en": "A five-second run lasted about 12 minutes 32 seconds and collected 151 samples. A one-second run lasted about 3 minutes 43 seconds and collected 223 samples. During short runs, weight and electricCurrent commonly changed on a roughly 2-3 second timescale while one-second polling often returned repeated values.", "description_ja": "5秒周期ログは約12分32秒で151点、1秒周期ログは約3分43秒で223点を取得した。短時間ではweightとelectricCurrentは主に2〜3秒程度で変化し、1秒ポーリングでは同値が複数回返ることが多かった。", "observation_type": "api_response", "source_type": "log", "artifact_refs": ["AR-001"], "quality": "VALID"},
    {"id": "O-002", "timestamp": null, "description_en": "During long-running collection, voltage, electricCurrent, weight, and electricityOfDay could remain exactly unchanged for extended periods and then jump together to newer values. One representative stale interval lasted about 20 minutes.", "description_ja": "長時間取得ではvoltage、electricCurrent、weight、electricityOfDayが長時間完全一致したままとなり、その後まとめて新しい値へジャンプした。代表的stale区間は約20分間だった。", "observation_type": "api_response", "source_type": "log", "artifact_refs": ["AR-001"], "quality": "VALID"},
    {"id": "O-003", "timestamp": null, "description_en": "Independent Python one-minute and Google Apps Script five-minute collectors returned the same stale values over the same intervals.", "description_ja": "独立したPython 1分ロガーとGoogle Apps Script 5分ログが同じ時間帯に同じstale値を返した。", "observation_type": "api_response", "source_type": "log", "artifact_refs": ["AR-001"], "quality": "VALID"},
    {"id": "O-004", "timestamp": null, "description_en": "Opening the target Plug Mini detail screen in the SwitchBot app during stale periods was followed by refreshed OpenAPI values multiple times; one legacy-note example changed electricityOfDay from 145 after about 20 minutes of staleness to 166 after opening the detail screen.", "description_ja": "stale中に対象Plug MiniのSwitchBotアプリ詳細画面を開くと、その後のOpenAPI値が最新化する現象を複数回確認した。旧ログの代表例では約20分間electricityOfDay=145で固定後、詳細画面表示後に166へ更新した。", "observation_type": "physical_observation", "source_type": "log", "artifact_refs": ["AR-001"], "quality": "VALID"},
    {"id": "O-005", "timestamp": null, "description_en": "The app-detail-screen-associated refresh was observed with Bluetooth disabled and with Wi-Fi disabled while the phone used cellular data.", "description_ja": "アプリ詳細画面表示に伴う更新はBluetooth OFF、およびWi-Fi OFFでスマートフォンが携帯回線のみの条件でも観測された。", "observation_type": "network", "source_type": "physical_observation", "artifact_refs": ["AR-001"], "quality": "VALID"},
    {"id": "O-006", "timestamp": "2026-08-13T13:54:00+08:00", "description_en": "The operator reported that resetting the Plug Mini did not eliminate the stale behavior.", "description_ja": "操作者はPlug Miniをリセットしてもstale挙動が解消しなかったと報告した。", "observation_type": "physical_observation", "source_type": "human_report", "artifact_refs": [], "quality": "VALID"},
    {"id": "O-007", "timestamp": null, "description_en": "mitmproxy observation did not identify a clear new HTTP refresh request during the app detail screen's connecting state. Pub/sub-like topic names were observed in app metadata, but the specific protocol and refresh command were not identified.", "description_ja": "mitmproxy観測ではアプリ詳細画面の接続中表示時に明確な新規HTTP refresh requestは特定できなかった。アプリのメタデータにはpub/sub風topic名が観測されたが、具体的プロトコルやrefresh commandは特定できなかった。", "observation_type": "network", "source_type": "packet_capture", "artifact_refs": ["AR-001"], "quality": "VALID"}
  ],
  "claims": [
    {"id": "C-001", "statement_en": "Short-interval OpenAPI polling can return repeated values; weight and electricCurrent commonly changed on a 2-3 second timescale in the recorded short run.", "statement_ja": "短周期OpenAPIポーリングでも同値が返り得て、記録した短時間runではweightとelectricCurrentは主に2〜3秒程度で変化した。", "evidence_state": "OBSERVED", "confidence": "HIGH", "evidence_refs": ["O-001"], "source_refs": []},
    {"id": "C-002", "statement_en": "Long stale intervals affecting multiple status fields are unlikely to be explained solely by a single Python or Google Apps Script client defect.", "statement_ja": "複数status fieldにまたがる長時間stale区間は、単一のPythonまたはGoogle Apps Scriptクライアント不具合だけで説明できる可能性が低い。", "evidence_state": "INFERRED", "confidence": "HIGH", "evidence_refs": ["O-002", "O-003"], "source_refs": []},
    {"id": "C-003", "statement_en": "SwitchBot Plug Mini implements a layered reporting mechanism based on load-band-specific change thresholds; at approximately 110 W, a 30 W change threshold applied in the investigated case.", "statement_ja": "SwitchBot Plug Miniには負荷帯別の変化しきい値に基づく段階別報告メカニズムがあり、調査対象の約110W負荷では30Wの変化しきい値が適用された。", "evidence_state": "VERIFIED", "confidence": "HIGH", "evidence_refs": ["SRC-001", "O-002", "O-003"], "source_refs": ["SRC-001"]},
    {"id": "C-004", "statement_en": "The manufacturer-reported thresholds are: <=10 W: >4 W change; <=100 W: >10 W; <=300 W: >30 W; <=500 W: >50 W; <=700 W: >70 W; <=1000 W: >100 W; <=1500 W: >100 W.", "statement_ja": "メーカー回答による報告しきい値は、10W以内=4W超、100W以内=10W超、300W以内=30W超、500W以内=50W超、700W以内=70W超、1000W以内=100W超、1500W以内=100W超である。", "evidence_state": "VERIFIED", "confidence": "HIGH", "evidence_refs": ["SRC-001"], "source_refs": ["SRC-001"]},
    {"id": "C-005", "statement_en": "For the investigated device, SwitchBot support stated that the 100-300 W reporting threshold could be adjusted from 30 W to 10 W through a backend command.", "statement_ja": "調査対象デバイスについて、SwitchBotサポートは100〜300W帯の報告しきい値をバックエンド指令により30Wから10Wへ調整可能と説明した。", "evidence_state": "VERIFIED", "confidence": "HIGH", "evidence_refs": ["SRC-001"], "source_refs": ["SRC-001"]},
    {"id": "C-006", "statement_en": "Opening the SwitchBot app detail screen causes a specific forced synchronization mechanism.", "statement_ja": "SwitchBotアプリの詳細画面を開くと特定の強制同期メカニズムが実行される。", "evidence_state": "HYPOTHESIS", "confidence": "MEDIUM", "evidence_refs": ["O-004", "O-005", "O-007"], "source_refs": ["SRC-002"]},
    {"id": "C-007", "statement_en": "When the power-change threshold triggers a report, voltage, electricCurrent, and electricityOfDay are guaranteed to update atomically with the power value.", "statement_ja": "電力変化しきい値で報告が発生すると、voltage、electricCurrent、electricityOfDayも電力値と必ず同時に更新される。", "evidence_state": "UNKNOWN", "confidence": "UNKNOWN", "evidence_refs": ["SRC-002"], "source_refs": ["SRC-002"]},
    {"id": "C-008", "statement_en": "The OpenAPI field weight represents instantaneous active power in watts.", "statement_ja": "OpenAPIのweightフィールドは瞬時有効電力[W]を表す。", "evidence_state": "INFERRED", "confidence": "HIGH", "evidence_refs": ["O-001", "AN-001"], "source_refs": []}
  ],
  "analysis": [
    {"id": "AN-001", "description_en": "The legacy record calculated weight/(voltage*current) over 223 one-second samples and obtained a mean of about 0.893 and median of about 0.945, physically consistent with an active-power interpretation for an AC load. This remains inference, not manufacturer verification.", "description_ja": "旧ログでは1秒周期223点に対してweight/(voltage*current)を計算し、平均約0.893、中央値約0.945となった。交流負荷の有効電力として物理的に整合するが、メーカー確認ではないため推論として保持する。", "input_refs": ["O-001", "AR-001"], "code_refs": [], "output_refs": [], "performed_by": {"type": "AI", "system": "ChatGPT"}, "status": "COMPLETED"},
    {"id": "AN-002", "description_en": "The manufacturer development-team response upgrades the earlier change-of-value hypothesis to a verified reporting behavior for the investigated case and explains why low-variation loads can produce long-lived stale OpenAPI snapshots without a device fault.", "description_ja": "メーカー開発部門の回答により、従来のchange-of-value仮説は調査対象ケースにおける検証済み報告挙動へ更新され、変動の小さい負荷で長時間staleになり得ることが故障ではなく仕様として説明された。", "input_refs": ["O-002", "O-003", "SRC-001"], "code_refs": [], "output_refs": [], "performed_by": {"type": "AI", "system": "ChatGPT"}, "status": "COMPLETED"}
  ],
  "results": {
    "summary_en": "The main objective was achieved. SwitchBot's development-team response identified an intentional layered reporting mechanism with load-dependent change thresholds, including a 30 W threshold around the investigated 110 W load. Independent client logs are consistent with this mechanism. Two follow-up details remain unresolved: simultaneous refresh behavior of other fields and the app detail-screen refresh mechanism.",
    "summary_ja": "主要目的は達成した。SwitchBot開発部門の回答により、負荷帯別変化しきい値を持つ意図的な段階別報告メカニズムが確認され、調査時の約110W負荷では30Wしきい値が適用された。独立クライアントのログもこの説明と整合する。未解決なのは他フィールドの同時更新保証とアプリ詳細画面に伴う更新メカニズムである。",
    "success_level": "SUCCESS",
    "established_claim_refs": ["C-001", "C-003", "C-004", "C-005"],
    "unresolved_claim_refs": ["C-006", "C-007", "C-008"],
    "disproven_claim_refs": []
  },
  "conclusion": {
    "en": "For the investigated SwitchBot Plug Mini (JP), OpenAPI v1.1 can legitimately return unchanged electrical status values for extended periods because reporting uses load-band-specific change thresholds rather than guaranteed periodic fresh publication of all fields. Around a 110 W load, SwitchBot's development team stated that a 30 W change was required for a report. Therefore, one- or five-minute polling does not imply measurement freshness at the same cadence. Long-running collectors should track retrieval time and freshness separately and detect stale runs explicitly. The app-triggered refresh mechanism and atomicity of accompanying status-field updates remain unverified.",
    "ja": "今回調査したSwitchBot Plug Mini (JP)では、OpenAPI v1.1が長時間同じ電気量statusを返すことは、負荷帯別の変化しきい値を用いる報告仕様によって正常に起こり得る。約110W負荷では、SwitchBot開発部門は報告に30Wの変化が必要と回答した。このため1分または5分周期でAPIを取得しても、その周期で測定値が新鮮であることは保証されない。長期収集では取得時刻とfreshnessを分離し、stale連続を明示的に検出すべきである。アプリ詳細画面に伴う更新メカニズムと報告時の各status fieldの同時更新保証は未検証である。",
    "evidence_basis_refs": ["C-001", "C-002", "C-003", "C-004", "C-005"],
    "remaining_uncertainties": ["Whether threshold-triggered reports atomically refresh voltage, electricCurrent, electricityOfDay, and power-related fields.", "Whether opening the app detail screen issues a direct refresh/synchronization command and through which protocol or message path.", "Whether the same default thresholds apply identically to all Plug Mini (JP) hardware/firmware revisions."],
    "recommended_next_actions": ["Preserve any future manufacturer response to the two follow-up questions as a new source and revise C-006/C-007 without rewriting prior history.", "If raw logger output is recovered, add it as a raw artifact with hash and exact timestamps.", "For production collectors, add stale-detection metadata rather than assuming every API retrieval is a fresh device measurement."]
  },
  "data_artifacts": [
    {"id": "AR-001", "type": "document", "path": "../2026-08-12-switchbot-plug-mini-openapi.md", "media_type": "text/markdown", "sha256": null, "public": false, "description": {"en": "Legacy pre-standard experiment note retained as the source note for this formal backfill.", "ja": "本正式バックフィルのsource noteとして保持する標準制定前の旧実験ノート。"}}
  ],
  "sources": [
    {"id": "SRC-001", "type": "manufacturer_documentation", "title": "SwitchBot support response based on development-team investigation of Plug Mini layered reporting behavior", "publisher": "SwitchBot", "url": null, "accessed_at": "2026-08-19", "version": null, "reliability": "HIGH", "notes": "Private support correspondence. Public record omits email addresses, device identifiers, MAC address, purchase/order data, account data, and other private identifiers."},
    {"id": "SRC-002", "type": "manufacturer_documentation", "title": "Follow-up questions concerning simultaneous field refresh and app detail-screen synchronization", "publisher": "SwitchBot support correspondence", "url": null, "accessed_at": "2026-08-21", "version": null, "reliability": "UNKNOWN", "notes": "The two questions were escalated for further investigation; no substantive answer was available at backfill time."}
  ],
  "provenance": {
    "generated_by": "AI",
    "ai_systems": [{"system": "ChatGPT", "model": "GPT-5.6 Sol", "roles": ["evidence reconstruction", "evidence classification", "backfill normalization", "documentation"]}],
    "human_roles": [{"role": "operator", "activities": ["API logging", "device reset", "mobile-app operation", "network-condition changes", "manufacturer inquiry", "observation reporting"]}],
    "automation_systems": ["Python logger", "Google Apps Script logger"],
    "human_editing": "UNKNOWN",
    "backfill": {"performed_at": "2026-08-22T12:19:00+09:00", "original_experiment_date": "2026-08-12", "source_record": "experiments/2026-08-12-switchbot-plug-mini-openapi.md", "reason": "Convert a pre-standard experiment note and later manufacturer correspondence into the formal canonical structure without fabricating missing execution details."}
  },
  "publication": {
    "public": true,
    "languages": {"en": {"published": true, "url": "https://ai-experiment-log.pages.dev/en/experiments/switchbot-plug-mini-openapi-layered-reporting/", "canonical": false}, "ja": {"published": true, "url": "https://ai-experiment-log.pages.dev/ja/experiments/switchbot-plug-mini-openapi-layered-reporting/", "canonical": false}},
    "machine_readable_url": "https://ai-experiment-log.pages.dev/data/experiments/AIEL-2026-0001/experiment.json"
  },
  "relationships": [],
  "revisions": [
    {"revision": 1, "timestamp": null, "type": "INITIAL", "summary": "Original pre-standard experiment observations recorded on 2026-08-12; exact creation time was not retained."},
    {"revision": 2, "timestamp": "2026-08-19T18:30:00+08:00", "type": "CONCLUSION_UPDATED", "summary": "Manufacturer development-team response verified layered reporting thresholds and resolved the main stale-behavior question."},
    {"revision": 3, "timestamp": "2026-08-22T12:19:00+09:00", "type": "METADATA_UPDATE", "summary": "Backfilled into Experiment Data Specification v1.0 structure with privacy-sensitive identifiers omitted and unknown timestamps represented as null."},
    {"revision": 4, "timestamp": "2026-08-22T12:30:00+09:00", "type": "PUBLICATION_UPDATE", "summary": "Manual publication review completed and bilingual/Hugo CI validation passed. Public deployment remains unverified, so publication flags and published_at remain unchanged."},
    {"revision": 5, "timestamp": "2026-08-22T12:49:54+09:00", "type": "METADATA_UPDATE", "summary": "Gitleaks 8.24.3 completed an automated full Git-history secret scan in GitHub Actions (workflow run 32550039781): 140 commits and approximately 519.83 KB scanned; no leaks found. secret_scan_performed updated to true."},
    {"revision": 6, "timestamp": "2026-08-22T12:52:00+09:00", "type": "PUBLICATION_UPDATE", "summary": "Production availability of both English and Japanese Cloudflare Pages URLs was directly observed in the user's browser screenshots at 2026-08-22 12:42:52-12:42:56 JST. publication.public and both language published flags were set to true. timestamps.published_at records the first verified public-availability observation (12:42:52 JST), not the underlying Cloudflare deployment event time, which was not independently established."},
    {"revision": 7, "timestamp": "2026-08-22T13:01:12+09:00", "type": "PUBLICATION_UPDATE", "summary": "GitHub Actions production verification run 32550560059 performed an HTTP GET of https://ai-experiment-log.pages.dev/data/experiments/AIEL-2026-0001/experiment.json and verified HTTP 200 with experiment_id=AIEL-2026-0001 on attempt 1. machine_readable_url was established from this direct production check."}
  ],
  "security": {
    "contains_sensitive_data": false,
    "redactions_applied": true,
    "redaction_categories": ["account_identifier", "device_identifier", "purchase_identifier", "email_address", "household_details"],
    "secret_scan_performed": true,
    "publication_reviewed": true
  }
}
