diff --git a/.ha_run.lock b/.ha_run.lock index 352bf00..b502ba8 100644 --- a/.ha_run.lock +++ b/.ha_run.lock @@ -1 +1 @@ -{"pid": 70, "version": 1, "ha_version": "2026.8.1", "start_ts": 1786755431.7882934} \ No newline at end of file +{"pid": 71, "version": 1, "ha_version": "2026.8.3", "start_ts": 1787912264.3193414} \ No newline at end of file diff --git a/esphome/.device-builder.json b/esphome/.device-builder.json index 203cfef..31fc300 100644 --- a/esphome/.device-builder.json +++ b/esphome/.device-builder.json @@ -317,13 +317,13 @@ }, "_firmware_jobs": [ { - "job_id": "a473e1ff91a1", - "configuration": "esp-bedside-panel.yaml", + "job_id": "2cd50350cbc3", + "configuration": "esp-ledmatrix1.yaml", "job_type": "upload", "status": "completed", - "created_at": "2026-08-15T02:02:52.316971+00:00", - "started_at": "2026-08-15T02:14:19.408959+00:00", - "completed_at": "2026-08-15T02:14:50.774825+00:00", + "created_at": "2026-08-29T00:39:06.205108+00:00", + "started_at": "2026-08-29T00:50:38.877520+00:00", + "completed_at": "2026-08-29T00:51:35.597834+00:00", "compile_started_at": null, "compile_ended_at": null, "exit_code": 0, @@ -332,7 +332,7 @@ "flash_bootloader": false, "is_deferred_install": false, "new_name": "", - "depends_on": "2fbca35e3c95", + "depends_on": "59d944b40572", "dependency_released": true, "progress": 100, "remote_peer": "", @@ -348,15 +348,15 @@ "failure_reason": "" }, { - "job_id": "2fbca35e3c95", - "configuration": "esp-bedside-panel.yaml", + "job_id": "59d944b40572", + "configuration": "esp-ledmatrix1.yaml", "job_type": "compile", "status": "completed", - "created_at": "2026-08-15T02:02:52.316913+00:00", - "started_at": "2026-08-15T02:02:52.317974+00:00", - "completed_at": "2026-08-15T02:14:19.407163+00:00", - "compile_started_at": "2026-08-15T02:05:17.332991+00:00", - "compile_ended_at": "2026-08-15T02:14:07.196719+00:00", + "created_at": "2026-08-29T00:39:06.205074+00:00", + "started_at": "2026-08-29T00:46:31.238162+00:00", + "completed_at": "2026-08-29T00:50:38.876255+00:00", + "compile_started_at": "2026-08-29T00:46:59.454123+00:00", + "compile_ended_at": "2026-08-29T00:50:30.129174+00:00", "exit_code": 0, "error": null, "port": "", @@ -379,13 +379,13 @@ "failure_reason": "" }, { - "job_id": "05a1d03fd4c9", - "configuration": "esp-centralstairs-top.yaml", + "job_id": "c4506c3b55c4", + "configuration": "esp-reterminal-e1001.yaml", "job_type": "upload", "status": "completed", - "created_at": "2026-08-12T06:11:24.834926+00:00", - "started_at": "2026-08-12T06:23:25.526769+00:00", - "completed_at": "2026-08-12T06:23:34.982995+00:00", + "created_at": "2026-08-29T00:37:55.752509+00:00", + "started_at": "2026-08-29T00:37:55.768623+00:00", + "completed_at": "2026-08-29T00:38:23.632536+00:00", "compile_started_at": null, "compile_ended_at": null, "exit_code": 0, @@ -394,7 +394,38 @@ "flash_bootloader": false, "is_deferred_install": false, "new_name": "", - "depends_on": "eea70cae5b4b", + "depends_on": "", + "dependency_released": false, + "progress": 100, + "remote_peer": "", + "remote_job_id": "", + "remote_peer_label": "", + "device_name": "", + "device_friendly_name": "", + "source": "local", + "source_pin_sha256": "", + "source_label": "", + "source_esphome_version": "", + "target_esphome_version": "", + "failure_reason": "" + }, + { + "job_id": "1b8de3463e62", + "configuration": "esp-garagedbcontrols.yaml", + "job_type": "upload", + "status": "completed", + "created_at": "2026-08-29T00:37:29.223509+00:00", + "started_at": "2026-08-29T00:47:29.570427+00:00", + "completed_at": "2026-08-29T00:47:55.703990+00:00", + "compile_started_at": null, + "compile_ended_at": null, + "exit_code": 0, + "error": null, + "port": "OTA", + "flash_bootloader": false, + "is_deferred_install": false, + "new_name": "", + "depends_on": "56d8dc0b7221", "dependency_released": true, "progress": 100, "remote_peer": "", @@ -410,15 +441,15 @@ "failure_reason": "" }, { - "job_id": "eea70cae5b4b", - "configuration": "esp-centralstairs-top.yaml", + "job_id": "56d8dc0b7221", + "configuration": "esp-garagedbcontrols.yaml", "job_type": "compile", "status": "completed", - "created_at": "2026-08-12T06:11:24.834880+00:00", - "started_at": "2026-08-12T06:21:21.949657+00:00", - "completed_at": "2026-08-12T06:23:25.524993+00:00", - "compile_started_at": "2026-08-12T06:21:24.590651+00:00", - "compile_ended_at": "2026-08-12T06:23:24.055776+00:00", + "created_at": "2026-08-29T00:37:29.223467+00:00", + "started_at": "2026-08-29T00:44:55.516098+00:00", + "completed_at": "2026-08-29T00:47:29.569290+00:00", + "compile_started_at": "2026-08-29T00:44:58.170788+00:00", + "compile_ended_at": "2026-08-29T00:47:28.018630+00:00", "exit_code": 0, "error": null, "port": "", @@ -441,13 +472,13 @@ "failure_reason": "" }, { - "job_id": "c4a2e6f3bb36", - "configuration": "esp-centralstairs-bottom.yaml", + "job_id": "02ef8c1bc1de", + "configuration": "esp-downstloungemain.yaml", "job_type": "upload", "status": "completed", - "created_at": "2026-08-12T06:11:22.149090+00:00", - "started_at": "2026-08-12T06:21:21.943720+00:00", - "completed_at": "2026-08-12T06:21:28.496577+00:00", + "created_at": "2026-08-29T00:37:21.711082+00:00", + "started_at": "2026-08-29T00:44:55.507193+00:00", + "completed_at": "2026-08-29T00:45:06.823128+00:00", "compile_started_at": null, "compile_ended_at": null, "exit_code": 0, @@ -456,7 +487,7 @@ "flash_bootloader": false, "is_deferred_install": false, "new_name": "", - "depends_on": "730061c59987", + "depends_on": "8c28419483bb", "dependency_released": true, "progress": 100, "remote_peer": "", @@ -472,15 +503,15 @@ "failure_reason": "" }, { - "job_id": "730061c59987", - "configuration": "esp-centralstairs-bottom.yaml", + "job_id": "8c28419483bb", + "configuration": "esp-downstloungemain.yaml", "job_type": "compile", "status": "completed", - "created_at": "2026-08-12T06:11:22.149049+00:00", - "started_at": "2026-08-12T06:19:18.498381+00:00", - "completed_at": "2026-08-12T06:21:21.941025+00:00", - "compile_started_at": "2026-08-12T06:19:21.073513+00:00", - "compile_ended_at": "2026-08-12T06:21:20.478540+00:00", + "created_at": "2026-08-29T00:37:21.711044+00:00", + "started_at": "2026-08-29T00:43:21.788381+00:00", + "completed_at": "2026-08-29T00:44:55.506125+00:00", + "compile_started_at": "2026-08-29T00:43:24.749191+00:00", + "compile_ended_at": "2026-08-29T00:44:53.997616+00:00", "exit_code": 0, "error": null, "port": "", @@ -503,13 +534,13 @@ "failure_reason": "" }, { - "job_id": "a736d9dcc153", - "configuration": "esp-bedrm2lights.yaml", + "job_id": "94df75de931b", + "configuration": "esp-garageextcornerlight.yaml", "job_type": "upload", "status": "completed", - "created_at": "2026-08-12T06:11:13.845297+00:00", - "started_at": "2026-08-12T06:19:18.488204+00:00", - "completed_at": "2026-08-12T06:19:28.042254+00:00", + "created_at": "2026-08-29T00:34:20.155272+00:00", + "started_at": "2026-08-29T00:43:21.777042+00:00", + "completed_at": "2026-08-29T00:46:04.023245+00:00", "compile_started_at": null, "compile_ended_at": null, "exit_code": 0, @@ -518,7 +549,7 @@ "flash_bootloader": false, "is_deferred_install": false, "new_name": "", - "depends_on": "4d5614fb7667", + "depends_on": "7e5fc13bdf12", "dependency_released": true, "progress": 100, "remote_peer": "", @@ -534,15 +565,15 @@ "failure_reason": "" }, { - "job_id": "4d5614fb7667", - "configuration": "esp-bedrm2lights.yaml", + "job_id": "7e5fc13bdf12", + "configuration": "esp-garageextcornerlight.yaml", "job_type": "compile", "status": "completed", - "created_at": "2026-08-12T06:11:13.845258+00:00", - "started_at": "2026-08-12T06:17:14.541724+00:00", - "completed_at": "2026-08-12T06:19:18.485658+00:00", - "compile_started_at": "2026-08-12T06:17:17.164050+00:00", - "compile_ended_at": "2026-08-12T06:19:16.998559+00:00", + "created_at": "2026-08-29T00:34:20.155234+00:00", + "started_at": "2026-08-29T00:41:26.247098+00:00", + "completed_at": "2026-08-29T00:43:21.776154+00:00", + "compile_started_at": "2026-08-29T00:41:29.523361+00:00", + "compile_ended_at": "2026-08-29T00:43:20.258866+00:00", "exit_code": 0, "error": null, "port": "", @@ -565,13 +596,13 @@ "failure_reason": "" }, { - "job_id": "ebf22c4ec1e4", - "configuration": "esp-bedrm2fanswitch.yaml", + "job_id": "07c7f30c5ca7", + "configuration": "esp-garagebtproxy.yaml", "job_type": "upload", "status": "completed", - "created_at": "2026-08-12T06:11:07.484185+00:00", - "started_at": "2026-08-12T06:17:14.532716+00:00", - "completed_at": "2026-08-12T06:17:24.415493+00:00", + "created_at": "2026-08-29T00:33:14.922548+00:00", + "started_at": "2026-08-29T00:46:31.237967+00:00", + "completed_at": "2026-08-29T00:51:46.065331+00:00", "compile_started_at": null, "compile_ended_at": null, "exit_code": 0, @@ -580,7 +611,7 @@ "flash_bootloader": false, "is_deferred_install": false, "new_name": "", - "depends_on": "e670a4e9aaf3", + "depends_on": "b1834e0046e6", "dependency_released": true, "progress": 100, "remote_peer": "", @@ -596,15 +627,139 @@ "failure_reason": "" }, { - "job_id": "e670a4e9aaf3", - "configuration": "esp-bedrm2fanswitch.yaml", + "job_id": "b1834e0046e6", + "configuration": "esp-garagebtproxy.yaml", "job_type": "compile", "status": "completed", - "created_at": "2026-08-12T06:11:07.484146+00:00", - "started_at": "2026-08-12T06:15:10.126960+00:00", - "completed_at": "2026-08-12T06:17:14.530452+00:00", - "compile_started_at": "2026-08-12T06:15:12.830985+00:00", - "compile_ended_at": "2026-08-12T06:17:13.061744+00:00", + "created_at": "2026-08-29T00:33:14.922508+00:00", + "started_at": "2026-08-29T00:39:14.882821+00:00", + "completed_at": "2026-08-29T00:46:31.236797+00:00", + "compile_started_at": "2026-08-29T00:39:42.354143+00:00", + "compile_ended_at": "2026-08-29T00:46:21.467648+00:00", + "exit_code": 0, + "error": null, + "port": "", + "flash_bootloader": false, + "is_deferred_install": false, + "new_name": "", + "depends_on": "", + "dependency_released": false, + "progress": 99, + "remote_peer": "", + "remote_job_id": "", + "remote_peer_label": "", + "device_name": "", + "device_friendly_name": "", + "source": "remote", + "source_pin_sha256": "11faf1169a008873b779b7223309fd7d8def200d1548f7b62955f71a67796a12", + "source_label": "Panda ESPHome Builder", + "source_esphome_version": "2026.7.2", + "target_esphome_version": "", + "failure_reason": "" + }, + { + "job_id": "161794d5366d", + "configuration": "esp-bedside-panel.yaml", + "job_type": "upload", + "status": "completed", + "created_at": "2026-08-29T00:32:56.735547+00:00", + "started_at": "2026-08-29T00:41:26.237524+00:00", + "completed_at": "2026-08-29T00:41:53.070560+00:00", + "compile_started_at": null, + "compile_ended_at": null, + "exit_code": 0, + "error": null, + "port": "OTA", + "flash_bootloader": false, + "is_deferred_install": false, + "new_name": "", + "depends_on": "4a02934b5a69", + "dependency_released": true, + "progress": 100, + "remote_peer": "", + "remote_job_id": "", + "remote_peer_label": "", + "device_name": "", + "device_friendly_name": "", + "source": "local", + "source_pin_sha256": "", + "source_label": "", + "source_esphome_version": "", + "target_esphome_version": "", + "failure_reason": "" + }, + { + "job_id": "4a02934b5a69", + "configuration": "esp-bedside-panel.yaml", + "job_type": "compile", + "status": "completed", + "created_at": "2026-08-29T00:32:56.735506+00:00", + "started_at": "2026-08-29T00:38:58.094129+00:00", + "completed_at": "2026-08-29T00:41:26.236032+00:00", + "compile_started_at": "2026-08-29T00:39:09.607613+00:00", + "compile_ended_at": "2026-08-29T00:41:25.025989+00:00", + "exit_code": 0, + "error": null, + "port": "", + "flash_bootloader": false, + "is_deferred_install": false, + "new_name": "", + "depends_on": "", + "dependency_released": false, + "progress": 78, + "remote_peer": "", + "remote_job_id": "", + "remote_peer_label": "", + "device_name": "", + "device_friendly_name": "", + "source": "local", + "source_pin_sha256": "", + "source_label": "", + "source_esphome_version": "", + "target_esphome_version": "", + "failure_reason": "" + }, + { + "job_id": "44809a6bfacf", + "configuration": "esp-downstloungeoutside.yaml", + "job_type": "upload", + "status": "completed", + "created_at": "2026-08-29T00:32:49.431057+00:00", + "started_at": "2026-08-29T00:38:58.085238+00:00", + "completed_at": "2026-08-29T00:39:08.693448+00:00", + "compile_started_at": null, + "compile_ended_at": null, + "exit_code": 0, + "error": null, + "port": "OTA", + "flash_bootloader": false, + "is_deferred_install": false, + "new_name": "", + "depends_on": "15f8fc94b8e9", + "dependency_released": true, + "progress": 100, + "remote_peer": "", + "remote_job_id": "", + "remote_peer_label": "", + "device_name": "", + "device_friendly_name": "", + "source": "local", + "source_pin_sha256": "", + "source_label": "", + "source_esphome_version": "", + "target_esphome_version": "", + "failure_reason": "" + }, + { + "job_id": "15f8fc94b8e9", + "configuration": "esp-downstloungeoutside.yaml", + "job_type": "compile", + "status": "completed", + "created_at": "2026-08-29T00:32:49.431016+00:00", + "started_at": "2026-08-29T00:37:17.050853+00:00", + "completed_at": "2026-08-29T00:38:58.082947+00:00", + "compile_started_at": "2026-08-29T00:37:19.395316+00:00", + "compile_ended_at": "2026-08-29T00:38:56.489558+00:00", "exit_code": 0, "error": null, "port": "", @@ -627,75 +782,13 @@ "failure_reason": "" }, { - "job_id": "f404874c5865", - "configuration": "esp-bedrm1airfilter.yaml", - "job_type": "upload", - "status": "completed", - "created_at": "2026-08-12T06:10:58.768261+00:00", - "started_at": "2026-08-12T06:15:10.119533+00:00", - "completed_at": "2026-08-12T06:15:18.715219+00:00", - "compile_started_at": null, - "compile_ended_at": null, - "exit_code": 0, - "error": null, - "port": "OTA", - "flash_bootloader": false, - "is_deferred_install": false, - "new_name": "", - "depends_on": "0b236905f726", - "dependency_released": true, - "progress": 100, - "remote_peer": "", - "remote_job_id": "", - "remote_peer_label": "", - "device_name": "", - "device_friendly_name": "", - "source": "local", - "source_pin_sha256": "", - "source_label": "", - "source_esphome_version": "", - "target_esphome_version": "", - "failure_reason": "" - }, - { - "job_id": "0b236905f726", - "configuration": "esp-bedrm1airfilter.yaml", - "job_type": "compile", - "status": "completed", - "created_at": "2026-08-12T06:10:58.768219+00:00", - "started_at": "2026-08-12T06:13:02.290161+00:00", - "completed_at": "2026-08-12T06:15:10.117093+00:00", - "compile_started_at": "2026-08-12T06:13:04.764246+00:00", - "compile_ended_at": "2026-08-12T06:15:08.655342+00:00", - "exit_code": 0, - "error": null, - "port": "", - "flash_bootloader": false, - "is_deferred_install": false, - "new_name": "", - "depends_on": "", - "dependency_released": false, - "progress": null, - "remote_peer": "", - "remote_job_id": "", - "remote_peer_label": "", - "device_name": "", - "device_friendly_name": "", - "source": "local", - "source_pin_sha256": "", - "source_label": "", - "source_esphome_version": "", - "target_esphome_version": "", - "failure_reason": "" - }, - { - "job_id": "43ff758be814", + "job_id": "026f55ea0ab9", "configuration": "esp-arcademachine1.yaml", "job_type": "upload", "status": "completed", - "created_at": "2026-08-12T06:10:53.375603+00:00", - "started_at": "2026-08-12T06:13:02.233373+00:00", - "completed_at": "2026-08-12T06:13:12.365411+00:00", + "created_at": "2026-08-29T00:32:37.162822+00:00", + "started_at": "2026-08-29T00:39:14.882642+00:00", + "completed_at": "2026-08-29T00:39:27.549440+00:00", "compile_started_at": null, "compile_ended_at": null, "exit_code": 0, @@ -704,7 +797,7 @@ "flash_bootloader": false, "is_deferred_install": false, "new_name": "", - "depends_on": "af52dcc80c5c", + "depends_on": "96e7a927b84a", "dependency_released": true, "progress": 100, "remote_peer": "", @@ -720,77 +813,15 @@ "failure_reason": "" }, { - "job_id": "af52dcc80c5c", + "job_id": "96e7a927b84a", "configuration": "esp-arcademachine1.yaml", "job_type": "compile", "status": "completed", - "created_at": "2026-08-12T06:10:53.375529+00:00", - "started_at": "2026-08-12T06:10:53.388288+00:00", - "completed_at": "2026-08-12T06:13:02.231522+00:00", - "compile_started_at": "2026-08-12T06:10:56.525770+00:00", - "compile_ended_at": "2026-08-12T06:13:00.758596+00:00", - "exit_code": 0, - "error": null, - "port": "", - "flash_bootloader": false, - "is_deferred_install": false, - "new_name": "", - "depends_on": "", - "dependency_released": false, - "progress": null, - "remote_peer": "", - "remote_job_id": "", - "remote_peer_label": "", - "device_name": "", - "device_friendly_name": "", - "source": "local", - "source_pin_sha256": "", - "source_label": "", - "source_esphome_version": "", - "target_esphome_version": "", - "failure_reason": "" - }, - { - "job_id": "7b199c64b0e9", - "configuration": "esp-3dprinterpow.yaml", - "job_type": "upload", - "status": "completed", - "created_at": "2026-08-12T06:10:41.162002+00:00", - "started_at": "2026-08-12T06:23:26.985687+00:00", - "completed_at": "2026-08-12T06:23:40.457621+00:00", - "compile_started_at": null, - "compile_ended_at": null, - "exit_code": 0, - "error": null, - "port": "OTA", - "flash_bootloader": false, - "is_deferred_install": false, - "new_name": "", - "depends_on": "09a303016889", - "dependency_released": true, - "progress": 100, - "remote_peer": "", - "remote_job_id": "", - "remote_peer_label": "", - "device_name": "", - "device_friendly_name": "", - "source": "local", - "source_pin_sha256": "", - "source_label": "", - "source_esphome_version": "", - "target_esphome_version": "", - "failure_reason": "" - }, - { - "job_id": "09a303016889", - "configuration": "esp-3dprinterpow.yaml", - "job_type": "compile", - "status": "completed", - "created_at": "2026-08-12T06:10:41.161848+00:00", - "started_at": "2026-08-12T06:10:41.163624+00:00", - "completed_at": "2026-08-12T06:23:26.981545+00:00", - "compile_started_at": "2026-08-12T06:12:01.760774+00:00", - "compile_ended_at": "2026-08-12T06:23:23.398615+00:00", + "created_at": "2026-08-29T00:32:37.162780+00:00", + "started_at": "2026-08-29T00:36:54.787097+00:00", + "completed_at": "2026-08-29T00:39:14.879161+00:00", + "compile_started_at": "2026-08-29T00:37:05.265564+00:00", + "compile_ended_at": "2026-08-29T00:39:11.090558+00:00", "exit_code": 0, "error": null, "port": "", @@ -813,15 +844,46 @@ "failure_reason": "" }, { - "job_id": "504d1e6ab453", - "configuration": "esp-reterminal-e1001.yaml", + "job_id": "b225403c1a50", + "configuration": "esp-entrancebathrmlights.yaml", + "job_type": "upload", + "status": "completed", + "created_at": "2026-08-29T00:32:15.331584+00:00", + "started_at": "2026-08-29T00:36:54.786874+00:00", + "completed_at": "2026-08-29T00:37:17.440488+00:00", + "compile_started_at": null, + "compile_ended_at": null, + "exit_code": 0, + "error": null, + "port": "OTA", + "flash_bootloader": false, + "is_deferred_install": false, + "new_name": "", + "depends_on": "40f777e833c1", + "dependency_released": true, + "progress": 100, + "remote_peer": "", + "remote_job_id": "", + "remote_peer_label": "", + "device_name": "", + "device_friendly_name": "", + "source": "local", + "source_pin_sha256": "", + "source_label": "", + "source_esphome_version": "", + "target_esphome_version": "", + "failure_reason": "" + }, + { + "job_id": "40f777e833c1", + "configuration": "esp-entrancebathrmlights.yaml", "job_type": "compile", "status": "completed", - "created_at": "2026-08-02T04:40:59.135722+00:00", - "started_at": "2026-08-02T04:40:59.136484+00:00", - "completed_at": "2026-08-02T04:41:23.522874+00:00", - "compile_started_at": "2026-08-02T04:41:11.876316+00:00", - "compile_ended_at": "2026-08-02T04:41:14.205320+00:00", + "created_at": "2026-08-29T00:32:15.331546+00:00", + "started_at": "2026-08-29T00:35:30.755993+00:00", + "completed_at": "2026-08-29T00:36:54.780756+00:00", + "compile_started_at": "2026-08-29T00:35:39.682527+00:00", + "compile_ended_at": "2026-08-29T00:36:50.910591+00:00", "exit_code": 0, "error": null, "port": "", @@ -830,7 +892,7 @@ "new_name": "", "depends_on": "", "dependency_released": false, - "progress": 93, + "progress": null, "remote_peer": "", "remote_job_id": "", "remote_peer_label": "", @@ -844,23 +906,3495 @@ "failure_reason": "" }, { - "job_id": "5632451d7d90", - "configuration": "esp-reterminal-e1001.yaml", + "job_id": "b46c8dfabbdf", + "configuration": "esp-downstmasterbedrmlights.yaml", "job_type": "upload", - "status": "failed", - "created_at": "2026-08-02T04:29:21.758006+00:00", - "started_at": "2026-08-02T04:40:32.968152+00:00", - "completed_at": "2026-08-02T04:40:36.606158+00:00", + "status": "completed", + "created_at": "2026-08-29T00:32:09.169560+00:00", + "started_at": "2026-08-29T00:37:17.043352+00:00", + "completed_at": "2026-08-29T00:37:29.902647+00:00", "compile_started_at": null, "compile_ended_at": null, - "exit_code": 1, + "exit_code": 0, "error": null, "port": "OTA", "flash_bootloader": false, "is_deferred_install": false, "new_name": "", - "depends_on": "727bf11ecacb", + "depends_on": "7067ba00c35a", "dependency_released": true, + "progress": 100, + "remote_peer": "", + "remote_job_id": "", + "remote_peer_label": "", + "device_name": "", + "device_friendly_name": "", + "source": "local", + "source_pin_sha256": "", + "source_label": "", + "source_esphome_version": "", + "target_esphome_version": "", + "failure_reason": "" + }, + { + "job_id": "7067ba00c35a", + "configuration": "esp-downstmasterbedrmlights.yaml", + "job_type": "compile", + "status": "completed", + "created_at": "2026-08-29T00:32:09.169521+00:00", + "started_at": "2026-08-29T00:35:26.969685+00:00", + "completed_at": "2026-08-29T00:37:17.040074+00:00", + "compile_started_at": "2026-08-29T00:35:30.406667+00:00", + "compile_ended_at": "2026-08-29T00:37:15.476861+00:00", + "exit_code": 0, + "error": null, + "port": "", + "flash_bootloader": false, + "is_deferred_install": false, + "new_name": "", + "depends_on": "", + "dependency_released": false, + "progress": null, + "remote_peer": "", + "remote_job_id": "", + "remote_peer_label": "", + "device_name": "", + "device_friendly_name": "", + "source": "local", + "source_pin_sha256": "", + "source_label": "", + "source_esphome_version": "", + "target_esphome_version": "", + "failure_reason": "" + }, + { + "job_id": "a53c1fcee613", + "configuration": "esp-loungeenvironment.yaml", + "job_type": "upload", + "status": "completed", + "created_at": "2026-08-29T00:31:59.318746+00:00", + "started_at": "2026-08-29T00:35:26.957936+00:00", + "completed_at": "2026-08-29T00:36:08.140787+00:00", + "compile_started_at": null, + "compile_ended_at": null, + "exit_code": 0, + "error": null, + "port": "OTA", + "flash_bootloader": false, + "is_deferred_install": false, + "new_name": "", + "depends_on": "fa30f57dc17f", + "dependency_released": true, + "progress": 100, + "remote_peer": "", + "remote_job_id": "", + "remote_peer_label": "", + "device_name": "", + "device_friendly_name": "", + "source": "local", + "source_pin_sha256": "", + "source_label": "", + "source_esphome_version": "", + "target_esphome_version": "", + "failure_reason": "" + }, + { + "job_id": "fa30f57dc17f", + "configuration": "esp-loungeenvironment.yaml", + "job_type": "compile", + "status": "completed", + "created_at": "2026-08-29T00:31:59.318709+00:00", + "started_at": "2026-08-29T00:34:08.025111+00:00", + "completed_at": "2026-08-29T00:35:26.955541+00:00", + "compile_started_at": "2026-08-29T00:34:11.943966+00:00", + "compile_ended_at": "2026-08-29T00:35:26.730600+00:00", + "exit_code": 0, + "error": null, + "port": "", + "flash_bootloader": false, + "is_deferred_install": false, + "new_name": "", + "depends_on": "", + "dependency_released": false, + "progress": 38, + "remote_peer": "", + "remote_job_id": "", + "remote_peer_label": "", + "device_name": "", + "device_friendly_name": "", + "source": "local", + "source_pin_sha256": "", + "source_label": "", + "source_esphome_version": "", + "target_esphome_version": "", + "failure_reason": "" + }, + { + "job_id": "1001015f3ab1", + "configuration": "esp-entmulti.yaml", + "job_type": "upload", + "status": "completed", + "created_at": "2026-08-29T00:22:08.698093+00:00", + "started_at": "2026-08-29T00:35:30.755795+00:00", + "completed_at": "2026-08-29T00:38:49.289237+00:00", + "compile_started_at": null, + "compile_ended_at": null, + "exit_code": 0, + "error": null, + "port": "OTA", + "flash_bootloader": false, + "is_deferred_install": false, + "new_name": "", + "depends_on": "477266a2cdd0", + "dependency_released": true, + "progress": 100, + "remote_peer": "", + "remote_job_id": "", + "remote_peer_label": "", + "device_name": "", + "device_friendly_name": "", + "source": "local", + "source_pin_sha256": "", + "source_label": "", + "source_esphome_version": "", + "target_esphome_version": "", + "failure_reason": "" + }, + { + "job_id": "477266a2cdd0", + "configuration": "esp-entmulti.yaml", + "job_type": "compile", + "status": "completed", + "created_at": "2026-08-29T00:22:08.698055+00:00", + "started_at": "2026-08-29T00:31:32.126828+00:00", + "completed_at": "2026-08-29T00:35:30.751842+00:00", + "compile_started_at": "2026-08-29T00:32:01.128110+00:00", + "compile_ended_at": "2026-08-29T00:35:22.368188+00:00", + "exit_code": 0, + "error": null, + "port": "", + "flash_bootloader": false, + "is_deferred_install": false, + "new_name": "", + "depends_on": "", + "dependency_released": false, + "progress": 99, + "remote_peer": "", + "remote_job_id": "", + "remote_peer_label": "", + "device_name": "", + "device_friendly_name": "", + "source": "remote", + "source_pin_sha256": "11faf1169a008873b779b7223309fd7d8def200d1548f7b62955f71a67796a12", + "source_label": "Panda ESPHome Builder", + "source_esphome_version": "2026.7.2", + "target_esphome_version": "", + "failure_reason": "" + }, + { + "job_id": "535e50834ab3", + "configuration": "esp-reterminal-e1001.yaml", + "job_type": "compile", + "status": "completed", + "created_at": "2026-08-29T00:21:54.472064+00:00", + "started_at": "2026-08-29T00:29:23.430289+00:00", + "completed_at": "2026-08-29T00:34:07.997775+00:00", + "compile_started_at": "2026-08-29T00:29:43.680126+00:00", + "compile_ended_at": "2026-08-29T00:34:07.691959+00:00", + "exit_code": 0, + "error": null, + "port": "", + "flash_bootloader": false, + "is_deferred_install": true, + "new_name": "", + "depends_on": "", + "dependency_released": false, + "progress": 99, + "remote_peer": "", + "remote_job_id": "", + "remote_peer_label": "", + "device_name": "", + "device_friendly_name": "", + "source": "local", + "source_pin_sha256": "", + "source_label": "", + "source_esphome_version": "", + "target_esphome_version": "", + "failure_reason": "" + }, + { + "job_id": "5904b1e09e46", + "configuration": "esp-poolpumppower.yaml", + "job_type": "upload", + "status": "completed", + "created_at": "2026-08-29T00:21:49.612768+00:00", + "started_at": "2026-08-29T00:31:32.126630+00:00", + "completed_at": "2026-08-29T00:32:31.708947+00:00", + "compile_started_at": null, + "compile_ended_at": null, + "exit_code": 0, + "error": null, + "port": "OTA", + "flash_bootloader": false, + "is_deferred_install": false, + "new_name": "", + "depends_on": "2e5d17fb59c6", + "dependency_released": true, + "progress": 100, + "remote_peer": "", + "remote_job_id": "", + "remote_peer_label": "", + "device_name": "", + "device_friendly_name": "", + "source": "local", + "source_pin_sha256": "", + "source_label": "", + "source_esphome_version": "", + "target_esphome_version": "", + "failure_reason": "" + }, + { + "job_id": "2e5d17fb59c6", + "configuration": "esp-poolpumppower.yaml", + "job_type": "compile", + "status": "completed", + "created_at": "2026-08-29T00:21:49.612728+00:00", + "started_at": "2026-08-29T00:27:20.249459+00:00", + "completed_at": "2026-08-29T00:31:32.124845+00:00", + "compile_started_at": "2026-08-29T00:27:58.427601+00:00", + "compile_ended_at": "2026-08-29T00:31:21.853126+00:00", + "exit_code": 0, + "error": null, + "port": "", + "flash_bootloader": false, + "is_deferred_install": false, + "new_name": "", + "depends_on": "", + "dependency_released": false, + "progress": 99, + "remote_peer": "", + "remote_job_id": "", + "remote_peer_label": "", + "device_name": "", + "device_friendly_name": "", + "source": "remote", + "source_pin_sha256": "11faf1169a008873b779b7223309fd7d8def200d1548f7b62955f71a67796a12", + "source_label": "Panda ESPHome Builder", + "source_esphome_version": "2026.7.2", + "target_esphome_version": "", + "failure_reason": "" + }, + { + "job_id": "910445e88e59", + "configuration": "esp-poollightpower2.yaml", + "job_type": "upload", + "status": "completed", + "created_at": "2026-08-29T00:21:45.807855+00:00", + "started_at": "2026-08-29T00:29:23.422032+00:00", + "completed_at": "2026-08-29T00:29:47.377263+00:00", + "compile_started_at": null, + "compile_ended_at": null, + "exit_code": 0, + "error": null, + "port": "OTA", + "flash_bootloader": false, + "is_deferred_install": false, + "new_name": "", + "depends_on": "b29c61e957b2", + "dependency_released": true, + "progress": 100, + "remote_peer": "", + "remote_job_id": "", + "remote_peer_label": "", + "device_name": "", + "device_friendly_name": "", + "source": "local", + "source_pin_sha256": "", + "source_label": "", + "source_esphome_version": "", + "target_esphome_version": "", + "failure_reason": "" + }, + { + "job_id": "b29c61e957b2", + "configuration": "esp-poollightpower2.yaml", + "job_type": "compile", + "status": "completed", + "created_at": "2026-08-29T00:21:45.807809+00:00", + "started_at": "2026-08-29T00:26:17.351067+00:00", + "completed_at": "2026-08-29T00:29:23.417551+00:00", + "compile_started_at": "2026-08-29T00:26:20.310670+00:00", + "compile_ended_at": "2026-08-29T00:29:21.807162+00:00", + "exit_code": 0, + "error": null, + "port": "", + "flash_bootloader": false, + "is_deferred_install": false, + "new_name": "", + "depends_on": "", + "dependency_released": false, + "progress": null, + "remote_peer": "", + "remote_job_id": "", + "remote_peer_label": "", + "device_name": "", + "device_friendly_name": "", + "source": "local", + "source_pin_sha256": "", + "source_label": "", + "source_esphome_version": "", + "target_esphome_version": "", + "failure_reason": "" + }, + { + "job_id": "f02592eba146", + "configuration": "esp-rocktumbler.yaml", + "job_type": "upload", + "status": "completed", + "created_at": "2026-08-29T00:21:36.093006+00:00", + "started_at": "2026-08-29T00:27:20.249221+00:00", + "completed_at": "2026-08-29T00:27:34.134362+00:00", + "compile_started_at": null, + "compile_ended_at": null, + "exit_code": 0, + "error": null, + "port": "OTA", + "flash_bootloader": false, + "is_deferred_install": false, + "new_name": "", + "depends_on": "137ef7c2ed93", + "dependency_released": true, + "progress": 100, + "remote_peer": "", + "remote_job_id": "", + "remote_peer_label": "", + "device_name": "", + "device_friendly_name": "", + "source": "local", + "source_pin_sha256": "", + "source_label": "", + "source_esphome_version": "", + "target_esphome_version": "", + "failure_reason": "" + }, + { + "job_id": "137ef7c2ed93", + "configuration": "esp-rocktumbler.yaml", + "job_type": "compile", + "status": "completed", + "created_at": "2026-08-29T00:21:36.092964+00:00", + "started_at": "2026-08-29T00:26:02.437738+00:00", + "completed_at": "2026-08-29T00:27:20.242490+00:00", + "compile_started_at": "2026-08-29T00:26:11.656896+00:00", + "compile_ended_at": "2026-08-29T00:27:16.745643+00:00", + "exit_code": 0, + "error": null, + "port": "", + "flash_bootloader": false, + "is_deferred_install": false, + "new_name": "", + "depends_on": "", + "dependency_released": false, + "progress": null, + "remote_peer": "", + "remote_job_id": "", + "remote_peer_label": "", + "device_name": "", + "device_friendly_name": "", + "source": "remote", + "source_pin_sha256": "11faf1169a008873b779b7223309fd7d8def200d1548f7b62955f71a67796a12", + "source_label": "Panda ESPHome Builder", + "source_esphome_version": "2026.7.2", + "target_esphome_version": "", + "failure_reason": "" + }, + { + "job_id": "fba48f738cee", + "configuration": "esp-occupancystair.yaml", + "job_type": "upload", + "status": "completed", + "created_at": "2026-08-29T00:21:33.230863+00:00", + "started_at": "2026-08-29T00:26:17.306253+00:00", + "completed_at": "2026-08-29T00:26:33.188710+00:00", + "compile_started_at": null, + "compile_ended_at": null, + "exit_code": 0, + "error": null, + "port": "OTA", + "flash_bootloader": false, + "is_deferred_install": false, + "new_name": "", + "depends_on": "71b54e307235", + "dependency_released": true, + "progress": 100, + "remote_peer": "", + "remote_job_id": "", + "remote_peer_label": "", + "device_name": "", + "device_friendly_name": "", + "source": "local", + "source_pin_sha256": "", + "source_label": "", + "source_esphome_version": "", + "target_esphome_version": "", + "failure_reason": "" + }, + { + "job_id": "71b54e307235", + "configuration": "esp-occupancystair.yaml", + "job_type": "compile", + "status": "completed", + "created_at": "2026-08-29T00:21:33.230820+00:00", + "started_at": "2026-08-29T00:24:41.582691+00:00", + "completed_at": "2026-08-29T00:26:17.304440+00:00", + "compile_started_at": "2026-08-29T00:24:45.758672+00:00", + "compile_ended_at": "2026-08-29T00:26:17.063063+00:00", + "exit_code": 0, + "error": null, + "port": "", + "flash_bootloader": false, + "is_deferred_install": false, + "new_name": "", + "depends_on": "", + "dependency_released": false, + "progress": 42, + "remote_peer": "", + "remote_job_id": "", + "remote_peer_label": "", + "device_name": "", + "device_friendly_name": "", + "source": "local", + "source_pin_sha256": "", + "source_label": "", + "source_esphome_version": "", + "target_esphome_version": "", + "failure_reason": "" + }, + { + "job_id": "33d16bd0cde9", + "configuration": "esp-underhouselights.yaml", + "job_type": "upload", + "status": "completed", + "created_at": "2026-08-29T00:21:23.309749+00:00", + "started_at": "2026-08-29T00:24:41.579263+00:00", + "completed_at": "2026-08-29T00:24:57.276684+00:00", + "compile_started_at": null, + "compile_ended_at": null, + "exit_code": 0, + "error": null, + "port": "OTA", + "flash_bootloader": false, + "is_deferred_install": false, + "new_name": "", + "depends_on": "294597e0347f", + "dependency_released": true, + "progress": 100, + "remote_peer": "", + "remote_job_id": "", + "remote_peer_label": "", + "device_name": "", + "device_friendly_name": "", + "source": "local", + "source_pin_sha256": "", + "source_label": "", + "source_esphome_version": "", + "target_esphome_version": "", + "failure_reason": "" + }, + { + "job_id": "294597e0347f", + "configuration": "esp-underhouselights.yaml", + "job_type": "compile", + "status": "completed", + "created_at": "2026-08-29T00:21:23.309708+00:00", + "started_at": "2026-08-29T00:22:54.740384+00:00", + "completed_at": "2026-08-29T00:24:41.571514+00:00", + "compile_started_at": "2026-08-29T00:22:57.852664+00:00", + "compile_ended_at": "2026-08-29T00:24:40.026902+00:00", + "exit_code": 0, + "error": null, + "port": "", + "flash_bootloader": false, + "is_deferred_install": false, + "new_name": "", + "depends_on": "", + "dependency_released": false, + "progress": null, + "remote_peer": "", + "remote_job_id": "", + "remote_peer_label": "", + "device_name": "", + "device_friendly_name": "", + "source": "local", + "source_pin_sha256": "", + "source_label": "", + "source_esphome_version": "", + "target_esphome_version": "", + "failure_reason": "" + }, + { + "job_id": "0102ec4b2c16", + "configuration": "esp-officeusbhubpower.yaml", + "job_type": "upload", + "status": "completed", + "created_at": "2026-08-29T00:04:39.074220+00:00", + "started_at": "2026-08-29T00:26:02.437491+00:00", + "completed_at": "2026-08-29T00:26:13.173436+00:00", + "compile_started_at": null, + "compile_ended_at": null, + "exit_code": 0, + "error": null, + "port": "OTA", + "flash_bootloader": false, + "is_deferred_install": false, + "new_name": "", + "depends_on": "6000a7ab9a9c", + "dependency_released": true, + "progress": 100, + "remote_peer": "", + "remote_job_id": "", + "remote_peer_label": "", + "device_name": "", + "device_friendly_name": "", + "source": "local", + "source_pin_sha256": "", + "source_label": "", + "source_esphome_version": "", + "target_esphome_version": "", + "failure_reason": "" + }, + { + "job_id": "6000a7ab9a9c", + "configuration": "esp-officeusbhubpower.yaml", + "job_type": "compile", + "status": "completed", + "created_at": "2026-08-29T00:04:39.074186+00:00", + "started_at": "2026-08-29T00:22:14.590089+00:00", + "completed_at": "2026-08-29T00:26:02.433263+00:00", + "compile_started_at": "2026-08-29T00:22:23.222496+00:00", + "compile_ended_at": "2026-08-29T00:25:58.503017+00:00", + "exit_code": 0, + "error": null, + "port": "", + "flash_bootloader": false, + "is_deferred_install": false, + "new_name": "", + "depends_on": "", + "dependency_released": false, + "progress": null, + "remote_peer": "", + "remote_job_id": "", + "remote_peer_label": "", + "device_name": "", + "device_friendly_name": "", + "source": "remote", + "source_pin_sha256": "11faf1169a008873b779b7223309fd7d8def200d1548f7b62955f71a67796a12", + "source_label": "Panda ESPHome Builder", + "source_esphome_version": "2026.7.2", + "target_esphome_version": "", + "failure_reason": "" + }, + { + "job_id": "bccabfe5b865", + "configuration": "esp-officelights.yaml", + "job_type": "upload", + "status": "completed", + "created_at": "2026-08-29T00:04:35.224166+00:00", + "started_at": "2026-08-29T00:22:54.726210+00:00", + "completed_at": "2026-08-29T00:23:05.564246+00:00", + "compile_started_at": null, + "compile_ended_at": null, + "exit_code": 0, + "error": null, + "port": "OTA", + "flash_bootloader": false, + "is_deferred_install": false, + "new_name": "", + "depends_on": "10e05d8734ae", + "dependency_released": true, + "progress": 100, + "remote_peer": "", + "remote_job_id": "", + "remote_peer_label": "", + "device_name": "", + "device_friendly_name": "", + "source": "local", + "source_pin_sha256": "", + "source_label": "", + "source_esphome_version": "", + "target_esphome_version": "", + "failure_reason": "" + }, + { + "job_id": "10e05d8734ae", + "configuration": "esp-officelights.yaml", + "job_type": "compile", + "status": "completed", + "created_at": "2026-08-29T00:04:35.224113+00:00", + "started_at": "2026-08-29T00:21:06.659194+00:00", + "completed_at": "2026-08-29T00:22:54.724030+00:00", + "compile_started_at": "2026-08-29T00:21:08.993198+00:00", + "compile_ended_at": "2026-08-29T00:22:53.146982+00:00", + "exit_code": 0, + "error": null, + "port": "", + "flash_bootloader": false, + "is_deferred_install": false, + "new_name": "", + "depends_on": "", + "dependency_released": false, + "progress": null, + "remote_peer": "", + "remote_job_id": "", + "remote_peer_label": "", + "device_name": "", + "device_friendly_name": "", + "source": "local", + "source_pin_sha256": "", + "source_label": "", + "source_esphome_version": "", + "target_esphome_version": "", + "failure_reason": "" + }, + { + "job_id": "6bd542a7369b", + "configuration": "esp-officedeskrightgpo.yaml", + "job_type": "upload", + "status": "completed", + "created_at": "2026-08-29T00:04:31.046057+00:00", + "started_at": "2026-08-29T00:21:06.631829+00:00", + "completed_at": "2026-08-29T00:22:27.131623+00:00", + "compile_started_at": null, + "compile_ended_at": null, + "exit_code": 0, + "error": null, + "port": "OTA", + "flash_bootloader": false, + "is_deferred_install": false, + "new_name": "", + "depends_on": "4f469deda1a6", + "dependency_released": true, + "progress": 100, + "remote_peer": "", + "remote_job_id": "", + "remote_peer_label": "", + "device_name": "", + "device_friendly_name": "", + "source": "local", + "source_pin_sha256": "", + "source_label": "", + "source_esphome_version": "", + "target_esphome_version": "", + "failure_reason": "" + }, + { + "job_id": "4f469deda1a6", + "configuration": "esp-officedeskrightgpo.yaml", + "job_type": "compile", + "status": "completed", + "created_at": "2026-08-29T00:04:31.046017+00:00", + "started_at": "2026-08-29T00:19:18.459386+00:00", + "completed_at": "2026-08-29T00:21:06.629752+00:00", + "compile_started_at": "2026-08-29T00:19:20.719067+00:00", + "compile_ended_at": "2026-08-29T00:21:05.051464+00:00", + "exit_code": 0, + "error": null, + "port": "", + "flash_bootloader": false, + "is_deferred_install": false, + "new_name": "", + "depends_on": "", + "dependency_released": false, + "progress": null, + "remote_peer": "", + "remote_job_id": "", + "remote_peer_label": "", + "device_name": "", + "device_friendly_name": "", + "source": "local", + "source_pin_sha256": "", + "source_label": "", + "source_esphome_version": "", + "target_esphome_version": "", + "failure_reason": "" + }, + { + "job_id": "44ca711e1ad9", + "configuration": "esp-officeelvcontrol.yaml", + "job_type": "upload", + "status": "completed", + "created_at": "2026-08-29T00:04:27.766116+00:00", + "started_at": "2026-08-29T00:19:18.450932+00:00", + "completed_at": "2026-08-29T00:19:29.146943+00:00", + "compile_started_at": null, + "compile_ended_at": null, + "exit_code": 0, + "error": null, + "port": "OTA", + "flash_bootloader": false, + "is_deferred_install": false, + "new_name": "", + "depends_on": "0780a367c3a8", + "dependency_released": true, + "progress": 100, + "remote_peer": "", + "remote_job_id": "", + "remote_peer_label": "", + "device_name": "", + "device_friendly_name": "", + "source": "local", + "source_pin_sha256": "", + "source_label": "", + "source_esphome_version": "", + "target_esphome_version": "", + "failure_reason": "" + }, + { + "job_id": "0780a367c3a8", + "configuration": "esp-officeelvcontrol.yaml", + "job_type": "compile", + "status": "completed", + "created_at": "2026-08-29T00:04:27.766071+00:00", + "started_at": "2026-08-29T00:17:34.127124+00:00", + "completed_at": "2026-08-29T00:19:18.448569+00:00", + "compile_started_at": "2026-08-29T00:17:36.424684+00:00", + "compile_ended_at": "2026-08-29T00:19:16.900382+00:00", + "exit_code": 0, + "error": null, + "port": "", + "flash_bootloader": false, + "is_deferred_install": false, + "new_name": "", + "depends_on": "", + "dependency_released": false, + "progress": null, + "remote_peer": "", + "remote_job_id": "", + "remote_peer_label": "", + "device_name": "", + "device_friendly_name": "", + "source": "local", + "source_pin_sha256": "", + "source_label": "", + "source_esphome_version": "", + "target_esphome_version": "", + "failure_reason": "" + }, + { + "job_id": "eebe19862d4d", + "configuration": "esp-masterbdrmwest.yaml", + "job_type": "upload", + "status": "completed", + "created_at": "2026-08-29T00:04:18.891355+00:00", + "started_at": "2026-08-29T00:17:34.114133+00:00", + "completed_at": "2026-08-29T00:17:44.781972+00:00", + "compile_started_at": null, + "compile_ended_at": null, + "exit_code": 0, + "error": null, + "port": "OTA", + "flash_bootloader": false, + "is_deferred_install": false, + "new_name": "", + "depends_on": "b4b6388a4799", + "dependency_released": true, + "progress": 100, + "remote_peer": "", + "remote_job_id": "", + "remote_peer_label": "", + "device_name": "", + "device_friendly_name": "", + "source": "local", + "source_pin_sha256": "", + "source_label": "", + "source_esphome_version": "", + "target_esphome_version": "", + "failure_reason": "" + }, + { + "job_id": "b4b6388a4799", + "configuration": "esp-masterbdrmwest.yaml", + "job_type": "compile", + "status": "completed", + "created_at": "2026-08-29T00:04:18.891315+00:00", + "started_at": "2026-08-29T00:15:48.210459+00:00", + "completed_at": "2026-08-29T00:17:34.111571+00:00", + "compile_started_at": "2026-08-29T00:15:50.648837+00:00", + "compile_ended_at": "2026-08-29T00:17:32.528185+00:00", + "exit_code": 0, + "error": null, + "port": "", + "flash_bootloader": false, + "is_deferred_install": false, + "new_name": "", + "depends_on": "", + "dependency_released": false, + "progress": null, + "remote_peer": "", + "remote_job_id": "", + "remote_peer_label": "", + "device_name": "", + "device_friendly_name": "", + "source": "local", + "source_pin_sha256": "", + "source_label": "", + "source_esphome_version": "", + "target_esphome_version": "", + "failure_reason": "" + }, + { + "job_id": "4172f12d49f6", + "configuration": "esp-masterbdrmsouth.yaml", + "job_type": "upload", + "status": "completed", + "created_at": "2026-08-29T00:04:15.586571+00:00", + "started_at": "2026-08-29T00:15:48.165683+00:00", + "completed_at": "2026-08-29T00:15:57.689675+00:00", + "compile_started_at": null, + "compile_ended_at": null, + "exit_code": 0, + "error": null, + "port": "OTA", + "flash_bootloader": false, + "is_deferred_install": false, + "new_name": "", + "depends_on": "edb59ae8bb53", + "dependency_released": true, + "progress": 100, + "remote_peer": "", + "remote_job_id": "", + "remote_peer_label": "", + "device_name": "", + "device_friendly_name": "", + "source": "local", + "source_pin_sha256": "", + "source_label": "", + "source_esphome_version": "", + "target_esphome_version": "", + "failure_reason": "" + }, + { + "job_id": "edb59ae8bb53", + "configuration": "esp-masterbdrmsouth.yaml", + "job_type": "compile", + "status": "completed", + "created_at": "2026-08-29T00:04:15.586531+00:00", + "started_at": "2026-08-29T00:14:01.524643+00:00", + "completed_at": "2026-08-29T00:15:48.162830+00:00", + "compile_started_at": "2026-08-29T00:14:04.710893+00:00", + "compile_ended_at": "2026-08-29T00:15:46.577265+00:00", + "exit_code": 0, + "error": null, + "port": "", + "flash_bootloader": false, + "is_deferred_install": false, + "new_name": "", + "depends_on": "", + "dependency_released": false, + "progress": null, + "remote_peer": "", + "remote_job_id": "", + "remote_peer_label": "", + "device_name": "", + "device_friendly_name": "", + "source": "local", + "source_pin_sha256": "", + "source_label": "", + "source_esphome_version": "", + "target_esphome_version": "", + "failure_reason": "" + }, + { + "job_id": "c2c31e12227f", + "configuration": "esp-mainkitchenlights.yaml", + "job_type": "upload", + "status": "completed", + "created_at": "2026-08-29T00:04:01.146914+00:00", + "started_at": "2026-08-29T00:14:01.515480+00:00", + "completed_at": "2026-08-29T00:14:10.551996+00:00", + "compile_started_at": null, + "compile_ended_at": null, + "exit_code": 0, + "error": null, + "port": "OTA", + "flash_bootloader": false, + "is_deferred_install": false, + "new_name": "", + "depends_on": "22cc83653c75", + "dependency_released": true, + "progress": 100, + "remote_peer": "", + "remote_job_id": "", + "remote_peer_label": "", + "device_name": "", + "device_friendly_name": "", + "source": "local", + "source_pin_sha256": "", + "source_label": "", + "source_esphome_version": "", + "target_esphome_version": "", + "failure_reason": "" + }, + { + "job_id": "22cc83653c75", + "configuration": "esp-mainkitchenlights.yaml", + "job_type": "compile", + "status": "completed", + "created_at": "2026-08-29T00:04:01.146872+00:00", + "started_at": "2026-08-29T00:12:16.720666+00:00", + "completed_at": "2026-08-29T00:14:01.512729+00:00", + "compile_started_at": "2026-08-29T00:12:19.664045+00:00", + "compile_ended_at": "2026-08-29T00:13:59.774057+00:00", + "exit_code": 0, + "error": null, + "port": "", + "flash_bootloader": false, + "is_deferred_install": false, + "new_name": "", + "depends_on": "", + "dependency_released": false, + "progress": null, + "remote_peer": "", + "remote_job_id": "", + "remote_peer_label": "", + "device_name": "", + "device_friendly_name": "", + "source": "local", + "source_pin_sha256": "", + "source_label": "", + "source_esphome_version": "", + "target_esphome_version": "", + "failure_reason": "" + }, + { + "job_id": "ba5609857649", + "configuration": "esp-mainpowermonitor.yaml", + "job_type": "upload", + "status": "completed", + "created_at": "2026-08-29T00:03:57.930772+00:00", + "started_at": "2026-08-29T00:22:14.589884+00:00", + "completed_at": "2026-08-29T00:22:26.593718+00:00", + "compile_started_at": null, + "compile_ended_at": null, + "exit_code": 0, + "error": null, + "port": "OTA", + "flash_bootloader": false, + "is_deferred_install": false, + "new_name": "", + "depends_on": "3023b045dbdc", + "dependency_released": true, + "progress": 100, + "remote_peer": "", + "remote_job_id": "", + "remote_peer_label": "", + "device_name": "", + "device_friendly_name": "", + "source": "local", + "source_pin_sha256": "", + "source_label": "", + "source_esphome_version": "", + "target_esphome_version": "", + "failure_reason": "" + }, + { + "job_id": "3023b045dbdc", + "configuration": "esp-mainpowermonitor.yaml", + "job_type": "compile", + "status": "completed", + "created_at": "2026-08-29T00:03:57.930731+00:00", + "started_at": "2026-08-29T00:10:17.379235+00:00", + "completed_at": "2026-08-29T00:22:14.571658+00:00", + "compile_started_at": "2026-08-29T00:10:28.889058+00:00", + "compile_ended_at": "2026-08-29T00:22:11.068323+00:00", + "exit_code": 0, + "error": null, + "port": "", + "flash_bootloader": false, + "is_deferred_install": false, + "new_name": "", + "depends_on": "", + "dependency_released": false, + "progress": null, + "remote_peer": "", + "remote_job_id": "", + "remote_peer_label": "", + "device_name": "", + "device_friendly_name": "", + "source": "remote", + "source_pin_sha256": "11faf1169a008873b779b7223309fd7d8def200d1548f7b62955f71a67796a12", + "source_label": "Panda ESPHome Builder", + "source_esphome_version": "2026.7.2", + "target_esphome_version": "", + "failure_reason": "" + }, + { + "job_id": "1c9cbe8db40f", + "configuration": "esp-mainhallwaynightlights.yaml", + "job_type": "upload", + "status": "completed", + "created_at": "2026-08-29T00:03:54.239430+00:00", + "started_at": "2026-08-29T00:10:17.379053+00:00", + "completed_at": "2026-08-29T00:10:47.055996+00:00", + "compile_started_at": null, + "compile_ended_at": null, + "exit_code": 0, + "error": null, + "port": "OTA", + "flash_bootloader": false, + "is_deferred_install": false, + "new_name": "", + "depends_on": "9a799a2890a6", + "dependency_released": true, + "progress": 100, + "remote_peer": "", + "remote_job_id": "", + "remote_peer_label": "", + "device_name": "", + "device_friendly_name": "", + "source": "local", + "source_pin_sha256": "", + "source_label": "", + "source_esphome_version": "", + "target_esphome_version": "", + "failure_reason": "" + }, + { + "job_id": "9a799a2890a6", + "configuration": "esp-mainhallwaynightlights.yaml", + "job_type": "compile", + "status": "completed", + "created_at": "2026-08-29T00:03:54.239388+00:00", + "started_at": "2026-08-29T00:03:54.240189+00:00", + "completed_at": "2026-08-29T00:10:17.377455+00:00", + "compile_started_at": "2026-08-29T00:04:11.071021+00:00", + "compile_ended_at": "2026-08-29T00:10:10.603093+00:00", + "exit_code": 0, + "error": null, + "port": "", + "flash_bootloader": false, + "is_deferred_install": false, + "new_name": "", + "depends_on": "", + "dependency_released": false, + "progress": null, + "remote_peer": "", + "remote_job_id": "", + "remote_peer_label": "", + "device_name": "", + "device_friendly_name": "", + "source": "remote", + "source_pin_sha256": "11faf1169a008873b779b7223309fd7d8def200d1548f7b62955f71a67796a12", + "source_label": "Panda ESPHome Builder", + "source_esphome_version": "2026.7.2", + "target_esphome_version": "", + "failure_reason": "" + }, + { + "job_id": "c9faeba1b8bc", + "configuration": "esp-mainhallwaymainlights.yaml", + "job_type": "upload", + "status": "completed", + "created_at": "2026-08-29T00:03:50.959672+00:00", + "started_at": "2026-08-29T00:12:16.713680+00:00", + "completed_at": "2026-08-29T00:12:28.257573+00:00", + "compile_started_at": null, + "compile_ended_at": null, + "exit_code": 0, + "error": null, + "port": "OTA", + "flash_bootloader": false, + "is_deferred_install": false, + "new_name": "", + "depends_on": "b304e4b18358", + "dependency_released": true, + "progress": 100, + "remote_peer": "", + "remote_job_id": "", + "remote_peer_label": "", + "device_name": "", + "device_friendly_name": "", + "source": "local", + "source_pin_sha256": "", + "source_label": "", + "source_esphome_version": "", + "target_esphome_version": "", + "failure_reason": "" + }, + { + "job_id": "b304e4b18358", + "configuration": "esp-mainhallwaymainlights.yaml", + "job_type": "compile", + "status": "completed", + "created_at": "2026-08-29T00:03:50.959626+00:00", + "started_at": "2026-08-29T00:10:32.701161+00:00", + "completed_at": "2026-08-29T00:12:16.712024+00:00", + "compile_started_at": "2026-08-29T00:10:35.301598+00:00", + "compile_ended_at": "2026-08-29T00:12:15.189400+00:00", + "exit_code": 0, + "error": null, + "port": "", + "flash_bootloader": false, + "is_deferred_install": false, + "new_name": "", + "depends_on": "", + "dependency_released": false, + "progress": null, + "remote_peer": "", + "remote_job_id": "", + "remote_peer_label": "", + "device_name": "", + "device_friendly_name": "", + "source": "local", + "source_pin_sha256": "", + "source_label": "", + "source_esphome_version": "", + "target_esphome_version": "", + "failure_reason": "" + }, + { + "job_id": "44f1be191648", + "configuration": "esp-entrancelightswitch.yaml", + "job_type": "upload", + "status": "completed", + "created_at": "2026-08-29T00:03:46.365003+00:00", + "started_at": "2026-08-29T00:10:32.690031+00:00", + "completed_at": "2026-08-29T00:10:42.454211+00:00", + "compile_started_at": null, + "compile_ended_at": null, + "exit_code": 0, + "error": null, + "port": "OTA", + "flash_bootloader": false, + "is_deferred_install": false, + "new_name": "", + "depends_on": "616b020a440e", + "dependency_released": true, + "progress": 100, + "remote_peer": "", + "remote_job_id": "", + "remote_peer_label": "", + "device_name": "", + "device_friendly_name": "", + "source": "local", + "source_pin_sha256": "", + "source_label": "", + "source_esphome_version": "", + "target_esphome_version": "", + "failure_reason": "" + }, + { + "job_id": "616b020a440e", + "configuration": "esp-entrancelightswitch.yaml", + "job_type": "compile", + "status": "completed", + "created_at": "2026-08-29T00:03:46.364964+00:00", + "started_at": "2026-08-29T00:08:47.860780+00:00", + "completed_at": "2026-08-29T00:10:32.688105+00:00", + "compile_started_at": "2026-08-29T00:08:50.818734+00:00", + "compile_ended_at": "2026-08-29T00:10:31.152726+00:00", + "exit_code": 0, + "error": null, + "port": "", + "flash_bootloader": false, + "is_deferred_install": false, + "new_name": "", + "depends_on": "", + "dependency_released": false, + "progress": null, + "remote_peer": "", + "remote_job_id": "", + "remote_peer_label": "", + "device_name": "", + "device_friendly_name": "", + "source": "local", + "source_pin_sha256": "", + "source_label": "", + "source_esphome_version": "", + "target_esphome_version": "", + "failure_reason": "" + }, + { + "job_id": "7b1a6bb9667f", + "configuration": "esp-maindishwasherpower.yaml", + "job_type": "upload", + "status": "completed", + "created_at": "2026-08-29T00:03:39.628919+00:00", + "started_at": "2026-08-29T00:08:47.852583+00:00", + "completed_at": "2026-08-29T00:09:53.783756+00:00", + "compile_started_at": null, + "compile_ended_at": null, + "exit_code": 0, + "error": null, + "port": "OTA", + "flash_bootloader": false, + "is_deferred_install": false, + "new_name": "", + "depends_on": "582af4d71ade", + "dependency_released": true, + "progress": 100, + "remote_peer": "", + "remote_job_id": "", + "remote_peer_label": "", + "device_name": "", + "device_friendly_name": "", + "source": "local", + "source_pin_sha256": "", + "source_label": "", + "source_esphome_version": "", + "target_esphome_version": "", + "failure_reason": "" + }, + { + "job_id": "582af4d71ade", + "configuration": "esp-maindishwasherpower.yaml", + "job_type": "compile", + "status": "completed", + "created_at": "2026-08-29T00:03:39.628867+00:00", + "started_at": "2026-08-29T00:07:04.724102+00:00", + "completed_at": "2026-08-29T00:08:47.850465+00:00", + "compile_started_at": "2026-08-29T00:07:10.427799+00:00", + "compile_ended_at": "2026-08-29T00:08:47.605973+00:00", + "exit_code": 0, + "error": null, + "port": "", + "flash_bootloader": false, + "is_deferred_install": false, + "new_name": "", + "depends_on": "", + "dependency_released": false, + "progress": 36, + "remote_peer": "", + "remote_job_id": "", + "remote_peer_label": "", + "device_name": "", + "device_friendly_name": "", + "source": "local", + "source_pin_sha256": "", + "source_label": "", + "source_esphome_version": "", + "target_esphome_version": "", + "failure_reason": "" + }, + { + "job_id": "900238933a98", + "configuration": "esp-mainbathroomlights.yaml", + "job_type": "upload", + "status": "completed", + "created_at": "2026-08-29T00:03:33.599542+00:00", + "started_at": "2026-08-29T00:07:04.711692+00:00", + "completed_at": "2026-08-29T00:07:48.749730+00:00", + "compile_started_at": null, + "compile_ended_at": null, + "exit_code": 0, + "error": null, + "port": "OTA", + "flash_bootloader": false, + "is_deferred_install": false, + "new_name": "", + "depends_on": "abb51ab2e92e", + "dependency_released": true, + "progress": 100, + "remote_peer": "", + "remote_job_id": "", + "remote_peer_label": "", + "device_name": "", + "device_friendly_name": "", + "source": "local", + "source_pin_sha256": "", + "source_label": "", + "source_esphome_version": "", + "target_esphome_version": "", + "failure_reason": "" + }, + { + "job_id": "abb51ab2e92e", + "configuration": "esp-mainbathroomlights.yaml", + "job_type": "compile", + "status": "completed", + "created_at": "2026-08-29T00:03:33.599491+00:00", + "started_at": "2026-08-29T00:03:33.600779+00:00", + "completed_at": "2026-08-29T00:07:04.708538+00:00", + "compile_started_at": "2026-08-29T00:03:50.014817+00:00", + "compile_ended_at": "2026-08-29T00:07:02.199214+00:00", + "exit_code": 0, + "error": null, + "port": "", + "flash_bootloader": false, + "is_deferred_install": false, + "new_name": "", + "depends_on": "", + "dependency_released": false, + "progress": null, + "remote_peer": "", + "remote_job_id": "", + "remote_peer_label": "", + "device_name": "", + "device_friendly_name": "", + "source": "local", + "source_pin_sha256": "", + "source_label": "", + "source_esphome_version": "", + "target_esphome_version": "", + "failure_reason": "" + }, + { + "job_id": "7439685de152", + "configuration": "esp-mainhallwaynorthlightswitch.yaml", + "job_type": "upload", + "status": "completed", + "created_at": "2026-08-28T23:38:48.668799+00:00", + "started_at": "2026-08-28T23:58:04.531031+00:00", + "completed_at": "2026-08-28T23:58:14.540698+00:00", + "compile_started_at": null, + "compile_ended_at": null, + "exit_code": 0, + "error": null, + "port": "OTA", + "flash_bootloader": false, + "is_deferred_install": false, + "new_name": "", + "depends_on": "f5966ba29c9a", + "dependency_released": true, + "progress": 100, + "remote_peer": "", + "remote_job_id": "", + "remote_peer_label": "", + "device_name": "", + "device_friendly_name": "", + "source": "local", + "source_pin_sha256": "", + "source_label": "", + "source_esphome_version": "", + "target_esphome_version": "", + "failure_reason": "" + }, + { + "job_id": "f5966ba29c9a", + "configuration": "esp-mainhallwaynorthlightswitch.yaml", + "job_type": "compile", + "status": "completed", + "created_at": "2026-08-28T23:38:48.668758+00:00", + "started_at": "2026-08-28T23:56:22.997984+00:00", + "completed_at": "2026-08-28T23:58:04.528282+00:00", + "compile_started_at": "2026-08-28T23:56:25.274343+00:00", + "compile_ended_at": "2026-08-28T23:58:02.971325+00:00", + "exit_code": 0, + "error": null, + "port": "", + "flash_bootloader": false, + "is_deferred_install": false, + "new_name": "", + "depends_on": "", + "dependency_released": false, + "progress": null, + "remote_peer": "", + "remote_job_id": "", + "remote_peer_label": "", + "device_name": "", + "device_friendly_name": "", + "source": "local", + "source_pin_sha256": "", + "source_label": "", + "source_esphome_version": "", + "target_esphome_version": "", + "failure_reason": "" + }, + { + "job_id": "632b31b7f3b7", + "configuration": "esp-mainbathfancombo.yaml", + "job_type": "upload", + "status": "completed", + "created_at": "2026-08-28T23:38:45.457269+00:00", + "started_at": "2026-08-28T23:59:03.421384+00:00", + "completed_at": "2026-08-28T23:59:15.020240+00:00", + "compile_started_at": null, + "compile_ended_at": null, + "exit_code": 0, + "error": null, + "port": "OTA", + "flash_bootloader": false, + "is_deferred_install": false, + "new_name": "", + "depends_on": "a340804afc46", + "dependency_released": true, + "progress": 100, + "remote_peer": "", + "remote_job_id": "", + "remote_peer_label": "", + "device_name": "", + "device_friendly_name": "", + "source": "local", + "source_pin_sha256": "", + "source_label": "", + "source_esphome_version": "", + "target_esphome_version": "", + "failure_reason": "" + }, + { + "job_id": "a340804afc46", + "configuration": "esp-mainbathfancombo.yaml", + "job_type": "compile", + "status": "completed", + "created_at": "2026-08-28T23:38:45.457210+00:00", + "started_at": "2026-08-28T23:55:15.391978+00:00", + "completed_at": "2026-08-28T23:59:03.419068+00:00", + "compile_started_at": "2026-08-28T23:55:24.369776+00:00", + "compile_ended_at": "2026-08-28T23:59:00.093744+00:00", + "exit_code": 0, + "error": null, + "port": "", + "flash_bootloader": false, + "is_deferred_install": false, + "new_name": "", + "depends_on": "", + "dependency_released": false, + "progress": null, + "remote_peer": "", + "remote_job_id": "", + "remote_peer_label": "", + "device_name": "", + "device_friendly_name": "", + "source": "remote", + "source_pin_sha256": "11faf1169a008873b779b7223309fd7d8def200d1548f7b62955f71a67796a12", + "source_label": "Panda ESPHome Builder", + "source_esphome_version": "2026.7.2", + "target_esphome_version": "", + "failure_reason": "" + }, + { + "job_id": "bb21873ff1f3", + "configuration": "esp-loungewestswitch.yaml", + "job_type": "upload", + "status": "completed", + "created_at": "2026-08-28T23:38:41.457895+00:00", + "started_at": "2026-08-28T23:56:22.987591+00:00", + "completed_at": "2026-08-28T23:56:33.226905+00:00", + "compile_started_at": null, + "compile_ended_at": null, + "exit_code": 0, + "error": null, + "port": "OTA", + "flash_bootloader": false, + "is_deferred_install": false, + "new_name": "", + "depends_on": "caf92bb25f16", + "dependency_released": true, + "progress": 100, + "remote_peer": "", + "remote_job_id": "", + "remote_peer_label": "", + "device_name": "", + "device_friendly_name": "", + "source": "local", + "source_pin_sha256": "", + "source_label": "", + "source_esphome_version": "", + "target_esphome_version": "", + "failure_reason": "" + }, + { + "job_id": "caf92bb25f16", + "configuration": "esp-loungewestswitch.yaml", + "job_type": "compile", + "status": "completed", + "created_at": "2026-08-28T23:38:41.457858+00:00", + "started_at": "2026-08-28T23:54:35.647156+00:00", + "completed_at": "2026-08-28T23:56:22.985555+00:00", + "compile_started_at": "2026-08-28T23:54:37.949688+00:00", + "compile_ended_at": "2026-08-28T23:56:21.443896+00:00", + "exit_code": 0, + "error": null, + "port": "", + "flash_bootloader": false, + "is_deferred_install": false, + "new_name": "", + "depends_on": "", + "dependency_released": false, + "progress": null, + "remote_peer": "", + "remote_job_id": "", + "remote_peer_label": "", + "device_name": "", + "device_friendly_name": "", + "source": "local", + "source_pin_sha256": "", + "source_label": "", + "source_esphome_version": "", + "target_esphome_version": "", + "failure_reason": "" + }, + { + "job_id": "ccc86cf9bcb3", + "configuration": "esp-loungesouthrightswitch.yaml", + "job_type": "upload", + "status": "completed", + "created_at": "2026-08-28T23:38:37.700053+00:00", + "started_at": "2026-08-28T23:54:35.628994+00:00", + "completed_at": "2026-08-28T23:54:46.853996+00:00", + "compile_started_at": null, + "compile_ended_at": null, + "exit_code": 0, + "error": null, + "port": "OTA", + "flash_bootloader": false, + "is_deferred_install": false, + "new_name": "", + "depends_on": "1ca3c133fbd8", + "dependency_released": true, + "progress": 100, + "remote_peer": "", + "remote_job_id": "", + "remote_peer_label": "", + "device_name": "", + "device_friendly_name": "", + "source": "local", + "source_pin_sha256": "", + "source_label": "", + "source_esphome_version": "", + "target_esphome_version": "", + "failure_reason": "" + }, + { + "job_id": "1ca3c133fbd8", + "configuration": "esp-loungesouthrightswitch.yaml", + "job_type": "compile", + "status": "completed", + "created_at": "2026-08-28T23:38:37.700014+00:00", + "started_at": "2026-08-28T23:52:48.667228+00:00", + "completed_at": "2026-08-28T23:54:35.626629+00:00", + "compile_started_at": "2026-08-28T23:52:55.940782+00:00", + "compile_ended_at": "2026-08-28T23:54:34.114167+00:00", + "exit_code": 0, + "error": null, + "port": "", + "flash_bootloader": false, + "is_deferred_install": false, + "new_name": "", + "depends_on": "", + "dependency_released": false, + "progress": null, + "remote_peer": "", + "remote_job_id": "", + "remote_peer_label": "", + "device_name": "", + "device_friendly_name": "", + "source": "local", + "source_pin_sha256": "", + "source_label": "", + "source_esphome_version": "", + "target_esphome_version": "", + "failure_reason": "" + }, + { + "job_id": "56d0e43a97dd", + "configuration": "esp-loungesouthleftswitch.yaml", + "job_type": "upload", + "status": "completed", + "created_at": "2026-08-28T23:38:34.966795+00:00", + "started_at": "2026-08-28T23:55:15.391775+00:00", + "completed_at": "2026-08-28T23:55:26.624775+00:00", + "compile_started_at": null, + "compile_ended_at": null, + "exit_code": 0, + "error": null, + "port": "OTA", + "flash_bootloader": false, + "is_deferred_install": false, + "new_name": "", + "depends_on": "ef88a10b01dc", + "dependency_released": true, + "progress": 100, + "remote_peer": "", + "remote_job_id": "", + "remote_peer_label": "", + "device_name": "", + "device_friendly_name": "", + "source": "local", + "source_pin_sha256": "", + "source_label": "", + "source_esphome_version": "", + "target_esphome_version": "", + "failure_reason": "" + }, + { + "job_id": "ef88a10b01dc", + "configuration": "esp-loungesouthleftswitch.yaml", + "job_type": "compile", + "status": "completed", + "created_at": "2026-08-28T23:38:34.966758+00:00", + "started_at": "2026-08-28T23:51:31.847405+00:00", + "completed_at": "2026-08-28T23:55:15.382100+00:00", + "compile_started_at": "2026-08-28T23:51:41.265209+00:00", + "compile_ended_at": "2026-08-28T23:55:11.855366+00:00", + "exit_code": 0, + "error": null, + "port": "", + "flash_bootloader": false, + "is_deferred_install": false, + "new_name": "", + "depends_on": "", + "dependency_released": false, + "progress": null, + "remote_peer": "", + "remote_job_id": "", + "remote_peer_label": "", + "device_name": "", + "device_friendly_name": "", + "source": "remote", + "source_pin_sha256": "11faf1169a008873b779b7223309fd7d8def200d1548f7b62955f71a67796a12", + "source_label": "Panda ESPHome Builder", + "source_esphome_version": "2026.7.2", + "target_esphome_version": "", + "failure_reason": "" + }, + { + "job_id": "575d4ca5b5e4", + "configuration": "esp-nspanel2lounge.yaml", + "job_type": "upload", + "status": "completed", + "created_at": "2026-08-28T23:38:30.384640+00:00", + "started_at": "2026-08-28T23:52:48.646951+00:00", + "completed_at": "2026-08-28T23:53:04.480454+00:00", + "compile_started_at": null, + "compile_ended_at": null, + "exit_code": 0, + "error": null, + "port": "OTA", + "flash_bootloader": false, + "is_deferred_install": false, + "new_name": "", + "depends_on": "dc47295ddd35", + "dependency_released": true, + "progress": 100, + "remote_peer": "", + "remote_job_id": "", + "remote_peer_label": "", + "device_name": "", + "device_friendly_name": "", + "source": "local", + "source_pin_sha256": "", + "source_label": "", + "source_esphome_version": "", + "target_esphome_version": "", + "failure_reason": "" + }, + { + "job_id": "dc47295ddd35", + "configuration": "esp-nspanel2lounge.yaml", + "job_type": "compile", + "status": "completed", + "created_at": "2026-08-28T23:38:30.384601+00:00", + "started_at": "2026-08-28T23:50:57.474684+00:00", + "completed_at": "2026-08-28T23:52:48.644803+00:00", + "compile_started_at": "2026-08-28T23:51:04.998470+00:00", + "compile_ended_at": "2026-08-28T23:52:48.201687+00:00", + "exit_code": 0, + "error": null, + "port": "", + "flash_bootloader": false, + "is_deferred_install": false, + "new_name": "", + "depends_on": "", + "dependency_released": false, + "progress": 38, + "remote_peer": "", + "remote_job_id": "", + "remote_peer_label": "", + "device_name": "", + "device_friendly_name": "", + "source": "local", + "source_pin_sha256": "", + "source_label": "", + "source_esphome_version": "", + "target_esphome_version": "", + "failure_reason": "" + }, + { + "job_id": "b728bc441ed2", + "configuration": "esp-laundrywashpow.yaml", + "job_type": "upload", + "status": "completed", + "created_at": "2026-08-28T23:38:22.230161+00:00", + "started_at": "2026-08-28T23:51:31.847201+00:00", + "completed_at": "2026-08-28T23:51:45.813118+00:00", + "compile_started_at": null, + "compile_ended_at": null, + "exit_code": 0, + "error": null, + "port": "OTA", + "flash_bootloader": false, + "is_deferred_install": false, + "new_name": "", + "depends_on": "9ed58651931a", + "dependency_released": true, + "progress": 100, + "remote_peer": "", + "remote_job_id": "", + "remote_peer_label": "", + "device_name": "", + "device_friendly_name": "", + "source": "local", + "source_pin_sha256": "", + "source_label": "", + "source_esphome_version": "", + "target_esphome_version": "", + "failure_reason": "" + }, + { + "job_id": "9ed58651931a", + "configuration": "esp-laundrywashpow.yaml", + "job_type": "compile", + "status": "completed", + "created_at": "2026-08-28T23:38:22.230118+00:00", + "started_at": "2026-08-28T23:43:09.071272+00:00", + "completed_at": "2026-08-28T23:51:31.841576+00:00", + "compile_started_at": "2026-08-28T23:43:18.202806+00:00", + "compile_ended_at": "2026-08-28T23:51:28.258791+00:00", + "exit_code": 0, + "error": null, + "port": "", + "flash_bootloader": false, + "is_deferred_install": false, + "new_name": "", + "depends_on": "", + "dependency_released": false, + "progress": null, + "remote_peer": "", + "remote_job_id": "", + "remote_peer_label": "", + "device_name": "", + "device_friendly_name": "", + "source": "remote", + "source_pin_sha256": "11faf1169a008873b779b7223309fd7d8def200d1548f7b62955f71a67796a12", + "source_label": "Panda ESPHome Builder", + "source_esphome_version": "2026.7.2", + "target_esphome_version": "", + "failure_reason": "" + }, + { + "job_id": "b66b75149a6b", + "configuration": "esp-laundrylights.yaml", + "job_type": "upload", + "status": "completed", + "created_at": "2026-08-28T23:38:17.915819+00:00", + "started_at": "2026-08-28T23:43:09.071087+00:00", + "completed_at": "2026-08-28T23:43:19.784014+00:00", + "compile_started_at": null, + "compile_ended_at": null, + "exit_code": 0, + "error": null, + "port": "OTA", + "flash_bootloader": false, + "is_deferred_install": false, + "new_name": "", + "depends_on": "f97a8a77e442", + "dependency_released": true, + "progress": 100, + "remote_peer": "", + "remote_job_id": "", + "remote_peer_label": "", + "device_name": "", + "device_friendly_name": "", + "source": "local", + "source_pin_sha256": "", + "source_label": "", + "source_esphome_version": "", + "target_esphome_version": "", + "failure_reason": "" + }, + { + "job_id": "f97a8a77e442", + "configuration": "esp-laundrylights.yaml", + "job_type": "compile", + "status": "completed", + "created_at": "2026-08-28T23:38:17.915779+00:00", + "started_at": "2026-08-28T23:38:17.918801+00:00", + "completed_at": "2026-08-28T23:43:09.067161+00:00", + "compile_started_at": "2026-08-28T23:38:38.604986+00:00", + "compile_ended_at": "2026-08-28T23:42:58.227411+00:00", + "exit_code": 0, + "error": null, + "port": "", + "flash_bootloader": false, + "is_deferred_install": false, + "new_name": "", + "depends_on": "", + "dependency_released": false, + "progress": null, + "remote_peer": "", + "remote_job_id": "", + "remote_peer_label": "", + "device_name": "", + "device_friendly_name": "", + "source": "remote", + "source_pin_sha256": "11faf1169a008873b779b7223309fd7d8def200d1548f7b62955f71a67796a12", + "source_label": "Panda ESPHome Builder", + "source_esphome_version": "2026.7.2", + "target_esphome_version": "", + "failure_reason": "" + }, + { + "job_id": "418061db5a48", + "configuration": "esp-laundryenv.yaml", + "job_type": "upload", + "status": "completed", + "created_at": "2026-08-28T23:38:11.905329+00:00", + "started_at": "2026-08-28T23:50:57.464088+00:00", + "completed_at": "2026-08-28T23:51:07.792887+00:00", + "compile_started_at": null, + "compile_ended_at": null, + "exit_code": 0, + "error": null, + "port": "OTA", + "flash_bootloader": false, + "is_deferred_install": false, + "new_name": "", + "depends_on": "36c73d9e66c0", + "dependency_released": true, + "progress": 100, + "remote_peer": "", + "remote_job_id": "", + "remote_peer_label": "", + "device_name": "", + "device_friendly_name": "", + "source": "local", + "source_pin_sha256": "", + "source_label": "", + "source_esphome_version": "", + "target_esphome_version": "", + "failure_reason": "" + }, + { + "job_id": "36c73d9e66c0", + "configuration": "esp-laundryenv.yaml", + "job_type": "compile", + "status": "completed", + "created_at": "2026-08-28T23:38:11.905273+00:00", + "started_at": "2026-08-28T23:49:14.413665+00:00", + "completed_at": "2026-08-28T23:50:57.461561+00:00", + "compile_started_at": "2026-08-28T23:49:16.704764+00:00", + "compile_ended_at": "2026-08-28T23:50:55.865561+00:00", + "exit_code": 0, + "error": null, + "port": "", + "flash_bootloader": false, + "is_deferred_install": false, + "new_name": "", + "depends_on": "", + "dependency_released": false, + "progress": null, + "remote_peer": "", + "remote_job_id": "", + "remote_peer_label": "", + "device_name": "", + "device_friendly_name": "", + "source": "local", + "source_pin_sha256": "", + "source_label": "", + "source_esphome_version": "", + "target_esphome_version": "", + "failure_reason": "" + }, + { + "job_id": "7e3a6bfe646d", + "configuration": "esp-laundrydrypow.yaml", + "job_type": "upload", + "status": "completed", + "created_at": "2026-08-28T23:38:05.991416+00:00", + "started_at": "2026-08-28T23:49:14.385300+00:00", + "completed_at": "2026-08-28T23:49:26.877154+00:00", + "compile_started_at": null, + "compile_ended_at": null, + "exit_code": 0, + "error": null, + "port": "OTA", + "flash_bootloader": false, + "is_deferred_install": false, + "new_name": "", + "depends_on": "6cc16ff7aaba", + "dependency_released": true, + "progress": 100, + "remote_peer": "", + "remote_job_id": "", + "remote_peer_label": "", + "device_name": "", + "device_friendly_name": "", + "source": "local", + "source_pin_sha256": "", + "source_label": "", + "source_esphome_version": "", + "target_esphome_version": "", + "failure_reason": "" + }, + { + "job_id": "6cc16ff7aaba", + "configuration": "esp-laundrydrypow.yaml", + "job_type": "compile", + "status": "completed", + "created_at": "2026-08-28T23:38:05.991368+00:00", + "started_at": "2026-08-28T23:44:33.722593+00:00", + "completed_at": "2026-08-28T23:49:14.382924+00:00", + "compile_started_at": "2026-08-28T23:44:36.020003+00:00", + "compile_ended_at": "2026-08-28T23:49:12.767941+00:00", + "exit_code": 0, + "error": null, + "port": "", + "flash_bootloader": false, + "is_deferred_install": false, + "new_name": "", + "depends_on": "", + "dependency_released": false, + "progress": null, + "remote_peer": "", + "remote_job_id": "", + "remote_peer_label": "", + "device_name": "", + "device_friendly_name": "", + "source": "local", + "source_pin_sha256": "", + "source_label": "", + "source_esphome_version": "", + "target_esphome_version": "", + "failure_reason": "" + }, + { + "job_id": "cbe1d4633832", + "configuration": "esp-laundryplugpow.yaml", + "job_type": "upload", + "status": "completed", + "created_at": "2026-08-28T23:37:58.101098+00:00", + "started_at": "2026-08-28T23:44:33.643162+00:00", + "completed_at": "2026-08-28T23:44:43.372222+00:00", + "compile_started_at": null, + "compile_ended_at": null, + "exit_code": 0, + "error": null, + "port": "OTA", + "flash_bootloader": false, + "is_deferred_install": false, + "new_name": "", + "depends_on": "6ad6448142e7", + "dependency_released": true, + "progress": 100, + "remote_peer": "", + "remote_job_id": "", + "remote_peer_label": "", + "device_name": "", + "device_friendly_name": "", + "source": "local", + "source_pin_sha256": "", + "source_label": "", + "source_esphome_version": "", + "target_esphome_version": "", + "failure_reason": "" + }, + { + "job_id": "6ad6448142e7", + "configuration": "esp-laundryplugpow.yaml", + "job_type": "compile", + "status": "completed", + "created_at": "2026-08-28T23:37:58.101054+00:00", + "started_at": "2026-08-28T23:42:35.722638+00:00", + "completed_at": "2026-08-28T23:44:33.640342+00:00", + "compile_started_at": "2026-08-28T23:42:38.065609+00:00", + "compile_ended_at": "2026-08-28T23:44:32.087084+00:00", + "exit_code": 0, + "error": null, + "port": "", + "flash_bootloader": false, + "is_deferred_install": false, + "new_name": "", + "depends_on": "", + "dependency_released": false, + "progress": null, + "remote_peer": "", + "remote_job_id": "", + "remote_peer_label": "", + "device_name": "", + "device_friendly_name": "", + "source": "local", + "source_pin_sha256": "", + "source_label": "", + "source_esphome_version": "", + "target_esphome_version": "", + "failure_reason": "" + }, + { + "job_id": "47e7577de5c3", + "configuration": "esp-garagelights.yaml", + "job_type": "upload", + "status": "completed", + "created_at": "2026-08-28T23:37:51.552574+00:00", + "started_at": "2026-08-28T23:42:35.700119+00:00", + "completed_at": "2026-08-28T23:42:53.885638+00:00", + "compile_started_at": null, + "compile_ended_at": null, + "exit_code": 0, + "error": null, + "port": "OTA", + "flash_bootloader": false, + "is_deferred_install": false, + "new_name": "", + "depends_on": "6f3ed07eb5c9", + "dependency_released": true, + "progress": 100, + "remote_peer": "", + "remote_job_id": "", + "remote_peer_label": "", + "device_name": "", + "device_friendly_name": "", + "source": "local", + "source_pin_sha256": "", + "source_label": "", + "source_esphome_version": "", + "target_esphome_version": "", + "failure_reason": "" + }, + { + "job_id": "6f3ed07eb5c9", + "configuration": "esp-garagelights.yaml", + "job_type": "compile", + "status": "completed", + "created_at": "2026-08-28T23:37:51.552535+00:00", + "started_at": "2026-08-28T23:39:57.221769+00:00", + "completed_at": "2026-08-28T23:42:35.697715+00:00", + "compile_started_at": "2026-08-28T23:39:59.561658+00:00", + "compile_ended_at": "2026-08-28T23:42:34.110677+00:00", + "exit_code": 0, + "error": null, + "port": "", + "flash_bootloader": false, + "is_deferred_install": false, + "new_name": "", + "depends_on": "", + "dependency_released": false, + "progress": null, + "remote_peer": "", + "remote_job_id": "", + "remote_peer_label": "", + "device_name": "", + "device_friendly_name": "", + "source": "local", + "source_pin_sha256": "", + "source_label": "", + "source_esphome_version": "", + "target_esphome_version": "", + "failure_reason": "" + }, + { + "job_id": "768d093b5cfb", + "configuration": "esp-flysprayer1.yaml", + "job_type": "upload", + "status": "completed", + "created_at": "2026-08-28T23:37:44.848241+00:00", + "started_at": "2026-08-28T23:39:57.212335+00:00", + "completed_at": "2026-08-28T23:40:09.618508+00:00", + "compile_started_at": null, + "compile_ended_at": null, + "exit_code": 0, + "error": null, + "port": "OTA", + "flash_bootloader": false, + "is_deferred_install": false, + "new_name": "", + "depends_on": "279bedac3a7d", + "dependency_released": true, + "progress": 100, + "remote_peer": "", + "remote_job_id": "", + "remote_peer_label": "", + "device_name": "", + "device_friendly_name": "", + "source": "local", + "source_pin_sha256": "", + "source_label": "", + "source_esphome_version": "", + "target_esphome_version": "", + "failure_reason": "" + }, + { + "job_id": "279bedac3a7d", + "configuration": "esp-flysprayer1.yaml", + "job_type": "compile", + "status": "completed", + "created_at": "2026-08-28T23:37:44.848183+00:00", + "started_at": "2026-08-28T23:37:44.850725+00:00", + "completed_at": "2026-08-28T23:39:57.209712+00:00", + "compile_started_at": "2026-08-28T23:37:47.363658+00:00", + "compile_ended_at": "2026-08-28T23:39:55.592663+00:00", + "exit_code": 0, + "error": null, + "port": "", + "flash_bootloader": false, + "is_deferred_install": false, + "new_name": "", + "depends_on": "", + "dependency_released": false, + "progress": null, + "remote_peer": "", + "remote_job_id": "", + "remote_peer_label": "", + "device_name": "", + "device_friendly_name": "", + "source": "local", + "source_pin_sha256": "", + "source_label": "", + "source_esphome_version": "", + "target_esphome_version": "", + "failure_reason": "" + }, + { + "job_id": "403d5dd39b78", + "configuration": "esp-downstloungeentry.yaml", + "job_type": "upload", + "status": "completed", + "created_at": "2026-08-28T23:29:10.443806+00:00", + "started_at": "2026-08-28T23:35:55.083658+00:00", + "completed_at": "2026-08-28T23:36:05.113574+00:00", + "compile_started_at": null, + "compile_ended_at": null, + "exit_code": 0, + "error": null, + "port": "OTA", + "flash_bootloader": false, + "is_deferred_install": false, + "new_name": "", + "depends_on": "03f97aad5550", + "dependency_released": true, + "progress": 100, + "remote_peer": "", + "remote_job_id": "", + "remote_peer_label": "", + "device_name": "", + "device_friendly_name": "", + "source": "local", + "source_pin_sha256": "", + "source_label": "", + "source_esphome_version": "", + "target_esphome_version": "", + "failure_reason": "" + }, + { + "job_id": "03f97aad5550", + "configuration": "esp-downstloungeentry.yaml", + "job_type": "compile", + "status": "completed", + "created_at": "2026-08-28T23:29:10.443768+00:00", + "started_at": "2026-08-28T23:31:43.611753+00:00", + "completed_at": "2026-08-28T23:35:55.081713+00:00", + "compile_started_at": "2026-08-28T23:31:52.446592+00:00", + "compile_ended_at": "2026-08-28T23:35:51.231580+00:00", + "exit_code": 0, + "error": null, + "port": "", + "flash_bootloader": false, + "is_deferred_install": false, + "new_name": "", + "depends_on": "", + "dependency_released": false, + "progress": null, + "remote_peer": "", + "remote_job_id": "", + "remote_peer_label": "", + "device_name": "", + "device_friendly_name": "", + "source": "remote", + "source_pin_sha256": "11faf1169a008873b779b7223309fd7d8def200d1548f7b62955f71a67796a12", + "source_label": "Panda ESPHome Builder", + "source_esphome_version": "2026.7.2", + "target_esphome_version": "", + "failure_reason": "" + }, + { + "job_id": "5f0b2cfe7a7b", + "configuration": "esp-downstkitchlights.yaml", + "job_type": "upload", + "status": "completed", + "created_at": "2026-08-28T23:29:07.149599+00:00", + "started_at": "2026-08-28T23:31:43.611533+00:00", + "completed_at": "2026-08-28T23:31:56.190546+00:00", + "compile_started_at": null, + "compile_ended_at": null, + "exit_code": 0, + "error": null, + "port": "OTA", + "flash_bootloader": false, + "is_deferred_install": false, + "new_name": "", + "depends_on": "62712fa59bfa", + "dependency_released": true, + "progress": 100, + "remote_peer": "", + "remote_job_id": "", + "remote_peer_label": "", + "device_name": "", + "device_friendly_name": "", + "source": "local", + "source_pin_sha256": "", + "source_label": "", + "source_esphome_version": "", + "target_esphome_version": "", + "failure_reason": "" + }, + { + "job_id": "62712fa59bfa", + "configuration": "esp-downstkitchlights.yaml", + "job_type": "compile", + "status": "completed", + "created_at": "2026-08-28T23:29:07.149558+00:00", + "started_at": "2026-08-28T23:30:21.764410+00:00", + "completed_at": "2026-08-28T23:31:43.603528+00:00", + "compile_started_at": "2026-08-28T23:30:31.791339+00:00", + "compile_ended_at": "2026-08-28T23:31:39.497407+00:00", + "exit_code": 0, + "error": null, + "port": "", + "flash_bootloader": false, + "is_deferred_install": false, + "new_name": "", + "depends_on": "", + "dependency_released": false, + "progress": null, + "remote_peer": "", + "remote_job_id": "", + "remote_peer_label": "", + "device_name": "", + "device_friendly_name": "", + "source": "remote", + "source_pin_sha256": "11faf1169a008873b779b7223309fd7d8def200d1548f7b62955f71a67796a12", + "source_label": "Panda ESPHome Builder", + "source_esphome_version": "2026.7.2", + "target_esphome_version": "", + "failure_reason": "" + }, + { + "job_id": "99a3ee296c01", + "configuration": "esp-downstairsdishwasher.yaml", + "job_type": "upload", + "status": "completed", + "created_at": "2026-08-28T23:29:02.333274+00:00", + "started_at": "2026-08-28T23:30:21.764186+00:00", + "completed_at": "2026-08-28T23:30:33.216857+00:00", + "compile_started_at": null, + "compile_ended_at": null, + "exit_code": 0, + "error": null, + "port": "OTA", + "flash_bootloader": false, + "is_deferred_install": false, + "new_name": "", + "depends_on": "6078964a2589", + "dependency_released": true, + "progress": 100, + "remote_peer": "", + "remote_job_id": "", + "remote_peer_label": "", + "device_name": "", + "device_friendly_name": "", + "source": "local", + "source_pin_sha256": "", + "source_label": "", + "source_esphome_version": "", + "target_esphome_version": "", + "failure_reason": "" + }, + { + "job_id": "6078964a2589", + "configuration": "esp-downstairsdishwasher.yaml", + "job_type": "compile", + "status": "completed", + "created_at": "2026-08-28T23:29:02.333235+00:00", + "started_at": "2026-08-28T23:29:02.353029+00:00", + "completed_at": "2026-08-28T23:30:21.758521+00:00", + "compile_started_at": "2026-08-28T23:29:12.589702+00:00", + "compile_ended_at": "2026-08-28T23:30:18.207542+00:00", + "exit_code": 0, + "error": null, + "port": "", + "flash_bootloader": false, + "is_deferred_install": false, + "new_name": "", + "depends_on": "", + "dependency_released": false, + "progress": null, + "remote_peer": "", + "remote_job_id": "", + "remote_peer_label": "", + "device_name": "", + "device_friendly_name": "", + "source": "remote", + "source_pin_sha256": "11faf1169a008873b779b7223309fd7d8def200d1548f7b62955f71a67796a12", + "source_label": "Panda ESPHome Builder", + "source_esphome_version": "2026.7.2", + "target_esphome_version": "", + "failure_reason": "" + }, + { + "job_id": "26ee70416784", + "configuration": "esp-downstbedrm2lights.yaml", + "job_type": "upload", + "status": "completed", + "created_at": "2026-08-28T23:28:58.573084+00:00", + "started_at": "2026-08-28T23:34:09.626269+00:00", + "completed_at": "2026-08-28T23:34:18.469513+00:00", + "compile_started_at": null, + "compile_ended_at": null, + "exit_code": 0, + "error": null, + "port": "OTA", + "flash_bootloader": false, + "is_deferred_install": false, + "new_name": "", + "depends_on": "0d4aba1a566b", + "dependency_released": true, + "progress": 100, + "remote_peer": "", + "remote_job_id": "", + "remote_peer_label": "", + "device_name": "", + "device_friendly_name": "", + "source": "local", + "source_pin_sha256": "", + "source_label": "", + "source_esphome_version": "", + "target_esphome_version": "", + "failure_reason": "" + }, + { + "job_id": "0d4aba1a566b", + "configuration": "esp-downstbedrm2lights.yaml", + "job_type": "compile", + "status": "completed", + "created_at": "2026-08-28T23:28:58.573048+00:00", + "started_at": "2026-08-28T23:32:24.994255+00:00", + "completed_at": "2026-08-28T23:34:09.624410+00:00", + "compile_started_at": "2026-08-28T23:32:27.477712+00:00", + "compile_ended_at": "2026-08-28T23:34:08.022426+00:00", + "exit_code": 0, + "error": null, + "port": "", + "flash_bootloader": false, + "is_deferred_install": false, + "new_name": "", + "depends_on": "", + "dependency_released": false, + "progress": null, + "remote_peer": "", + "remote_job_id": "", + "remote_peer_label": "", + "device_name": "", + "device_friendly_name": "", + "source": "local", + "source_pin_sha256": "", + "source_label": "", + "source_esphome_version": "", + "target_esphome_version": "", + "failure_reason": "" + }, + { + "job_id": "0a1ce75abbdf", + "configuration": "esp-downstbathswitch.yaml", + "job_type": "upload", + "status": "completed", + "created_at": "2026-08-28T23:28:50.752680+00:00", + "started_at": "2026-08-28T23:32:24.985010+00:00", + "completed_at": "2026-08-28T23:32:34.710352+00:00", + "compile_started_at": null, + "compile_ended_at": null, + "exit_code": 0, + "error": null, + "port": "OTA", + "flash_bootloader": false, + "is_deferred_install": false, + "new_name": "", + "depends_on": "394db5df063f", + "dependency_released": true, + "progress": 100, + "remote_peer": "", + "remote_job_id": "", + "remote_peer_label": "", + "device_name": "", + "device_friendly_name": "", + "source": "local", + "source_pin_sha256": "", + "source_label": "", + "source_esphome_version": "", + "target_esphome_version": "", + "failure_reason": "" + }, + { + "job_id": "394db5df063f", + "configuration": "esp-downstbathswitch.yaml", + "job_type": "compile", + "status": "completed", + "created_at": "2026-08-28T23:28:50.752635+00:00", + "started_at": "2026-08-28T23:30:35.849909+00:00", + "completed_at": "2026-08-28T23:32:24.982750+00:00", + "compile_started_at": "2026-08-28T23:30:38.391707+00:00", + "compile_ended_at": "2026-08-28T23:32:23.404349+00:00", + "exit_code": 0, + "error": null, + "port": "", + "flash_bootloader": false, + "is_deferred_install": false, + "new_name": "", + "depends_on": "", + "dependency_released": false, + "progress": null, + "remote_peer": "", + "remote_job_id": "", + "remote_peer_label": "", + "device_name": "", + "device_friendly_name": "", + "source": "local", + "source_pin_sha256": "", + "source_label": "", + "source_esphome_version": "", + "target_esphome_version": "", + "failure_reason": "" + }, + { + "job_id": "dfa3d82ef8f1", + "configuration": "esp-datacupboardpower-right.yaml", + "job_type": "upload", + "status": "completed", + "created_at": "2026-08-28T23:28:46.268665+00:00", + "started_at": "2026-08-28T23:30:35.819745+00:00", + "completed_at": "2026-08-28T23:30:45.031129+00:00", + "compile_started_at": null, + "compile_ended_at": null, + "exit_code": 0, + "error": null, + "port": "OTA", + "flash_bootloader": false, + "is_deferred_install": false, + "new_name": "", + "depends_on": "e7b8aa487fbb", + "dependency_released": true, + "progress": 100, + "remote_peer": "", + "remote_job_id": "", + "remote_peer_label": "", + "device_name": "", + "device_friendly_name": "", + "source": "local", + "source_pin_sha256": "", + "source_label": "", + "source_esphome_version": "", + "target_esphome_version": "", + "failure_reason": "" + }, + { + "job_id": "e7b8aa487fbb", + "configuration": "esp-datacupboardpower-right.yaml", + "job_type": "compile", + "status": "completed", + "created_at": "2026-08-28T23:28:46.268625+00:00", + "started_at": "2026-08-28T23:28:46.269787+00:00", + "completed_at": "2026-08-28T23:30:35.817493+00:00", + "compile_started_at": "2026-08-28T23:28:49.429645+00:00", + "compile_ended_at": "2026-08-28T23:30:34.221600+00:00", + "exit_code": 0, + "error": null, + "port": "", + "flash_bootloader": false, + "is_deferred_install": false, + "new_name": "", + "depends_on": "", + "dependency_released": false, + "progress": null, + "remote_peer": "", + "remote_job_id": "", + "remote_peer_label": "", + "device_name": "", + "device_friendly_name": "", + "source": "local", + "source_pin_sha256": "", + "source_label": "", + "source_esphome_version": "", + "target_esphome_version": "", + "failure_reason": "" + }, + { + "job_id": "55e44bd0d28f", + "configuration": "esp-datacupboardpower-left.yaml", + "job_type": "upload", + "status": "completed", + "created_at": "2026-08-28T22:38:24.561117+00:00", + "started_at": "2026-08-28T22:57:44.435848+00:00", + "completed_at": "2026-08-28T22:57:51.604813+00:00", + "compile_started_at": null, + "compile_ended_at": null, + "exit_code": 0, + "error": null, + "port": "OTA", + "flash_bootloader": false, + "is_deferred_install": false, + "new_name": "", + "depends_on": "111626be2f5e", + "dependency_released": true, + "progress": 100, + "remote_peer": "", + "remote_job_id": "", + "remote_peer_label": "", + "device_name": "", + "device_friendly_name": "", + "source": "local", + "source_pin_sha256": "", + "source_label": "", + "source_esphome_version": "", + "target_esphome_version": "", + "failure_reason": "" + }, + { + "job_id": "111626be2f5e", + "configuration": "esp-datacupboardpower-left.yaml", + "job_type": "compile", + "status": "completed", + "created_at": "2026-08-28T22:38:24.561079+00:00", + "started_at": "2026-08-28T22:55:02.592056+00:00", + "completed_at": "2026-08-28T22:57:44.433414+00:00", + "compile_started_at": "2026-08-28T22:55:06.845044+00:00", + "compile_ended_at": "2026-08-28T22:57:42.865485+00:00", + "exit_code": 0, + "error": null, + "port": "", + "flash_bootloader": false, + "is_deferred_install": false, + "new_name": "", + "depends_on": "", + "dependency_released": false, + "progress": null, + "remote_peer": "", + "remote_job_id": "", + "remote_peer_label": "", + "device_name": "", + "device_friendly_name": "", + "source": "local", + "source_pin_sha256": "", + "source_label": "", + "source_esphome_version": "", + "target_esphome_version": "", + "failure_reason": "" + }, + { + "job_id": "e556ba5cd1fd", + "configuration": "esp-datacupboardfans.yaml", + "job_type": "upload", + "status": "completed", + "created_at": "2026-08-28T22:38:20.431519+00:00", + "started_at": "2026-08-28T22:55:02.582061+00:00", + "completed_at": "2026-08-28T22:55:09.550787+00:00", + "compile_started_at": null, + "compile_ended_at": null, + "exit_code": 0, + "error": null, + "port": "OTA", + "flash_bootloader": false, + "is_deferred_install": false, + "new_name": "", + "depends_on": "f4a1bb3c1648", + "dependency_released": true, + "progress": 100, + "remote_peer": "", + "remote_job_id": "", + "remote_peer_label": "", + "device_name": "", + "device_friendly_name": "", + "source": "local", + "source_pin_sha256": "", + "source_label": "", + "source_esphome_version": "", + "target_esphome_version": "", + "failure_reason": "" + }, + { + "job_id": "f4a1bb3c1648", + "configuration": "esp-datacupboardfans.yaml", + "job_type": "compile", + "status": "completed", + "created_at": "2026-08-28T22:38:20.431479+00:00", + "started_at": "2026-08-28T22:52:17.830169+00:00", + "completed_at": "2026-08-28T22:55:02.579489+00:00", + "compile_started_at": "2026-08-28T22:52:20.553740+00:00", + "compile_ended_at": "2026-08-28T22:55:00.969041+00:00", + "exit_code": 0, + "error": null, + "port": "", + "flash_bootloader": false, + "is_deferred_install": false, + "new_name": "", + "depends_on": "", + "dependency_released": false, + "progress": null, + "remote_peer": "", + "remote_job_id": "", + "remote_peer_label": "", + "device_name": "", + "device_friendly_name": "", + "source": "local", + "source_pin_sha256": "", + "source_label": "", + "source_esphome_version": "", + "target_esphome_version": "", + "failure_reason": "" + }, + { + "job_id": "2205eb5a5c50", + "configuration": "esp-centralstairs-top.yaml", + "job_type": "upload", + "status": "completed", + "created_at": "2026-08-28T22:38:14.919756+00:00", + "started_at": "2026-08-28T22:55:17.818414+00:00", + "completed_at": "2026-08-28T22:55:39.925740+00:00", + "compile_started_at": null, + "compile_ended_at": null, + "exit_code": 0, + "error": null, + "port": "OTA", + "flash_bootloader": false, + "is_deferred_install": false, + "new_name": "", + "depends_on": "69dba8560c1f", + "dependency_released": true, + "progress": 100, + "remote_peer": "", + "remote_job_id": "", + "remote_peer_label": "", + "device_name": "", + "device_friendly_name": "", + "source": "local", + "source_pin_sha256": "", + "source_label": "", + "source_esphome_version": "", + "target_esphome_version": "", + "failure_reason": "" + }, + { + "job_id": "69dba8560c1f", + "configuration": "esp-centralstairs-top.yaml", + "job_type": "compile", + "status": "completed", + "created_at": "2026-08-28T22:38:14.919718+00:00", + "started_at": "2026-08-28T22:51:15.721508+00:00", + "completed_at": "2026-08-28T22:55:17.816818+00:00", + "compile_started_at": "2026-08-28T22:51:26.237353+00:00", + "compile_ended_at": "2026-08-28T22:55:14.435179+00:00", + "exit_code": 0, + "error": null, + "port": "", + "flash_bootloader": false, + "is_deferred_install": false, + "new_name": "", + "depends_on": "", + "dependency_released": false, + "progress": null, + "remote_peer": "", + "remote_job_id": "", + "remote_peer_label": "", + "device_name": "", + "device_friendly_name": "", + "source": "remote", + "source_pin_sha256": "11faf1169a008873b779b7223309fd7d8def200d1548f7b62955f71a67796a12", + "source_label": "Panda ESPHome Builder", + "source_esphome_version": "2026.7.2", + "target_esphome_version": "", + "failure_reason": "" + }, + { + "job_id": "84a3ad4bdc0a", + "configuration": "esp-centralstairs-bottom.yaml", + "job_type": "upload", + "status": "completed", + "created_at": "2026-08-28T22:38:11.925580+00:00", + "started_at": "2026-08-28T22:52:17.814396+00:00", + "completed_at": "2026-08-28T22:52:25.165177+00:00", + "compile_started_at": null, + "compile_ended_at": null, + "exit_code": 0, + "error": null, + "port": "OTA", + "flash_bootloader": false, + "is_deferred_install": false, + "new_name": "", + "depends_on": "1912ad318614", + "dependency_released": true, + "progress": 100, + "remote_peer": "", + "remote_job_id": "", + "remote_peer_label": "", + "device_name": "", + "device_friendly_name": "", + "source": "local", + "source_pin_sha256": "", + "source_label": "", + "source_esphome_version": "", + "target_esphome_version": "", + "failure_reason": "" + }, + { + "job_id": "1912ad318614", + "configuration": "esp-centralstairs-bottom.yaml", + "job_type": "compile", + "status": "completed", + "created_at": "2026-08-28T22:38:11.925543+00:00", + "started_at": "2026-08-28T22:50:30.431123+00:00", + "completed_at": "2026-08-28T22:52:17.812768+00:00", + "compile_started_at": "2026-08-28T22:50:33.004266+00:00", + "compile_ended_at": "2026-08-28T22:52:16.246053+00:00", + "exit_code": 0, + "error": null, + "port": "", + "flash_bootloader": false, + "is_deferred_install": false, + "new_name": "", + "depends_on": "", + "dependency_released": false, + "progress": null, + "remote_peer": "", + "remote_job_id": "", + "remote_peer_label": "", + "device_name": "", + "device_friendly_name": "", + "source": "local", + "source_pin_sha256": "", + "source_label": "", + "source_esphome_version": "", + "target_esphome_version": "", + "failure_reason": "" + }, + { + "job_id": "a7169fe004db", + "configuration": "esp-bedrm2fanswitch.yaml", + "job_type": "upload", + "status": "completed", + "created_at": "2026-08-28T22:37:49.860439+00:00", + "started_at": "2026-08-28T22:50:30.413687+00:00", + "completed_at": "2026-08-28T22:50:41.685019+00:00", + "compile_started_at": null, + "compile_ended_at": null, + "exit_code": 0, + "error": null, + "port": "OTA", + "flash_bootloader": false, + "is_deferred_install": false, + "new_name": "", + "depends_on": "15e4df02b05a", + "dependency_released": true, + "progress": 100, + "remote_peer": "", + "remote_job_id": "", + "remote_peer_label": "", + "device_name": "", + "device_friendly_name": "", + "source": "local", + "source_pin_sha256": "", + "source_label": "", + "source_esphome_version": "", + "target_esphome_version": "", + "failure_reason": "" + }, + { + "job_id": "15e4df02b05a", + "configuration": "esp-bedrm2fanswitch.yaml", + "job_type": "compile", + "status": "completed", + "created_at": "2026-08-28T22:37:49.860402+00:00", + "started_at": "2026-08-28T22:48:47.642079+00:00", + "completed_at": "2026-08-28T22:50:30.411941+00:00", + "compile_started_at": "2026-08-28T22:48:50.254347+00:00", + "compile_ended_at": "2026-08-28T22:50:28.907753+00:00", + "exit_code": 0, + "error": null, + "port": "", + "flash_bootloader": false, + "is_deferred_install": false, + "new_name": "", + "depends_on": "", + "dependency_released": false, + "progress": null, + "remote_peer": "", + "remote_job_id": "", + "remote_peer_label": "", + "device_name": "", + "device_friendly_name": "", + "source": "local", + "source_pin_sha256": "", + "source_label": "", + "source_esphome_version": "", + "target_esphome_version": "", + "failure_reason": "" + }, + { + "job_id": "7988b9705aaa", + "configuration": "esp-bedrm2lights.yaml", + "job_type": "upload", + "status": "completed", + "created_at": "2026-08-28T22:37:45.433782+00:00", + "started_at": "2026-08-28T22:48:47.622651+00:00", + "completed_at": "2026-08-28T22:48:59.097977+00:00", + "compile_started_at": null, + "compile_ended_at": null, + "exit_code": 0, + "error": null, + "port": "OTA", + "flash_bootloader": false, + "is_deferred_install": false, + "new_name": "", + "depends_on": "14bea85319f0", + "dependency_released": true, + "progress": 100, + "remote_peer": "", + "remote_job_id": "", + "remote_peer_label": "", + "device_name": "", + "device_friendly_name": "", + "source": "local", + "source_pin_sha256": "", + "source_label": "", + "source_esphome_version": "", + "target_esphome_version": "", + "failure_reason": "" + }, + { + "job_id": "14bea85319f0", + "configuration": "esp-bedrm2lights.yaml", + "job_type": "compile", + "status": "completed", + "created_at": "2026-08-28T22:37:45.433745+00:00", + "started_at": "2026-08-28T22:47:02.488786+00:00", + "completed_at": "2026-08-28T22:48:47.620270+00:00", + "compile_started_at": "2026-08-28T22:47:05.038011+00:00", + "compile_ended_at": "2026-08-28T22:48:46.140733+00:00", + "exit_code": 0, + "error": null, + "port": "", + "flash_bootloader": false, + "is_deferred_install": false, + "new_name": "", + "depends_on": "", + "dependency_released": false, + "progress": null, + "remote_peer": "", + "remote_job_id": "", + "remote_peer_label": "", + "device_name": "", + "device_friendly_name": "", + "source": "local", + "source_pin_sha256": "", + "source_label": "", + "source_esphome_version": "", + "target_esphome_version": "", + "failure_reason": "" + }, + { + "job_id": "99db2cf0179e", + "configuration": "esp-bedrm3fanswitch.yaml", + "job_type": "upload", + "status": "completed", + "created_at": "2026-08-28T22:37:38.830523+00:00", + "started_at": "2026-08-28T22:51:15.721309+00:00", + "completed_at": "2026-08-28T22:51:41.269887+00:00", + "compile_started_at": null, + "compile_ended_at": null, + "exit_code": 0, + "error": null, + "port": "OTA", + "flash_bootloader": false, + "is_deferred_install": false, + "new_name": "", + "depends_on": "a1973d37b37f", + "dependency_released": true, + "progress": 100, + "remote_peer": "", + "remote_job_id": "", + "remote_peer_label": "", + "device_name": "", + "device_friendly_name": "", + "source": "local", + "source_pin_sha256": "", + "source_label": "", + "source_esphome_version": "", + "target_esphome_version": "", + "failure_reason": "" + }, + { + "job_id": "a1973d37b37f", + "configuration": "esp-bedrm3fanswitch.yaml", + "job_type": "compile", + "status": "completed", + "created_at": "2026-08-28T22:37:38.830486+00:00", + "started_at": "2026-08-28T22:45:12.247787+00:00", + "completed_at": "2026-08-28T22:51:15.718498+00:00", + "compile_started_at": "2026-08-28T22:45:20.568070+00:00", + "compile_ended_at": "2026-08-28T22:51:12.248547+00:00", + "exit_code": 0, + "error": null, + "port": "", + "flash_bootloader": false, + "is_deferred_install": false, + "new_name": "", + "depends_on": "", + "dependency_released": false, + "progress": null, + "remote_peer": "", + "remote_job_id": "", + "remote_peer_label": "", + "device_name": "", + "device_friendly_name": "", + "source": "remote", + "source_pin_sha256": "11faf1169a008873b779b7223309fd7d8def200d1548f7b62955f71a67796a12", + "source_label": "Panda ESPHome Builder", + "source_esphome_version": "2026.7.2", + "target_esphome_version": "", + "failure_reason": "" + }, + { + "job_id": "206414cefaa0", + "configuration": "esp-bedrm1airfilter.yaml", + "job_type": "upload", + "status": "completed", + "created_at": "2026-08-28T22:37:23.488719+00:00", + "started_at": "2026-08-28T22:45:12.247603+00:00", + "completed_at": "2026-08-28T22:45:20.920864+00:00", + "compile_started_at": null, + "compile_ended_at": null, + "exit_code": 0, + "error": null, + "port": "OTA", + "flash_bootloader": false, + "is_deferred_install": false, + "new_name": "", + "depends_on": "42faa3d28e53", + "dependency_released": true, + "progress": 100, + "remote_peer": "", + "remote_job_id": "", + "remote_peer_label": "", + "device_name": "", + "device_friendly_name": "", + "source": "local", + "source_pin_sha256": "", + "source_label": "", + "source_esphome_version": "", + "target_esphome_version": "", + "failure_reason": "" + }, + { + "job_id": "42faa3d28e53", + "configuration": "esp-bedrm1airfilter.yaml", + "job_type": "compile", + "status": "completed", + "created_at": "2026-08-28T22:37:23.488680+00:00", + "started_at": "2026-08-28T22:43:57.788779+00:00", + "completed_at": "2026-08-28T22:45:12.245889+00:00", + "compile_started_at": "2026-08-28T22:44:05.931059+00:00", + "compile_ended_at": "2026-08-28T22:45:08.889755+00:00", + "exit_code": 0, + "error": null, + "port": "", + "flash_bootloader": false, + "is_deferred_install": false, + "new_name": "", + "depends_on": "", + "dependency_released": false, + "progress": null, + "remote_peer": "", + "remote_job_id": "", + "remote_peer_label": "", + "device_name": "", + "device_friendly_name": "", + "source": "remote", + "source_pin_sha256": "11faf1169a008873b779b7223309fd7d8def200d1548f7b62955f71a67796a12", + "source_label": "Panda ESPHome Builder", + "source_esphome_version": "2026.7.2", + "target_esphome_version": "", + "failure_reason": "" + }, + { + "job_id": "fa81bded85a4", + "configuration": "esp-3dprinterpow.yaml", + "job_type": "upload", + "status": "completed", + "created_at": "2026-08-28T22:37:15.746570+00:00", + "started_at": "2026-08-28T22:47:02.482724+00:00", + "completed_at": "2026-08-28T22:47:16.228012+00:00", + "compile_started_at": null, + "compile_ended_at": null, + "exit_code": 0, + "error": null, + "port": "OTA", + "flash_bootloader": false, + "is_deferred_install": false, + "new_name": "", + "depends_on": "fa281d7e8ea8", + "dependency_released": true, + "progress": 100, + "remote_peer": "", + "remote_job_id": "", + "remote_peer_label": "", + "device_name": "", + "device_friendly_name": "", + "source": "local", + "source_pin_sha256": "", + "source_label": "", + "source_esphome_version": "", + "target_esphome_version": "", + "failure_reason": "" + }, + { + "job_id": "fa281d7e8ea8", + "configuration": "esp-3dprinterpow.yaml", + "job_type": "compile", + "status": "completed", + "created_at": "2026-08-28T22:37:15.746532+00:00", + "started_at": "2026-08-28T22:39:25.205173+00:00", + "completed_at": "2026-08-28T22:47:02.478065+00:00", + "compile_started_at": "2026-08-28T22:39:32.153528+00:00", + "compile_ended_at": "2026-08-28T22:47:00.845099+00:00", + "exit_code": 0, + "error": null, + "port": "", + "flash_bootloader": false, + "is_deferred_install": false, + "new_name": "", + "depends_on": "", + "dependency_released": false, + "progress": null, + "remote_peer": "", + "remote_job_id": "", + "remote_peer_label": "", + "device_name": "", + "device_friendly_name": "", + "source": "local", + "source_pin_sha256": "", + "source_label": "", + "source_esphome_version": "", + "target_esphome_version": "", + "failure_reason": "" + }, + { + "job_id": "c2570954fa79", + "configuration": "esp-lounge6chdimmer.yaml", + "job_type": "upload", + "status": "completed", + "created_at": "2026-08-28T22:37:10.295884+00:00", + "started_at": "2026-08-28T22:43:57.788565+00:00", + "completed_at": "2026-08-28T22:44:05.768266+00:00", + "compile_started_at": null, + "compile_ended_at": null, + "exit_code": 0, + "error": null, + "port": "OTA", + "flash_bootloader": false, + "is_deferred_install": false, + "new_name": "", + "depends_on": "e01dc19e7e73", + "dependency_released": true, + "progress": 100, + "remote_peer": "", + "remote_job_id": "", + "remote_peer_label": "", + "device_name": "", + "device_friendly_name": "", + "source": "local", + "source_pin_sha256": "", + "source_label": "", + "source_esphome_version": "", + "target_esphome_version": "", + "failure_reason": "" + }, + { + "job_id": "e01dc19e7e73", + "configuration": "esp-lounge6chdimmer.yaml", + "job_type": "compile", + "status": "completed", + "created_at": "2026-08-28T22:37:10.295845+00:00", + "started_at": "2026-08-28T22:37:10.296545+00:00", + "completed_at": "2026-08-28T22:43:57.780896+00:00", + "compile_started_at": "2026-08-28T22:37:36.386442+00:00", + "compile_ended_at": "2026-08-28T22:43:53.976088+00:00", + "exit_code": 0, + "error": null, + "port": "", + "flash_bootloader": false, + "is_deferred_install": false, + "new_name": "", + "depends_on": "", + "dependency_released": false, + "progress": null, + "remote_peer": "", + "remote_job_id": "", + "remote_peer_label": "", + "device_name": "", + "device_friendly_name": "", + "source": "remote", + "source_pin_sha256": "11faf1169a008873b779b7223309fd7d8def200d1548f7b62955f71a67796a12", + "source_label": "Panda ESPHome Builder", + "source_esphome_version": "2026.7.2", + "target_esphome_version": "", + "failure_reason": "" + }, + { + "job_id": "2f73254d89ba", + "configuration": "esp-occupancyoffice.yaml", + "job_type": "upload", + "status": "completed", + "created_at": "2026-08-28T22:36:21.344008+00:00", + "started_at": "2026-08-28T22:39:25.196425+00:00", + "completed_at": "2026-08-28T22:39:39.895776+00:00", + "compile_started_at": null, + "compile_ended_at": null, + "exit_code": 0, + "error": null, + "port": "OTA", + "flash_bootloader": false, + "is_deferred_install": false, + "new_name": "", + "depends_on": "166ab276cf5c", + "dependency_released": true, + "progress": 100, + "remote_peer": "", + "remote_job_id": "", + "remote_peer_label": "", + "device_name": "", + "device_friendly_name": "", + "source": "local", + "source_pin_sha256": "", + "source_label": "", + "source_esphome_version": "", + "target_esphome_version": "", + "failure_reason": "" + }, + { + "job_id": "166ab276cf5c", + "configuration": "esp-occupancyoffice.yaml", + "job_type": "compile", + "status": "completed", + "created_at": "2026-08-28T22:36:21.343950+00:00", + "started_at": "2026-08-28T22:36:21.346327+00:00", + "completed_at": "2026-08-28T22:39:25.193718+00:00", + "compile_started_at": "2026-08-28T22:36:40.640515+00:00", + "compile_ended_at": "2026-08-28T22:39:24.984005+00:00", + "exit_code": 0, + "error": null, + "port": "", + "flash_bootloader": false, + "is_deferred_install": false, + "new_name": "", + "depends_on": "", + "dependency_released": false, + "progress": 99, + "remote_peer": "", + "remote_job_id": "", + "remote_peer_label": "", + "device_name": "", + "device_friendly_name": "", + "source": "local", + "source_pin_sha256": "", + "source_label": "", + "source_esphome_version": "", + "target_esphome_version": "", + "failure_reason": "" + }, + { + "job_id": "8bfd4a699e19", + "configuration": "esp-loungenorthswitch.yaml", + "job_type": "upload", + "status": "completed", + "created_at": "2026-08-22T07:45:23.510499+00:00", + "started_at": "2026-08-22T07:57:16.072068+00:00", + "completed_at": "2026-08-22T07:57:26.039856+00:00", + "compile_started_at": null, + "compile_ended_at": null, + "exit_code": 0, + "error": null, + "port": "OTA", + "flash_bootloader": false, + "is_deferred_install": false, + "new_name": "", + "depends_on": "d732f3816b0a", + "dependency_released": true, + "progress": 100, + "remote_peer": "", + "remote_job_id": "", + "remote_peer_label": "", + "device_name": "", + "device_friendly_name": "", + "source": "local", + "source_pin_sha256": "", + "source_label": "", + "source_esphome_version": "", + "target_esphome_version": "", + "failure_reason": "" + }, + { + "job_id": "d732f3816b0a", + "configuration": "esp-loungenorthswitch.yaml", + "job_type": "compile", + "status": "completed", + "created_at": "2026-08-22T07:45:23.510464+00:00", + "started_at": "2026-08-22T07:55:27.249362+00:00", + "completed_at": "2026-08-22T07:57:16.069563+00:00", + "compile_started_at": "2026-08-22T07:55:30.200254+00:00", + "compile_ended_at": "2026-08-22T07:57:14.499585+00:00", + "exit_code": 0, + "error": null, + "port": "", + "flash_bootloader": false, + "is_deferred_install": false, + "new_name": "", + "depends_on": "", + "dependency_released": false, + "progress": null, + "remote_peer": "", + "remote_job_id": "", + "remote_peer_label": "", + "device_name": "", + "device_friendly_name": "", + "source": "local", + "source_pin_sha256": "", + "source_label": "", + "source_esphome_version": "", + "target_esphome_version": "", + "failure_reason": "" + }, + { + "job_id": "a09804fa20aa", + "configuration": "esp-entranceoutsideledlights.yaml", + "job_type": "upload", + "status": "completed", + "created_at": "2026-08-22T04:47:35.217360+00:00", + "started_at": "2026-08-22T04:58:14.146146+00:00", + "completed_at": "2026-08-22T04:58:29.304808+00:00", + "compile_started_at": null, + "compile_ended_at": null, + "exit_code": 0, + "error": null, + "port": "OTA", + "flash_bootloader": false, + "is_deferred_install": false, + "new_name": "", + "depends_on": "277115ad8908", + "dependency_released": true, + "progress": 100, + "remote_peer": "", + "remote_job_id": "", + "remote_peer_label": "", + "device_name": "", + "device_friendly_name": "", + "source": "local", + "source_pin_sha256": "", + "source_label": "", + "source_esphome_version": "", + "target_esphome_version": "", + "failure_reason": "" + }, + { + "job_id": "277115ad8908", + "configuration": "esp-entranceoutsideledlights.yaml", + "job_type": "compile", + "status": "completed", + "created_at": "2026-08-22T04:47:35.217318+00:00", + "started_at": "2026-08-22T04:55:34.198291+00:00", + "completed_at": "2026-08-22T04:58:14.143304+00:00", + "compile_started_at": "2026-08-22T04:55:38.090983+00:00", + "compile_ended_at": "2026-08-22T04:58:12.487157+00:00", + "exit_code": 0, + "error": null, + "port": "", + "flash_bootloader": false, + "is_deferred_install": false, + "new_name": "", + "depends_on": "", + "dependency_released": false, + "progress": null, + "remote_peer": "", + "remote_job_id": "", + "remote_peer_label": "", + "device_name": "", + "device_friendly_name": "", + "source": "local", + "source_pin_sha256": "", + "source_label": "", + "source_esphome_version": "", + "target_esphome_version": "", + "failure_reason": "" + }, + { + "job_id": "a99d81443dea", + "configuration": "esp-downstairskitchleds.yaml", + "job_type": "upload", + "status": "completed", + "created_at": "2026-08-20T11:49:56.464762+00:00", + "started_at": "2026-08-20T12:05:57.932116+00:00", + "completed_at": "2026-08-20T12:06:06.282239+00:00", + "compile_started_at": null, + "compile_ended_at": null, + "exit_code": 0, + "error": null, + "port": "OTA", + "flash_bootloader": false, + "is_deferred_install": false, + "new_name": "", + "depends_on": "e8bbdd3d794e", + "dependency_released": true, + "progress": 100, + "remote_peer": "", + "remote_job_id": "", + "remote_peer_label": "", + "device_name": "", + "device_friendly_name": "", + "source": "local", + "source_pin_sha256": "", + "source_label": "", + "source_esphome_version": "", + "target_esphome_version": "", + "failure_reason": "" + }, + { + "job_id": "e8bbdd3d794e", + "configuration": "esp-downstairskitchleds.yaml", + "job_type": "compile", + "status": "completed", + "created_at": "2026-08-20T11:49:56.464719+00:00", + "started_at": "2026-08-20T12:03:02.989002+00:00", + "completed_at": "2026-08-20T12:05:57.931014+00:00", + "compile_started_at": "2026-08-20T12:03:05.483192+00:00", + "compile_ended_at": "2026-08-20T12:05:56.432159+00:00", + "exit_code": 0, + "error": null, + "port": "", + "flash_bootloader": false, + "is_deferred_install": false, + "new_name": "", + "depends_on": "", + "dependency_released": false, + "progress": null, + "remote_peer": "", + "remote_job_id": "", + "remote_peer_label": "", + "device_name": "", + "device_friendly_name": "", + "source": "local", + "source_pin_sha256": "", + "source_label": "", + "source_esphome_version": "", + "target_esphome_version": "", + "failure_reason": "" + }, + { + "job_id": "7b96967e1489", + "configuration": "esp-bedrm2ceilingfan.yaml", + "job_type": "upload", + "status": "completed", + "created_at": "2026-08-20T11:48:47.854312+00:00", + "started_at": "2026-08-20T11:54:34.561746+00:00", + "completed_at": "2026-08-20T11:54:51.160299+00:00", + "compile_started_at": null, + "compile_ended_at": null, + "exit_code": 0, + "error": null, + "port": "OTA", + "flash_bootloader": false, + "is_deferred_install": false, + "new_name": "", + "depends_on": "66f06d50086c", + "dependency_released": true, + "progress": 100, + "remote_peer": "", + "remote_job_id": "", + "remote_peer_label": "", + "device_name": "", + "device_friendly_name": "", + "source": "local", + "source_pin_sha256": "", + "source_label": "", + "source_esphome_version": "", + "target_esphome_version": "", + "failure_reason": "" + }, + { + "job_id": "66f06d50086c", + "configuration": "esp-bedrm2ceilingfan.yaml", + "job_type": "compile", + "status": "completed", + "created_at": "2026-08-20T11:48:47.854269+00:00", + "started_at": "2026-08-20T11:51:35.613774+00:00", + "completed_at": "2026-08-20T11:54:34.560822+00:00", + "compile_started_at": "2026-08-20T11:51:38.997391+00:00", + "compile_ended_at": "2026-08-20T11:54:32.958041+00:00", + "exit_code": 0, + "error": null, + "port": "", + "flash_bootloader": false, + "is_deferred_install": false, + "new_name": "", + "depends_on": "", + "dependency_released": false, + "progress": null, + "remote_peer": "", + "remote_job_id": "", + "remote_peer_label": "", + "device_name": "", + "device_friendly_name": "", + "source": "local", + "source_pin_sha256": "", + "source_label": "", + "source_esphome_version": "", + "target_esphome_version": "", + "failure_reason": "" + }, + { + "job_id": "e1aba04685af", + "configuration": "esp-officeduallights.yaml", + "job_type": "upload", + "status": "completed", + "created_at": "2026-08-16T05:31:47.346007+00:00", + "started_at": "2026-08-16T05:34:18.649544+00:00", + "completed_at": "2026-08-16T05:34:33.344242+00:00", + "compile_started_at": null, + "compile_ended_at": null, + "exit_code": 0, + "error": null, + "port": "OTA", + "flash_bootloader": false, + "is_deferred_install": false, + "new_name": "", + "depends_on": "8714f3d9487f", + "dependency_released": true, + "progress": 100, + "remote_peer": "", + "remote_job_id": "", + "remote_peer_label": "", + "device_name": "", + "device_friendly_name": "", + "source": "local", + "source_pin_sha256": "", + "source_label": "", + "source_esphome_version": "", + "target_esphome_version": "", + "failure_reason": "" + }, + { + "job_id": "8714f3d9487f", + "configuration": "esp-officeduallights.yaml", + "job_type": "compile", + "status": "completed", + "created_at": "2026-08-16T05:31:47.345962+00:00", + "started_at": "2026-08-16T05:31:47.347180+00:00", + "completed_at": "2026-08-16T05:34:18.641802+00:00", + "compile_started_at": "2026-08-16T05:31:49.819610+00:00", + "compile_ended_at": "2026-08-16T05:34:16.649062+00:00", + "exit_code": 0, + "error": null, + "port": "", + "flash_bootloader": false, + "is_deferred_install": false, + "new_name": "", + "depends_on": "", + "dependency_released": false, "progress": null, "remote_peer": "", "remote_job_id": "", @@ -905,440 +4439,6 @@ "target_esphome_version": "", "failure_reason": "" }, - { - "job_id": "e12f845a0711", - "configuration": "esp-masterbdrmwest.yaml", - "job_type": "upload", - "status": "completed", - "created_at": "2026-07-26T09:13:54.937467+00:00", - "started_at": "2026-07-26T09:16:30.846065+00:00", - "completed_at": "2026-07-26T09:16:40.774363+00:00", - "compile_started_at": null, - "compile_ended_at": null, - "exit_code": 0, - "error": null, - "port": "OTA", - "flash_bootloader": false, - "is_deferred_install": false, - "new_name": "", - "depends_on": "c53ae99094b6", - "dependency_released": true, - "progress": 100, - "remote_peer": "", - "remote_job_id": "", - "remote_peer_label": "", - "device_name": "", - "device_friendly_name": "", - "source": "local", - "source_pin_sha256": "", - "source_label": "", - "source_esphome_version": "", - "target_esphome_version": "", - "failure_reason": "" - }, - { - "job_id": "c53ae99094b6", - "configuration": "esp-masterbdrmwest.yaml", - "job_type": "compile", - "status": "completed", - "created_at": "2026-07-26T09:13:54.937417+00:00", - "started_at": "2026-07-26T09:13:54.938941+00:00", - "completed_at": "2026-07-26T09:16:30.843669+00:00", - "compile_started_at": "2026-07-26T09:14:22.115716+00:00", - "compile_ended_at": "2026-07-26T09:16:29.352799+00:00", - "exit_code": 0, - "error": null, - "port": "", - "flash_bootloader": false, - "is_deferred_install": false, - "new_name": "", - "depends_on": "", - "dependency_released": false, - "progress": null, - "remote_peer": "", - "remote_job_id": "", - "remote_peer_label": "", - "device_name": "", - "device_friendly_name": "", - "source": "local", - "source_pin_sha256": "", - "source_label": "", - "source_esphome_version": "", - "target_esphome_version": "", - "failure_reason": "" - }, - { - "job_id": "94ee1a57c2ff", - "configuration": "esp-officeusbhubpower.yaml", - "job_type": "upload", - "status": "completed", - "created_at": "2026-07-26T08:34:03.809574+00:00", - "started_at": "2026-07-26T08:38:23.704024+00:00", - "completed_at": "2026-07-26T08:38:33.914749+00:00", - "compile_started_at": null, - "compile_ended_at": null, - "exit_code": 0, - "error": null, - "port": "OTA", - "flash_bootloader": false, - "is_deferred_install": false, - "new_name": "", - "depends_on": "ebd8d8364252", - "dependency_released": true, - "progress": 100, - "remote_peer": "", - "remote_job_id": "", - "remote_peer_label": "", - "device_name": "", - "device_friendly_name": "", - "source": "local", - "source_pin_sha256": "", - "source_label": "", - "source_esphome_version": "", - "target_esphome_version": "", - "failure_reason": "" - }, - { - "job_id": "ebd8d8364252", - "configuration": "esp-officeusbhubpower.yaml", - "job_type": "compile", - "status": "completed", - "created_at": "2026-07-26T08:34:03.809469+00:00", - "started_at": "2026-07-26T08:36:15.624789+00:00", - "completed_at": "2026-07-26T08:38:23.701970+00:00", - "compile_started_at": "2026-07-26T08:36:20.887825+00:00", - "compile_ended_at": "2026-07-26T08:38:22.249605+00:00", - "exit_code": 0, - "error": null, - "port": "", - "flash_bootloader": false, - "is_deferred_install": false, - "new_name": "", - "depends_on": "", - "dependency_released": false, - "progress": null, - "remote_peer": "", - "remote_job_id": "", - "remote_peer_label": "", - "device_name": "", - "device_friendly_name": "", - "source": "local", - "source_pin_sha256": "", - "source_label": "", - "source_esphome_version": "", - "target_esphome_version": "", - "failure_reason": "" - }, - { - "job_id": "acdf1464bd29", - "configuration": "esp-loungesouthrightswitch.yaml", - "job_type": "upload", - "status": "completed", - "created_at": "2026-07-26T08:33:44.235789+00:00", - "started_at": "2026-07-26T08:36:15.617978+00:00", - "completed_at": "2026-07-26T08:36:25.610591+00:00", - "compile_started_at": null, - "compile_ended_at": null, - "exit_code": 0, - "error": null, - "port": "OTA", - "flash_bootloader": false, - "is_deferred_install": false, - "new_name": "", - "depends_on": "06ef699dde7b", - "dependency_released": true, - "progress": 100, - "remote_peer": "", - "remote_job_id": "", - "remote_peer_label": "", - "device_name": "", - "device_friendly_name": "", - "source": "local", - "source_pin_sha256": "", - "source_label": "", - "source_esphome_version": "", - "target_esphome_version": "", - "failure_reason": "" - }, - { - "job_id": "06ef699dde7b", - "configuration": "esp-loungesouthrightswitch.yaml", - "job_type": "compile", - "status": "completed", - "created_at": "2026-07-26T08:33:44.235748+00:00", - "started_at": "2026-07-26T08:36:09.388197+00:00", - "completed_at": "2026-07-26T08:36:15.615724+00:00", - "compile_started_at": "2026-07-26T08:36:13.570582+00:00", - "compile_ended_at": "2026-07-26T08:36:15.393502+00:00", - "exit_code": 0, - "error": null, - "port": "", - "flash_bootloader": false, - "is_deferred_install": false, - "new_name": "", - "depends_on": "", - "dependency_released": false, - "progress": null, - "remote_peer": "", - "remote_job_id": "", - "remote_peer_label": "", - "device_name": "", - "device_friendly_name": "", - "source": "local", - "source_pin_sha256": "", - "source_label": "", - "source_esphome_version": "", - "target_esphome_version": "", - "failure_reason": "" - }, - { - "job_id": "b9f94620382e", - "configuration": "esp-masterbdrmsouth.yaml", - "job_type": "upload", - "status": "completed", - "created_at": "2026-07-26T08:33:37.960602+00:00", - "started_at": "2026-07-26T08:36:09.378540+00:00", - "completed_at": "2026-07-26T08:36:19.756598+00:00", - "compile_started_at": null, - "compile_ended_at": null, - "exit_code": 0, - "error": null, - "port": "OTA", - "flash_bootloader": false, - "is_deferred_install": false, - "new_name": "", - "depends_on": "1a7fba35772c", - "dependency_released": true, - "progress": 100, - "remote_peer": "", - "remote_job_id": "", - "remote_peer_label": "", - "device_name": "", - "device_friendly_name": "", - "source": "local", - "source_pin_sha256": "", - "source_label": "", - "source_esphome_version": "", - "target_esphome_version": "", - "failure_reason": "" - }, - { - "job_id": "1a7fba35772c", - "configuration": "esp-masterbdrmsouth.yaml", - "job_type": "compile", - "status": "completed", - "created_at": "2026-07-26T08:33:37.960544+00:00", - "started_at": "2026-07-26T08:33:37.967682+00:00", - "completed_at": "2026-07-26T08:36:09.375801+00:00", - "compile_started_at": "2026-07-26T08:34:05.227790+00:00", - "compile_ended_at": "2026-07-26T08:36:07.887375+00:00", - "exit_code": 0, - "error": null, - "port": "", - "flash_bootloader": false, - "is_deferred_install": false, - "new_name": "", - "depends_on": "", - "dependency_released": false, - "progress": null, - "remote_peer": "", - "remote_job_id": "", - "remote_peer_label": "", - "device_name": "", - "device_friendly_name": "", - "source": "local", - "source_pin_sha256": "", - "source_label": "", - "source_esphome_version": "", - "target_esphome_version": "", - "failure_reason": "" - }, - { - "job_id": "9009d64cb5ed", - "configuration": "esp-downstloungeentry.yaml", - "job_type": "upload", - "status": "completed", - "created_at": "2026-07-26T08:30:47.186984+00:00", - "started_at": "2026-07-26T08:33:15.041106+00:00", - "completed_at": "2026-07-26T08:33:23.563939+00:00", - "compile_started_at": null, - "compile_ended_at": null, - "exit_code": 0, - "error": null, - "port": "OTA", - "flash_bootloader": false, - "is_deferred_install": false, - "new_name": "", - "depends_on": "5e3d525ab45b", - "dependency_released": true, - "progress": 100, - "remote_peer": "", - "remote_job_id": "", - "remote_peer_label": "", - "device_name": "", - "device_friendly_name": "", - "source": "local", - "source_pin_sha256": "", - "source_label": "", - "source_esphome_version": "", - "target_esphome_version": "", - "failure_reason": "" - }, - { - "job_id": "5e3d525ab45b", - "configuration": "esp-downstloungeentry.yaml", - "job_type": "compile", - "status": "completed", - "created_at": "2026-07-26T08:30:47.186900+00:00", - "started_at": "2026-07-26T08:30:47.189352+00:00", - "completed_at": "2026-07-26T08:33:15.038786+00:00", - "compile_started_at": "2026-07-26T08:31:14.487027+00:00", - "compile_ended_at": "2026-07-26T08:33:13.544079+00:00", - "exit_code": 0, - "error": null, - "port": "", - "flash_bootloader": false, - "is_deferred_install": false, - "new_name": "", - "depends_on": "", - "dependency_released": false, - "progress": null, - "remote_peer": "", - "remote_job_id": "", - "remote_peer_label": "", - "device_name": "", - "device_friendly_name": "", - "source": "local", - "source_pin_sha256": "", - "source_label": "", - "source_esphome_version": "", - "target_esphome_version": "", - "failure_reason": "" - }, - { - "job_id": "bade39f01450", - "configuration": "esp-occupancystair.yaml", - "job_type": "upload", - "status": "completed", - "created_at": "2026-07-26T07:46:17.384213+00:00", - "started_at": "2026-07-26T07:52:42.990667+00:00", - "completed_at": "2026-07-26T07:52:59.572434+00:00", - "compile_started_at": null, - "compile_ended_at": null, - "exit_code": 0, - "error": null, - "port": "OTA", - "flash_bootloader": false, - "is_deferred_install": false, - "new_name": "", - "depends_on": "a84a43774cb8", - "dependency_released": true, - "progress": 100, - "remote_peer": "", - "remote_job_id": "", - "remote_peer_label": "", - "device_name": "", - "device_friendly_name": "", - "source": "local", - "source_pin_sha256": "", - "source_label": "", - "source_esphome_version": "", - "target_esphome_version": "", - "failure_reason": "" - }, - { - "job_id": "a84a43774cb8", - "configuration": "esp-occupancystair.yaml", - "job_type": "compile", - "status": "completed", - "created_at": "2026-07-26T07:46:17.384177+00:00", - "started_at": "2026-07-26T07:50:06.193805+00:00", - "completed_at": "2026-07-26T07:52:42.988508+00:00", - "compile_started_at": "2026-07-26T07:50:17.437105+00:00", - "compile_ended_at": "2026-07-26T07:52:42.744695+00:00", - "exit_code": 0, - "error": null, - "port": "", - "flash_bootloader": false, - "is_deferred_install": false, - "new_name": "", - "depends_on": "", - "dependency_released": false, - "progress": 97, - "remote_peer": "", - "remote_job_id": "", - "remote_peer_label": "", - "device_name": "", - "device_friendly_name": "", - "source": "local", - "source_pin_sha256": "", - "source_label": "", - "source_esphome_version": "", - "target_esphome_version": "", - "failure_reason": "" - }, - { - "job_id": "59bffad5b16d", - "configuration": "esp-nspanel2lounge.yaml", - "job_type": "upload", - "status": "completed", - "created_at": "2026-07-26T07:45:53.650708+00:00", - "started_at": "2026-07-26T07:50:06.181451+00:00", - "completed_at": "2026-07-26T07:50:25.160015+00:00", - "compile_started_at": null, - "compile_ended_at": null, - "exit_code": 0, - "error": null, - "port": "OTA", - "flash_bootloader": false, - "is_deferred_install": false, - "new_name": "", - "depends_on": "f84dbca1b170", - "dependency_released": true, - "progress": 100, - "remote_peer": "", - "remote_job_id": "", - "remote_peer_label": "", - "device_name": "", - "device_friendly_name": "", - "source": "local", - "source_pin_sha256": "", - "source_label": "", - "source_esphome_version": "", - "target_esphome_version": "", - "failure_reason": "" - }, - { - "job_id": "f84dbca1b170", - "configuration": "esp-nspanel2lounge.yaml", - "job_type": "compile", - "status": "completed", - "created_at": "2026-07-26T07:45:53.650636+00:00", - "started_at": "2026-07-26T07:45:53.652030+00:00", - "completed_at": "2026-07-26T07:50:06.177463+00:00", - "compile_started_at": "2026-07-26T07:46:29.866789+00:00", - "compile_ended_at": "2026-07-26T07:50:05.512980+00:00", - "exit_code": 0, - "error": null, - "port": "", - "flash_bootloader": false, - "is_deferred_install": false, - "new_name": "", - "depends_on": "", - "dependency_released": false, - "progress": 99, - "remote_peer": "", - "remote_job_id": "", - "remote_peer_label": "", - "device_name": "", - "device_friendly_name": "", - "source": "local", - "source_pin_sha256": "", - "source_label": "", - "source_esphome_version": "", - "target_esphome_version": "", - "failure_reason": "" - }, { "job_id": "d62458de05ec", "configuration": "esp-breakfastbarleds.yaml", @@ -1463,68 +4563,6 @@ "target_esphome_version": "", "failure_reason": "" }, - { - "job_id": "392a4717dcf2", - "configuration": "esp-downstairskitchleds.yaml", - "job_type": "upload", - "status": "completed", - "created_at": "2026-07-26T06:18:42.041714+00:00", - "started_at": "2026-07-26T06:25:15.825514+00:00", - "completed_at": "2026-07-26T06:25:25.403219+00:00", - "compile_started_at": null, - "compile_ended_at": null, - "exit_code": 0, - "error": null, - "port": "OTA", - "flash_bootloader": false, - "is_deferred_install": false, - "new_name": "", - "depends_on": "979c5d3108f0", - "dependency_released": true, - "progress": 100, - "remote_peer": "", - "remote_job_id": "", - "remote_peer_label": "", - "device_name": "", - "device_friendly_name": "", - "source": "local", - "source_pin_sha256": "", - "source_label": "", - "source_esphome_version": "", - "target_esphome_version": "", - "failure_reason": "" - }, - { - "job_id": "979c5d3108f0", - "configuration": "esp-downstairskitchleds.yaml", - "job_type": "compile", - "status": "completed", - "created_at": "2026-07-26T06:18:42.041677+00:00", - "started_at": "2026-07-26T06:25:03.788643+00:00", - "completed_at": "2026-07-26T06:25:15.823793+00:00", - "compile_started_at": "2026-07-26T06:25:07.159853+00:00", - "compile_ended_at": "2026-07-26T06:25:15.535105+00:00", - "exit_code": 0, - "error": null, - "port": "", - "flash_bootloader": false, - "is_deferred_install": false, - "new_name": "", - "depends_on": "", - "dependency_released": false, - "progress": null, - "remote_peer": "", - "remote_job_id": "", - "remote_peer_label": "", - "device_name": "", - "device_friendly_name": "", - "source": "local", - "source_pin_sha256": "", - "source_label": "", - "source_esphome_version": "", - "target_esphome_version": "", - "failure_reason": "" - }, { "job_id": "55085d28fa6e", "configuration": "esp-bedrm1arlecbulb.yaml", @@ -1711,130 +4749,6 @@ "target_esphome_version": "", "failure_reason": "" }, - { - "job_id": "5c1aacb8a99a", - "configuration": "esp-entmulti.yaml", - "job_type": "upload", - "status": "completed", - "created_at": "2026-07-26T06:00:10.226140+00:00", - "started_at": "2026-07-26T06:00:48.504040+00:00", - "completed_at": "2026-07-26T06:06:01.456994+00:00", - "compile_started_at": null, - "compile_ended_at": null, - "exit_code": 0, - "error": null, - "port": "OTA", - "flash_bootloader": false, - "is_deferred_install": false, - "new_name": "", - "depends_on": "81f1aba19a86", - "dependency_released": true, - "progress": 100, - "remote_peer": "", - "remote_job_id": "", - "remote_peer_label": "", - "device_name": "", - "device_friendly_name": "", - "source": "local", - "source_pin_sha256": "", - "source_label": "", - "source_esphome_version": "", - "target_esphome_version": "", - "failure_reason": "" - }, - { - "job_id": "81f1aba19a86", - "configuration": "esp-entmulti.yaml", - "job_type": "compile", - "status": "completed", - "created_at": "2026-07-26T06:00:10.226098+00:00", - "started_at": "2026-07-26T06:00:10.227204+00:00", - "completed_at": "2026-07-26T06:00:48.500836+00:00", - "compile_started_at": "2026-07-26T06:00:14.289805+00:00", - "compile_ended_at": "2026-07-26T06:00:48.221444+00:00", - "exit_code": 0, - "error": null, - "port": "", - "flash_bootloader": false, - "is_deferred_install": false, - "new_name": "", - "depends_on": "", - "dependency_released": false, - "progress": 41, - "remote_peer": "", - "remote_job_id": "", - "remote_peer_label": "", - "device_name": "", - "device_friendly_name": "", - "source": "local", - "source_pin_sha256": "", - "source_label": "", - "source_esphome_version": "", - "target_esphome_version": "", - "failure_reason": "" - }, - { - "job_id": "3bb5edb10815", - "configuration": "esp-lounge6chdimmer.yaml", - "job_type": "upload", - "status": "completed", - "created_at": "2026-07-26T05:46:28.394657+00:00", - "started_at": "2026-07-26T05:57:33.108864+00:00", - "completed_at": "2026-07-26T05:57:40.735934+00:00", - "compile_started_at": null, - "compile_ended_at": null, - "exit_code": 0, - "error": null, - "port": "OTA", - "flash_bootloader": false, - "is_deferred_install": false, - "new_name": "", - "depends_on": "c779b0efade8", - "dependency_released": true, - "progress": 100, - "remote_peer": "", - "remote_job_id": "", - "remote_peer_label": "", - "device_name": "", - "device_friendly_name": "", - "source": "local", - "source_pin_sha256": "", - "source_label": "", - "source_esphome_version": "", - "target_esphome_version": "", - "failure_reason": "" - }, - { - "job_id": "c779b0efade8", - "configuration": "esp-lounge6chdimmer.yaml", - "job_type": "compile", - "status": "completed", - "created_at": "2026-07-26T05:46:28.394618+00:00", - "started_at": "2026-07-26T05:53:21.488683+00:00", - "completed_at": "2026-07-26T05:57:33.106409+00:00", - "compile_started_at": "2026-07-26T05:53:29.071610+00:00", - "compile_ended_at": "2026-07-26T05:57:30.754810+00:00", - "exit_code": 0, - "error": null, - "port": "", - "flash_bootloader": false, - "is_deferred_install": false, - "new_name": "", - "depends_on": "", - "dependency_released": false, - "progress": null, - "remote_peer": "", - "remote_job_id": "", - "remote_peer_label": "", - "device_name": "", - "device_friendly_name": "", - "source": "local", - "source_pin_sha256": "", - "source_label": "", - "source_esphome_version": "", - "target_esphome_version": "", - "failure_reason": "" - }, { "job_id": "331655348831", "configuration": "esp-bedrm3ceilingfan.yaml", @@ -2083,2300 +4997,6 @@ "target_esphome_version": "", "failure_reason": "" }, - { - "job_id": "acd967af773b", - "configuration": "esp-entrancebathrmlights.yaml", - "job_type": "upload", - "status": "completed", - "created_at": "2026-07-26T05:38:18.089976+00:00", - "started_at": "2026-07-26T05:38:31.904311+00:00", - "completed_at": "2026-07-26T05:38:42.220115+00:00", - "compile_started_at": null, - "compile_ended_at": null, - "exit_code": 0, - "error": null, - "port": "OTA", - "flash_bootloader": false, - "is_deferred_install": false, - "new_name": "", - "depends_on": "8c6ddaac26b0", - "dependency_released": true, - "progress": 100, - "remote_peer": "", - "remote_job_id": "", - "remote_peer_label": "", - "device_name": "", - "device_friendly_name": "", - "source": "local", - "source_pin_sha256": "", - "source_label": "", - "source_esphome_version": "", - "target_esphome_version": "", - "failure_reason": "" - }, - { - "job_id": "8c6ddaac26b0", - "configuration": "esp-entrancebathrmlights.yaml", - "job_type": "compile", - "status": "completed", - "created_at": "2026-07-26T05:38:18.089938+00:00", - "started_at": "2026-07-26T05:38:24.431184+00:00", - "completed_at": "2026-07-26T05:38:31.902158+00:00", - "compile_started_at": "2026-07-26T05:38:29.334707+00:00", - "compile_ended_at": "2026-07-26T05:38:31.583982+00:00", - "exit_code": 0, - "error": null, - "port": "", - "flash_bootloader": false, - "is_deferred_install": false, - "new_name": "", - "depends_on": "", - "dependency_released": false, - "progress": null, - "remote_peer": "", - "remote_job_id": "", - "remote_peer_label": "", - "device_name": "", - "device_friendly_name": "", - "source": "local", - "source_pin_sha256": "", - "source_label": "", - "source_esphome_version": "", - "target_esphome_version": "", - "failure_reason": "" - }, - { - "job_id": "653801fbb76c", - "configuration": "esp-datacupboardfans.yaml", - "job_type": "upload", - "status": "completed", - "created_at": "2026-07-26T05:38:11.524782+00:00", - "started_at": "2026-07-26T05:38:24.401312+00:00", - "completed_at": "2026-07-26T05:38:31.350686+00:00", - "compile_started_at": null, - "compile_ended_at": null, - "exit_code": 0, - "error": null, - "port": "OTA", - "flash_bootloader": false, - "is_deferred_install": false, - "new_name": "", - "depends_on": "5cc5ac77a400", - "dependency_released": true, - "progress": 100, - "remote_peer": "", - "remote_job_id": "", - "remote_peer_label": "", - "device_name": "", - "device_friendly_name": "", - "source": "local", - "source_pin_sha256": "", - "source_label": "", - "source_esphome_version": "", - "target_esphome_version": "", - "failure_reason": "" - }, - { - "job_id": "5cc5ac77a400", - "configuration": "esp-datacupboardfans.yaml", - "job_type": "compile", - "status": "completed", - "created_at": "2026-07-26T05:38:11.524060+00:00", - "started_at": "2026-07-26T05:38:11.526273+00:00", - "completed_at": "2026-07-26T05:38:24.399962+00:00", - "compile_started_at": "2026-07-26T05:38:16.661839+00:00", - "compile_ended_at": "2026-07-26T05:38:24.107797+00:00", - "exit_code": 0, - "error": null, - "port": "", - "flash_bootloader": false, - "is_deferred_install": false, - "new_name": "", - "depends_on": "", - "dependency_released": false, - "progress": null, - "remote_peer": "", - "remote_job_id": "", - "remote_peer_label": "", - "device_name": "", - "device_friendly_name": "", - "source": "local", - "source_pin_sha256": "", - "source_label": "", - "source_esphome_version": "", - "target_esphome_version": "", - "failure_reason": "" - }, - { - "job_id": "0ec369057631", - "configuration": "esp-loungeenvironment.yaml", - "job_type": "upload", - "status": "completed", - "created_at": "2026-07-25T11:55:50.445472+00:00", - "started_at": "2026-07-25T13:15:24.250843+00:00", - "completed_at": "2026-07-25T13:15:42.751604+00:00", - "compile_started_at": null, - "compile_ended_at": null, - "exit_code": 0, - "error": null, - "port": "OTA", - "flash_bootloader": false, - "is_deferred_install": false, - "new_name": "", - "depends_on": "784dd1146e89", - "dependency_released": true, - "progress": 100, - "remote_peer": "", - "remote_job_id": "", - "remote_peer_label": "", - "device_name": "", - "device_friendly_name": "", - "source": "local", - "source_pin_sha256": "", - "source_label": "", - "source_esphome_version": "", - "target_esphome_version": "", - "failure_reason": "" - }, - { - "job_id": "784dd1146e89", - "configuration": "esp-loungeenvironment.yaml", - "job_type": "compile", - "status": "completed", - "created_at": "2026-07-25T11:55:50.445426+00:00", - "started_at": "2026-07-25T13:11:27.442060+00:00", - "completed_at": "2026-07-25T13:15:24.248837+00:00", - "compile_started_at": "2026-07-25T13:11:43.527175+00:00", - "compile_ended_at": "2026-07-25T13:15:23.984301+00:00", - "exit_code": 0, - "error": null, - "port": "", - "flash_bootloader": false, - "is_deferred_install": false, - "new_name": "", - "depends_on": "", - "dependency_released": false, - "progress": 99, - "remote_peer": "", - "remote_job_id": "", - "remote_peer_label": "", - "device_name": "", - "device_friendly_name": "", - "source": "local", - "source_pin_sha256": "", - "source_label": "", - "source_esphome_version": "", - "target_esphome_version": "", - "failure_reason": "" - }, - { - "job_id": "12980c9cd7d2", - "configuration": "esp-mainpowermonitor.yaml", - "job_type": "upload", - "status": "completed", - "created_at": "2026-07-25T11:55:41.647549+00:00", - "started_at": "2026-07-25T13:11:27.434015+00:00", - "completed_at": "2026-07-25T13:11:34.902547+00:00", - "compile_started_at": null, - "compile_ended_at": null, - "exit_code": 0, - "error": null, - "port": "OTA", - "flash_bootloader": false, - "is_deferred_install": false, - "new_name": "", - "depends_on": "b87fc3e19403", - "dependency_released": true, - "progress": 100, - "remote_peer": "", - "remote_job_id": "", - "remote_peer_label": "", - "device_name": "", - "device_friendly_name": "", - "source": "local", - "source_pin_sha256": "", - "source_label": "", - "source_esphome_version": "", - "target_esphome_version": "", - "failure_reason": "" - }, - { - "job_id": "b87fc3e19403", - "configuration": "esp-mainpowermonitor.yaml", - "job_type": "compile", - "status": "completed", - "created_at": "2026-07-25T11:55:41.647499+00:00", - "started_at": "2026-07-25T13:05:08.356290+00:00", - "completed_at": "2026-07-25T13:11:27.431872+00:00", - "compile_started_at": "2026-07-25T13:05:12.370588+00:00", - "compile_ended_at": "2026-07-25T13:11:25.801260+00:00", - "exit_code": 0, - "error": null, - "port": "", - "flash_bootloader": false, - "is_deferred_install": false, - "new_name": "", - "depends_on": "", - "dependency_released": false, - "progress": null, - "remote_peer": "", - "remote_job_id": "", - "remote_peer_label": "", - "device_name": "", - "device_friendly_name": "", - "source": "local", - "source_pin_sha256": "", - "source_label": "", - "source_esphome_version": "", - "target_esphome_version": "", - "failure_reason": "" - }, - { - "job_id": "7c58d8c0928c", - "configuration": "esp-maindishwasherpower.yaml", - "job_type": "upload", - "status": "completed", - "created_at": "2026-07-25T11:55:36.326965+00:00", - "started_at": "2026-07-25T13:05:08.349387+00:00", - "completed_at": "2026-07-25T13:10:19.803898+00:00", - "compile_started_at": null, - "compile_ended_at": null, - "exit_code": 0, - "error": null, - "port": "OTA", - "flash_bootloader": false, - "is_deferred_install": false, - "new_name": "", - "depends_on": "1fdc5ee6b879", - "dependency_released": true, - "progress": 100, - "remote_peer": "", - "remote_job_id": "", - "remote_peer_label": "", - "device_name": "", - "device_friendly_name": "", - "source": "local", - "source_pin_sha256": "", - "source_label": "", - "source_esphome_version": "", - "target_esphome_version": "", - "failure_reason": "" - }, - { - "job_id": "1fdc5ee6b879", - "configuration": "esp-maindishwasherpower.yaml", - "job_type": "compile", - "status": "completed", - "created_at": "2026-07-25T11:55:36.326926+00:00", - "started_at": "2026-07-25T13:02:07.321401+00:00", - "completed_at": "2026-07-25T13:05:08.347078+00:00", - "compile_started_at": "2026-07-25T13:02:23.609894+00:00", - "compile_ended_at": "2026-07-25T13:05:08.090913+00:00", - "exit_code": 0, - "error": null, - "port": "", - "flash_bootloader": false, - "is_deferred_install": false, - "new_name": "", - "depends_on": "", - "dependency_released": false, - "progress": 99, - "remote_peer": "", - "remote_job_id": "", - "remote_peer_label": "", - "device_name": "", - "device_friendly_name": "", - "source": "local", - "source_pin_sha256": "", - "source_label": "", - "source_esphome_version": "", - "target_esphome_version": "", - "failure_reason": "" - }, - { - "job_id": "0f929824f9c2", - "configuration": "esp-rocktumbler.yaml", - "job_type": "upload", - "status": "completed", - "created_at": "2026-07-25T11:54:55.394981+00:00", - "started_at": "2026-07-25T12:58:57.737604+00:00", - "completed_at": "2026-07-25T12:59:06.212832+00:00", - "compile_started_at": null, - "compile_ended_at": null, - "exit_code": 0, - "error": null, - "port": "OTA", - "flash_bootloader": false, - "is_deferred_install": false, - "new_name": "", - "depends_on": "3316726ee524", - "dependency_released": true, - "progress": 100, - "remote_peer": "", - "remote_job_id": "", - "remote_peer_label": "", - "device_name": "", - "device_friendly_name": "", - "source": "local", - "source_pin_sha256": "", - "source_label": "", - "source_esphome_version": "", - "target_esphome_version": "", - "failure_reason": "" - }, - { - "job_id": "3316726ee524", - "configuration": "esp-rocktumbler.yaml", - "job_type": "compile", - "status": "completed", - "created_at": "2026-07-25T11:54:55.394940+00:00", - "started_at": "2026-07-25T12:56:10.761200+00:00", - "completed_at": "2026-07-25T12:58:57.735476+00:00", - "compile_started_at": "2026-07-25T12:56:16.285897+00:00", - "compile_ended_at": "2026-07-25T12:58:56.040849+00:00", - "exit_code": 0, - "error": null, - "port": "", - "flash_bootloader": false, - "is_deferred_install": false, - "new_name": "", - "depends_on": "", - "dependency_released": false, - "progress": null, - "remote_peer": "", - "remote_job_id": "", - "remote_peer_label": "", - "device_name": "", - "device_friendly_name": "", - "source": "local", - "source_pin_sha256": "", - "source_label": "", - "source_esphome_version": "", - "target_esphome_version": "", - "failure_reason": "" - }, - { - "job_id": "cd460d7d90fc", - "configuration": "esp-poollightpower2.yaml", - "job_type": "upload", - "status": "completed", - "created_at": "2026-07-25T11:54:39.896576+00:00", - "started_at": "2026-07-25T12:56:10.755207+00:00", - "completed_at": "2026-07-25T12:56:21.121626+00:00", - "compile_started_at": null, - "compile_ended_at": null, - "exit_code": 0, - "error": null, - "port": "OTA", - "flash_bootloader": false, - "is_deferred_install": false, - "new_name": "", - "depends_on": "c1fcbbd25d38", - "dependency_released": true, - "progress": 100, - "remote_peer": "", - "remote_job_id": "", - "remote_peer_label": "", - "device_name": "", - "device_friendly_name": "", - "source": "local", - "source_pin_sha256": "", - "source_label": "", - "source_esphome_version": "", - "target_esphome_version": "", - "failure_reason": "" - }, - { - "job_id": "c1fcbbd25d38", - "configuration": "esp-poollightpower2.yaml", - "job_type": "compile", - "status": "completed", - "created_at": "2026-07-25T11:54:39.896538+00:00", - "started_at": "2026-07-25T12:53:13.202316+00:00", - "completed_at": "2026-07-25T12:56:10.753186+00:00", - "compile_started_at": "2026-07-25T12:53:23.487278+00:00", - "compile_ended_at": "2026-07-25T12:56:08.996318+00:00", - "exit_code": 0, - "error": null, - "port": "", - "flash_bootloader": false, - "is_deferred_install": false, - "new_name": "", - "depends_on": "", - "dependency_released": false, - "progress": null, - "remote_peer": "", - "remote_job_id": "", - "remote_peer_label": "", - "device_name": "", - "device_friendly_name": "", - "source": "local", - "source_pin_sha256": "", - "source_label": "", - "source_esphome_version": "", - "target_esphome_version": "", - "failure_reason": "" - }, - { - "job_id": "276411ea7db1", - "configuration": "esp-poolpumppower.yaml", - "job_type": "upload", - "status": "completed", - "created_at": "2026-07-25T11:54:02.869063+00:00", - "started_at": "2026-07-25T12:48:42.351383+00:00", - "completed_at": "2026-07-25T12:49:23.765053+00:00", - "compile_started_at": null, - "compile_ended_at": null, - "exit_code": 0, - "error": null, - "port": "OTA", - "flash_bootloader": false, - "is_deferred_install": false, - "new_name": "", - "depends_on": "7e8c51cb73de", - "dependency_released": true, - "progress": 100, - "remote_peer": "", - "remote_job_id": "", - "remote_peer_label": "", - "device_name": "", - "device_friendly_name": "", - "source": "local", - "source_pin_sha256": "", - "source_label": "", - "source_esphome_version": "", - "target_esphome_version": "", - "failure_reason": "" - }, - { - "job_id": "7e8c51cb73de", - "configuration": "esp-poolpumppower.yaml", - "job_type": "compile", - "status": "completed", - "created_at": "2026-07-25T11:54:02.869022+00:00", - "started_at": "2026-07-25T12:43:42.176123+00:00", - "completed_at": "2026-07-25T12:48:42.349036+00:00", - "compile_started_at": "2026-07-25T12:44:02.134231+00:00", - "compile_ended_at": "2026-07-25T12:48:42.041270+00:00", - "exit_code": 0, - "error": null, - "port": "", - "flash_bootloader": false, - "is_deferred_install": false, - "new_name": "", - "depends_on": "", - "dependency_released": false, - "progress": 99, - "remote_peer": "", - "remote_job_id": "", - "remote_peer_label": "", - "device_name": "", - "device_friendly_name": "", - "source": "local", - "source_pin_sha256": "", - "source_label": "", - "source_esphome_version": "", - "target_esphome_version": "", - "failure_reason": "" - }, - { - "job_id": "cbd941e99c01", - "configuration": "esp-laundrywashpow.yaml", - "job_type": "upload", - "status": "completed", - "created_at": "2026-07-25T11:53:38.706990+00:00", - "started_at": "2026-07-25T12:43:42.166040+00:00", - "completed_at": "2026-07-25T12:43:51.887370+00:00", - "compile_started_at": null, - "compile_ended_at": null, - "exit_code": 0, - "error": null, - "port": "OTA", - "flash_bootloader": false, - "is_deferred_install": false, - "new_name": "", - "depends_on": "2ae2cc700ec5", - "dependency_released": true, - "progress": 100, - "remote_peer": "", - "remote_job_id": "", - "remote_peer_label": "", - "device_name": "", - "device_friendly_name": "", - "source": "local", - "source_pin_sha256": "", - "source_label": "", - "source_esphome_version": "", - "target_esphome_version": "", - "failure_reason": "" - }, - { - "job_id": "2ae2cc700ec5", - "configuration": "esp-laundrywashpow.yaml", - "job_type": "compile", - "status": "completed", - "created_at": "2026-07-25T11:53:38.706950+00:00", - "started_at": "2026-07-25T12:37:11.218657+00:00", - "completed_at": "2026-07-25T12:43:42.163632+00:00", - "compile_started_at": "2026-07-25T12:37:13.687172+00:00", - "compile_ended_at": "2026-07-25T12:43:40.619270+00:00", - "exit_code": 0, - "error": null, - "port": "", - "flash_bootloader": false, - "is_deferred_install": false, - "new_name": "", - "depends_on": "", - "dependency_released": false, - "progress": null, - "remote_peer": "", - "remote_job_id": "", - "remote_peer_label": "", - "device_name": "", - "device_friendly_name": "", - "source": "local", - "source_pin_sha256": "", - "source_label": "", - "source_esphome_version": "", - "target_esphome_version": "", - "failure_reason": "" - }, - { - "job_id": "070bfda14fda", - "configuration": "esp-laundrydrypow.yaml", - "job_type": "upload", - "status": "completed", - "created_at": "2026-07-25T11:53:31.143073+00:00", - "started_at": "2026-07-25T12:37:11.212944+00:00", - "completed_at": "2026-07-25T12:37:21.695812+00:00", - "compile_started_at": null, - "compile_ended_at": null, - "exit_code": 0, - "error": null, - "port": "OTA", - "flash_bootloader": false, - "is_deferred_install": false, - "new_name": "", - "depends_on": "f1bdada56114", - "dependency_released": true, - "progress": 100, - "remote_peer": "", - "remote_job_id": "", - "remote_peer_label": "", - "device_name": "", - "device_friendly_name": "", - "source": "local", - "source_pin_sha256": "", - "source_label": "", - "source_esphome_version": "", - "target_esphome_version": "", - "failure_reason": "" - }, - { - "job_id": "f1bdada56114", - "configuration": "esp-laundrydrypow.yaml", - "job_type": "compile", - "status": "completed", - "created_at": "2026-07-25T11:53:31.143036+00:00", - "started_at": "2026-07-25T12:30:40.877693+00:00", - "completed_at": "2026-07-25T12:37:11.203926+00:00", - "compile_started_at": "2026-07-25T12:30:43.388772+00:00", - "compile_ended_at": "2026-07-25T12:37:09.580973+00:00", - "exit_code": 0, - "error": null, - "port": "", - "flash_bootloader": false, - "is_deferred_install": false, - "new_name": "", - "depends_on": "", - "dependency_released": false, - "progress": null, - "remote_peer": "", - "remote_job_id": "", - "remote_peer_label": "", - "device_name": "", - "device_friendly_name": "", - "source": "local", - "source_pin_sha256": "", - "source_label": "", - "source_esphome_version": "", - "target_esphome_version": "", - "failure_reason": "" - }, - { - "job_id": "f0d2310254f4", - "configuration": "esp-garagebtproxy.yaml", - "job_type": "upload", - "status": "completed", - "created_at": "2026-07-25T11:53:23.431030+00:00", - "started_at": "2026-07-25T12:30:40.868011+00:00", - "completed_at": "2026-07-25T12:30:58.282043+00:00", - "compile_started_at": null, - "compile_ended_at": null, - "exit_code": 0, - "error": null, - "port": "OTA", - "flash_bootloader": false, - "is_deferred_install": false, - "new_name": "", - "depends_on": "5d85d0ef1dd8", - "dependency_released": true, - "progress": 100, - "remote_peer": "", - "remote_job_id": "", - "remote_peer_label": "", - "device_name": "", - "device_friendly_name": "", - "source": "local", - "source_pin_sha256": "", - "source_label": "", - "source_esphome_version": "", - "target_esphome_version": "", - "failure_reason": "" - }, - { - "job_id": "5d85d0ef1dd8", - "configuration": "esp-garagebtproxy.yaml", - "job_type": "compile", - "status": "completed", - "created_at": "2026-07-25T11:53:23.430989+00:00", - "started_at": "2026-07-25T12:26:00.049404+00:00", - "completed_at": "2026-07-25T12:30:40.866332+00:00", - "compile_started_at": "2026-07-25T12:26:17.417034+00:00", - "compile_ended_at": "2026-07-25T12:30:40.654712+00:00", - "exit_code": 0, - "error": null, - "port": "", - "flash_bootloader": false, - "is_deferred_install": false, - "new_name": "", - "depends_on": "", - "dependency_released": false, - "progress": 99, - "remote_peer": "", - "remote_job_id": "", - "remote_peer_label": "", - "device_name": "", - "device_friendly_name": "", - "source": "local", - "source_pin_sha256": "", - "source_label": "", - "source_esphome_version": "", - "target_esphome_version": "", - "failure_reason": "" - }, - { - "job_id": "657d800b21bd", - "configuration": "esp-garagedbcontrols.yaml", - "job_type": "upload", - "status": "completed", - "created_at": "2026-07-25T11:53:17.023178+00:00", - "started_at": "2026-07-25T12:26:00.032823+00:00", - "completed_at": "2026-07-25T12:26:15.951906+00:00", - "compile_started_at": null, - "compile_ended_at": null, - "exit_code": 0, - "error": null, - "port": "OTA", - "flash_bootloader": false, - "is_deferred_install": false, - "new_name": "", - "depends_on": "1fb0864bacb8", - "dependency_released": true, - "progress": 100, - "remote_peer": "", - "remote_job_id": "", - "remote_peer_label": "", - "device_name": "", - "device_friendly_name": "", - "source": "local", - "source_pin_sha256": "", - "source_label": "", - "source_esphome_version": "", - "target_esphome_version": "", - "failure_reason": "" - }, - { - "job_id": "1fb0864bacb8", - "configuration": "esp-garagedbcontrols.yaml", - "job_type": "compile", - "status": "completed", - "created_at": "2026-07-25T11:53:17.023141+00:00", - "started_at": "2026-07-25T12:23:08.813757+00:00", - "completed_at": "2026-07-25T12:26:00.029830+00:00", - "compile_started_at": "2026-07-25T12:23:23.546830+00:00", - "compile_ended_at": "2026-07-25T12:25:58.349374+00:00", - "exit_code": 0, - "error": null, - "port": "", - "flash_bootloader": false, - "is_deferred_install": false, - "new_name": "", - "depends_on": "", - "dependency_released": false, - "progress": null, - "remote_peer": "", - "remote_job_id": "", - "remote_peer_label": "", - "device_name": "", - "device_friendly_name": "", - "source": "local", - "source_pin_sha256": "", - "source_label": "", - "source_esphome_version": "", - "target_esphome_version": "", - "failure_reason": "" - }, - { - "job_id": "9608e1cef017", - "configuration": "esp-entranceoutsideledlights.yaml", - "job_type": "upload", - "status": "completed", - "created_at": "2026-07-25T11:53:10.680180+00:00", - "started_at": "2026-07-25T12:23:08.805792+00:00", - "completed_at": "2026-07-25T12:23:19.397748+00:00", - "compile_started_at": null, - "compile_ended_at": null, - "exit_code": 0, - "error": null, - "port": "OTA", - "flash_bootloader": false, - "is_deferred_install": false, - "new_name": "", - "depends_on": "8036cc3e1712", - "dependency_released": true, - "progress": 100, - "remote_peer": "", - "remote_job_id": "", - "remote_peer_label": "", - "device_name": "", - "device_friendly_name": "", - "source": "local", - "source_pin_sha256": "", - "source_label": "", - "source_esphome_version": "", - "target_esphome_version": "", - "failure_reason": "" - }, - { - "job_id": "8036cc3e1712", - "configuration": "esp-entranceoutsideledlights.yaml", - "job_type": "compile", - "status": "completed", - "created_at": "2026-07-25T11:53:10.680142+00:00", - "started_at": "2026-07-25T12:20:11.466107+00:00", - "completed_at": "2026-07-25T12:23:08.803962+00:00", - "compile_started_at": "2026-07-25T12:20:17.588990+00:00", - "compile_ended_at": "2026-07-25T12:23:07.144122+00:00", - "exit_code": 0, - "error": null, - "port": "", - "flash_bootloader": false, - "is_deferred_install": false, - "new_name": "", - "depends_on": "", - "dependency_released": false, - "progress": null, - "remote_peer": "", - "remote_job_id": "", - "remote_peer_label": "", - "device_name": "", - "device_friendly_name": "", - "source": "local", - "source_pin_sha256": "", - "source_label": "", - "source_esphome_version": "", - "target_esphome_version": "", - "failure_reason": "" - }, - { - "job_id": "2a47a120fa58", - "configuration": "esp-datacupboardpower-right.yaml", - "job_type": "upload", - "status": "completed", - "created_at": "2026-07-25T11:53:00.929680+00:00", - "started_at": "2026-07-25T12:20:11.459683+00:00", - "completed_at": "2026-07-25T12:20:19.213972+00:00", - "compile_started_at": null, - "compile_ended_at": null, - "exit_code": 0, - "error": null, - "port": "OTA", - "flash_bootloader": false, - "is_deferred_install": false, - "new_name": "", - "depends_on": "dece62308682", - "dependency_released": true, - "progress": 100, - "remote_peer": "", - "remote_job_id": "", - "remote_peer_label": "", - "device_name": "", - "device_friendly_name": "", - "source": "local", - "source_pin_sha256": "", - "source_label": "", - "source_esphome_version": "", - "target_esphome_version": "", - "failure_reason": "" - }, - { - "job_id": "dece62308682", - "configuration": "esp-datacupboardpower-right.yaml", - "job_type": "compile", - "status": "completed", - "created_at": "2026-07-25T11:53:00.929619+00:00", - "started_at": "2026-07-25T12:17:25.583402+00:00", - "completed_at": "2026-07-25T12:20:11.457454+00:00", - "compile_started_at": "2026-07-25T12:17:31.762921+00:00", - "compile_ended_at": "2026-07-25T12:20:09.793512+00:00", - "exit_code": 0, - "error": null, - "port": "", - "flash_bootloader": false, - "is_deferred_install": false, - "new_name": "", - "depends_on": "", - "dependency_released": false, - "progress": null, - "remote_peer": "", - "remote_job_id": "", - "remote_peer_label": "", - "device_name": "", - "device_friendly_name": "", - "source": "local", - "source_pin_sha256": "", - "source_label": "", - "source_esphome_version": "", - "target_esphome_version": "", - "failure_reason": "" - }, - { - "job_id": "dc9b2ad2470f", - "configuration": "esp-datacupboardpower-left.yaml", - "job_type": "upload", - "status": "completed", - "created_at": "2026-07-25T11:52:52.937995+00:00", - "started_at": "2026-07-25T12:17:25.563839+00:00", - "completed_at": "2026-07-25T12:17:33.097256+00:00", - "compile_started_at": null, - "compile_ended_at": null, - "exit_code": 0, - "error": null, - "port": "OTA", - "flash_bootloader": false, - "is_deferred_install": false, - "new_name": "", - "depends_on": "87c00674bf55", - "dependency_released": true, - "progress": 100, - "remote_peer": "", - "remote_job_id": "", - "remote_peer_label": "", - "device_name": "", - "device_friendly_name": "", - "source": "local", - "source_pin_sha256": "", - "source_label": "", - "source_esphome_version": "", - "target_esphome_version": "", - "failure_reason": "" - }, - { - "job_id": "87c00674bf55", - "configuration": "esp-datacupboardpower-left.yaml", - "job_type": "compile", - "status": "completed", - "created_at": "2026-07-25T11:52:52.937952+00:00", - "started_at": "2026-07-25T12:14:35.994478+00:00", - "completed_at": "2026-07-25T12:17:25.556351+00:00", - "compile_started_at": "2026-07-25T12:14:44.441023+00:00", - "compile_ended_at": "2026-07-25T12:17:23.988295+00:00", - "exit_code": 0, - "error": null, - "port": "", - "flash_bootloader": false, - "is_deferred_install": false, - "new_name": "", - "depends_on": "", - "dependency_released": false, - "progress": null, - "remote_peer": "", - "remote_job_id": "", - "remote_peer_label": "", - "device_name": "", - "device_friendly_name": "", - "source": "local", - "source_pin_sha256": "", - "source_label": "", - "source_esphome_version": "", - "target_esphome_version": "", - "failure_reason": "" - }, - { - "job_id": "a97cec78925a", - "configuration": "esp-laundrylights.yaml", - "job_type": "upload", - "status": "completed", - "created_at": "2026-07-25T11:42:27.477003+00:00", - "started_at": "2026-07-25T12:11:46.920991+00:00", - "completed_at": "2026-07-25T12:11:54.928617+00:00", - "compile_started_at": null, - "compile_ended_at": null, - "exit_code": 0, - "error": null, - "port": "OTA", - "flash_bootloader": false, - "is_deferred_install": false, - "new_name": "", - "depends_on": "0afb1a8d93c9", - "dependency_released": true, - "progress": 100, - "remote_peer": "", - "remote_job_id": "", - "remote_peer_label": "", - "device_name": "", - "device_friendly_name": "", - "source": "local", - "source_pin_sha256": "", - "source_label": "", - "source_esphome_version": "", - "target_esphome_version": "", - "failure_reason": "" - }, - { - "job_id": "0afb1a8d93c9", - "configuration": "esp-laundrylights.yaml", - "job_type": "compile", - "status": "completed", - "created_at": "2026-07-25T11:42:27.476965+00:00", - "started_at": "2026-07-25T12:09:05.851989+00:00", - "completed_at": "2026-07-25T12:11:46.919311+00:00", - "compile_started_at": "2026-07-25T12:09:11.089206+00:00", - "compile_ended_at": "2026-07-25T12:11:45.351214+00:00", - "exit_code": 0, - "error": null, - "port": "", - "flash_bootloader": false, - "is_deferred_install": false, - "new_name": "", - "depends_on": "", - "dependency_released": false, - "progress": null, - "remote_peer": "", - "remote_job_id": "", - "remote_peer_label": "", - "device_name": "", - "device_friendly_name": "", - "source": "local", - "source_pin_sha256": "", - "source_label": "", - "source_esphome_version": "", - "target_esphome_version": "", - "failure_reason": "" - }, - { - "job_id": "92fa14b996f8", - "configuration": "esp-garagelights.yaml", - "job_type": "upload", - "status": "completed", - "created_at": "2026-07-25T11:23:58.627930+00:00", - "started_at": "2026-07-25T11:57:31.954235+00:00", - "completed_at": "2026-07-25T11:57:42.819451+00:00", - "compile_started_at": null, - "compile_ended_at": null, - "exit_code": 0, - "error": null, - "port": "OTA", - "flash_bootloader": false, - "is_deferred_install": false, - "new_name": "", - "depends_on": "ae06b5df484f", - "dependency_released": true, - "progress": 100, - "remote_peer": "", - "remote_job_id": "", - "remote_peer_label": "", - "device_name": "", - "device_friendly_name": "", - "source": "local", - "source_pin_sha256": "", - "source_label": "", - "source_esphome_version": "", - "target_esphome_version": "", - "failure_reason": "" - }, - { - "job_id": "ae06b5df484f", - "configuration": "esp-garagelights.yaml", - "job_type": "compile", - "status": "completed", - "created_at": "2026-07-25T11:23:58.627874+00:00", - "started_at": "2026-07-25T11:54:45.774701+00:00", - "completed_at": "2026-07-25T11:57:31.945967+00:00", - "compile_started_at": "2026-07-25T11:54:50.993043+00:00", - "compile_ended_at": "2026-07-25T11:57:30.315431+00:00", - "exit_code": 0, - "error": null, - "port": "", - "flash_bootloader": false, - "is_deferred_install": false, - "new_name": "", - "depends_on": "", - "dependency_released": false, - "progress": null, - "remote_peer": "", - "remote_job_id": "", - "remote_peer_label": "", - "device_name": "", - "device_friendly_name": "", - "source": "local", - "source_pin_sha256": "", - "source_label": "", - "source_esphome_version": "", - "target_esphome_version": "", - "failure_reason": "" - }, - { - "job_id": "fed122f063b8", - "configuration": "esp-garageextcornerlight.yaml", - "job_type": "upload", - "status": "completed", - "created_at": "2026-07-25T11:23:37.818790+00:00", - "started_at": "2026-07-25T11:54:45.765916+00:00", - "completed_at": "2026-07-25T11:54:57.330262+00:00", - "compile_started_at": null, - "compile_ended_at": null, - "exit_code": 0, - "error": null, - "port": "OTA", - "flash_bootloader": false, - "is_deferred_install": false, - "new_name": "", - "depends_on": "239967649f0c", - "dependency_released": true, - "progress": 100, - "remote_peer": "", - "remote_job_id": "", - "remote_peer_label": "", - "device_name": "", - "device_friendly_name": "", - "source": "local", - "source_pin_sha256": "", - "source_label": "", - "source_esphome_version": "", - "target_esphome_version": "", - "failure_reason": "" - }, - { - "job_id": "239967649f0c", - "configuration": "esp-garageextcornerlight.yaml", - "job_type": "compile", - "status": "completed", - "created_at": "2026-07-25T11:23:37.818748+00:00", - "started_at": "2026-07-25T11:52:02.616974+00:00", - "completed_at": "2026-07-25T11:54:45.763153+00:00", - "compile_started_at": "2026-07-25T11:52:08.067710+00:00", - "compile_ended_at": "2026-07-25T11:54:44.227714+00:00", - "exit_code": 0, - "error": null, - "port": "", - "flash_bootloader": false, - "is_deferred_install": false, - "new_name": "", - "depends_on": "", - "dependency_released": false, - "progress": null, - "remote_peer": "", - "remote_job_id": "", - "remote_peer_label": "", - "device_name": "", - "device_friendly_name": "", - "source": "local", - "source_pin_sha256": "", - "source_label": "", - "source_esphome_version": "", - "target_esphome_version": "", - "failure_reason": "" - }, - { - "job_id": "5e6dca1eea0c", - "configuration": "esp-flysprayer1.yaml", - "job_type": "upload", - "status": "completed", - "created_at": "2026-07-25T11:23:10.441682+00:00", - "started_at": "2026-07-25T11:52:02.604165+00:00", - "completed_at": "2026-07-25T11:52:18.038289+00:00", - "compile_started_at": null, - "compile_ended_at": null, - "exit_code": 0, - "error": null, - "port": "OTA", - "flash_bootloader": false, - "is_deferred_install": false, - "new_name": "", - "depends_on": "b98b6d69f47c", - "dependency_released": true, - "progress": 100, - "remote_peer": "", - "remote_job_id": "", - "remote_peer_label": "", - "device_name": "", - "device_friendly_name": "", - "source": "local", - "source_pin_sha256": "", - "source_label": "", - "source_esphome_version": "", - "target_esphome_version": "", - "failure_reason": "" - }, - { - "job_id": "b98b6d69f47c", - "configuration": "esp-flysprayer1.yaml", - "job_type": "compile", - "status": "completed", - "created_at": "2026-07-25T11:23:10.441637+00:00", - "started_at": "2026-07-25T11:48:52.216883+00:00", - "completed_at": "2026-07-25T11:52:02.601289+00:00", - "compile_started_at": "2026-07-25T11:48:58.131852+00:00", - "compile_ended_at": "2026-07-25T11:52:00.977631+00:00", - "exit_code": 0, - "error": null, - "port": "", - "flash_bootloader": false, - "is_deferred_install": false, - "new_name": "", - "depends_on": "", - "dependency_released": false, - "progress": null, - "remote_peer": "", - "remote_job_id": "", - "remote_peer_label": "", - "device_name": "", - "device_friendly_name": "", - "source": "local", - "source_pin_sha256": "", - "source_label": "", - "source_esphome_version": "", - "target_esphome_version": "", - "failure_reason": "" - }, - { - "job_id": "579468678ae9", - "configuration": "esp-laundryplugpow.yaml", - "job_type": "upload", - "status": "completed", - "created_at": "2026-07-25T11:22:54.547876+00:00", - "started_at": "2026-07-25T11:48:52.199754+00:00", - "completed_at": "2026-07-25T11:49:01.695295+00:00", - "compile_started_at": null, - "compile_ended_at": null, - "exit_code": 0, - "error": null, - "port": "OTA", - "flash_bootloader": false, - "is_deferred_install": false, - "new_name": "", - "depends_on": "0d3c47765694", - "dependency_released": true, - "progress": 100, - "remote_peer": "", - "remote_job_id": "", - "remote_peer_label": "", - "device_name": "", - "device_friendly_name": "", - "source": "local", - "source_pin_sha256": "", - "source_label": "", - "source_esphome_version": "", - "target_esphome_version": "", - "failure_reason": "" - }, - { - "job_id": "0d3c47765694", - "configuration": "esp-laundryplugpow.yaml", - "job_type": "compile", - "status": "completed", - "created_at": "2026-07-25T11:22:54.547834+00:00", - "started_at": "2026-07-25T11:45:52.764061+00:00", - "completed_at": "2026-07-25T11:48:52.197621+00:00", - "compile_started_at": "2026-07-25T11:45:58.046406+00:00", - "compile_ended_at": "2026-07-25T11:48:50.619246+00:00", - "exit_code": 0, - "error": null, - "port": "", - "flash_bootloader": false, - "is_deferred_install": false, - "new_name": "", - "depends_on": "", - "dependency_released": false, - "progress": null, - "remote_peer": "", - "remote_job_id": "", - "remote_peer_label": "", - "device_name": "", - "device_friendly_name": "", - "source": "local", - "source_pin_sha256": "", - "source_label": "", - "source_esphome_version": "", - "target_esphome_version": "", - "failure_reason": "" - }, - { - "job_id": "075463221147", - "configuration": "esp-loungenorthswitch.yaml", - "job_type": "upload", - "status": "completed", - "created_at": "2026-07-25T11:22:45.783147+00:00", - "started_at": "2026-07-25T11:45:52.718667+00:00", - "completed_at": "2026-07-25T11:46:05.021281+00:00", - "compile_started_at": null, - "compile_ended_at": null, - "exit_code": 0, - "error": null, - "port": "OTA", - "flash_bootloader": false, - "is_deferred_install": false, - "new_name": "", - "depends_on": "44b95836f36e", - "dependency_released": true, - "progress": 100, - "remote_peer": "", - "remote_job_id": "", - "remote_peer_label": "", - "device_name": "", - "device_friendly_name": "", - "source": "local", - "source_pin_sha256": "", - "source_label": "", - "source_esphome_version": "", - "target_esphome_version": "", - "failure_reason": "" - }, - { - "job_id": "44b95836f36e", - "configuration": "esp-loungenorthswitch.yaml", - "job_type": "compile", - "status": "completed", - "created_at": "2026-07-25T11:22:45.783111+00:00", - "started_at": "2026-07-25T11:43:06.213038+00:00", - "completed_at": "2026-07-25T11:45:52.716198+00:00", - "compile_started_at": "2026-07-25T11:43:12.216719+00:00", - "compile_ended_at": "2026-07-25T11:45:51.147565+00:00", - "exit_code": 0, - "error": null, - "port": "", - "flash_bootloader": false, - "is_deferred_install": false, - "new_name": "", - "depends_on": "", - "dependency_released": false, - "progress": null, - "remote_peer": "", - "remote_job_id": "", - "remote_peer_label": "", - "device_name": "", - "device_friendly_name": "", - "source": "local", - "source_pin_sha256": "", - "source_label": "", - "source_esphome_version": "", - "target_esphome_version": "", - "failure_reason": "" - }, - { - "job_id": "eae4621badcf", - "configuration": "esp-ledmatrix1.yaml", - "job_type": "upload", - "status": "completed", - "created_at": "2026-07-25T11:22:37.929174+00:00", - "started_at": "2026-07-25T11:43:06.206925+00:00", - "completed_at": "2026-07-25T11:43:26.777777+00:00", - "compile_started_at": null, - "compile_ended_at": null, - "exit_code": 0, - "error": null, - "port": "OTA", - "flash_bootloader": false, - "is_deferred_install": false, - "new_name": "", - "depends_on": "a2dda2562d08", - "dependency_released": true, - "progress": 100, - "remote_peer": "", - "remote_job_id": "", - "remote_peer_label": "", - "device_name": "", - "device_friendly_name": "", - "source": "local", - "source_pin_sha256": "", - "source_label": "", - "source_esphome_version": "", - "target_esphome_version": "", - "failure_reason": "" - }, - { - "job_id": "a2dda2562d08", - "configuration": "esp-ledmatrix1.yaml", - "job_type": "compile", - "status": "completed", - "created_at": "2026-07-25T11:22:37.929134+00:00", - "started_at": "2026-07-25T11:38:16.148477+00:00", - "completed_at": "2026-07-25T11:43:06.204036+00:00", - "compile_started_at": "2026-07-25T11:38:32.381123+00:00", - "compile_ended_at": "2026-07-25T11:43:05.902233+00:00", - "exit_code": 0, - "error": null, - "port": "", - "flash_bootloader": false, - "is_deferred_install": false, - "new_name": "", - "depends_on": "", - "dependency_released": false, - "progress": 99, - "remote_peer": "", - "remote_job_id": "", - "remote_peer_label": "", - "device_name": "", - "device_friendly_name": "", - "source": "local", - "source_pin_sha256": "", - "source_label": "", - "source_esphome_version": "", - "target_esphome_version": "", - "failure_reason": "" - }, - { - "job_id": "ff7454740258", - "configuration": "esp-laundryenv.yaml", - "job_type": "upload", - "status": "completed", - "created_at": "2026-07-25T11:22:31.285016+00:00", - "started_at": "2026-07-25T11:38:16.141194+00:00", - "completed_at": "2026-07-25T11:38:25.438028+00:00", - "compile_started_at": null, - "compile_ended_at": null, - "exit_code": 0, - "error": null, - "port": "OTA", - "flash_bootloader": false, - "is_deferred_install": false, - "new_name": "", - "depends_on": "f4f853cd741c", - "dependency_released": true, - "progress": 100, - "remote_peer": "", - "remote_job_id": "", - "remote_peer_label": "", - "device_name": "", - "device_friendly_name": "", - "source": "local", - "source_pin_sha256": "", - "source_label": "", - "source_esphome_version": "", - "target_esphome_version": "", - "failure_reason": "" - }, - { - "job_id": "f4f853cd741c", - "configuration": "esp-laundryenv.yaml", - "job_type": "compile", - "status": "completed", - "created_at": "2026-07-25T11:22:31.284976+00:00", - "started_at": "2026-07-25T11:35:32.592505+00:00", - "completed_at": "2026-07-25T11:38:16.139010+00:00", - "compile_started_at": "2026-07-25T11:35:37.877656+00:00", - "compile_ended_at": "2026-07-25T11:38:14.623513+00:00", - "exit_code": 0, - "error": null, - "port": "", - "flash_bootloader": false, - "is_deferred_install": false, - "new_name": "", - "depends_on": "", - "dependency_released": false, - "progress": null, - "remote_peer": "", - "remote_job_id": "", - "remote_peer_label": "", - "device_name": "", - "device_friendly_name": "", - "source": "local", - "source_pin_sha256": "", - "source_label": "", - "source_esphome_version": "", - "target_esphome_version": "", - "failure_reason": "" - }, - { - "job_id": "43fec9daa172", - "configuration": "esp-loungesouthleftswitch.yaml", - "job_type": "upload", - "status": "completed", - "created_at": "2026-07-25T11:22:02.920864+00:00", - "started_at": "2026-07-25T11:35:32.585255+00:00", - "completed_at": "2026-07-25T11:35:43.875817+00:00", - "compile_started_at": null, - "compile_ended_at": null, - "exit_code": 0, - "error": null, - "port": "OTA", - "flash_bootloader": false, - "is_deferred_install": false, - "new_name": "", - "depends_on": "4282fd683dc7", - "dependency_released": true, - "progress": 100, - "remote_peer": "", - "remote_job_id": "", - "remote_peer_label": "", - "device_name": "", - "device_friendly_name": "", - "source": "local", - "source_pin_sha256": "", - "source_label": "", - "source_esphome_version": "", - "target_esphome_version": "", - "failure_reason": "" - }, - { - "job_id": "4282fd683dc7", - "configuration": "esp-loungesouthleftswitch.yaml", - "job_type": "compile", - "status": "completed", - "created_at": "2026-07-25T11:22:02.920824+00:00", - "started_at": "2026-07-25T11:32:48.973935+00:00", - "completed_at": "2026-07-25T11:35:32.582652+00:00", - "compile_started_at": "2026-07-25T11:32:54.339070+00:00", - "compile_ended_at": "2026-07-25T11:35:31.050514+00:00", - "exit_code": 0, - "error": null, - "port": "", - "flash_bootloader": false, - "is_deferred_install": false, - "new_name": "", - "depends_on": "", - "dependency_released": false, - "progress": null, - "remote_peer": "", - "remote_job_id": "", - "remote_peer_label": "", - "device_name": "", - "device_friendly_name": "", - "source": "local", - "source_pin_sha256": "", - "source_label": "", - "source_esphome_version": "", - "target_esphome_version": "", - "failure_reason": "" - }, - { - "job_id": "d6d01e791e4b", - "configuration": "esp-loungewestswitch.yaml", - "job_type": "upload", - "status": "completed", - "created_at": "2026-07-25T10:29:41.202972+00:00", - "started_at": "2026-07-25T11:30:09.889827+00:00", - "completed_at": "2026-07-25T11:30:21.142827+00:00", - "compile_started_at": null, - "compile_ended_at": null, - "exit_code": 0, - "error": null, - "port": "OTA", - "flash_bootloader": false, - "is_deferred_install": false, - "new_name": "", - "depends_on": "36ea97001595", - "dependency_released": true, - "progress": 100, - "remote_peer": "", - "remote_job_id": "", - "remote_peer_label": "", - "device_name": "", - "device_friendly_name": "", - "source": "local", - "source_pin_sha256": "", - "source_label": "", - "source_esphome_version": "", - "target_esphome_version": "", - "failure_reason": "" - }, - { - "job_id": "36ea97001595", - "configuration": "esp-loungewestswitch.yaml", - "job_type": "compile", - "status": "completed", - "created_at": "2026-07-25T10:29:41.202936+00:00", - "started_at": "2026-07-25T11:27:23.088206+00:00", - "completed_at": "2026-07-25T11:30:09.887213+00:00", - "compile_started_at": "2026-07-25T11:27:28.517906+00:00", - "compile_ended_at": "2026-07-25T11:30:08.075770+00:00", - "exit_code": 0, - "error": null, - "port": "", - "flash_bootloader": false, - "is_deferred_install": false, - "new_name": "", - "depends_on": "", - "dependency_released": false, - "progress": null, - "remote_peer": "", - "remote_job_id": "", - "remote_peer_label": "", - "device_name": "", - "device_friendly_name": "", - "source": "local", - "source_pin_sha256": "", - "source_label": "", - "source_esphome_version": "", - "target_esphome_version": "", - "failure_reason": "" - }, - { - "job_id": "e686679d06e7", - "configuration": "esp-mainbathfancombo.yaml", - "job_type": "upload", - "status": "completed", - "created_at": "2026-07-25T10:29:35.311737+00:00", - "started_at": "2026-07-25T11:27:23.082826+00:00", - "completed_at": "2026-07-25T11:27:34.680374+00:00", - "compile_started_at": null, - "compile_ended_at": null, - "exit_code": 0, - "error": null, - "port": "OTA", - "flash_bootloader": false, - "is_deferred_install": false, - "new_name": "", - "depends_on": "ac4c92b99823", - "dependency_released": true, - "progress": 100, - "remote_peer": "", - "remote_job_id": "", - "remote_peer_label": "", - "device_name": "", - "device_friendly_name": "", - "source": "local", - "source_pin_sha256": "", - "source_label": "", - "source_esphome_version": "", - "target_esphome_version": "", - "failure_reason": "" - }, - { - "job_id": "ac4c92b99823", - "configuration": "esp-mainbathfancombo.yaml", - "job_type": "compile", - "status": "completed", - "created_at": "2026-07-25T10:29:35.311695+00:00", - "started_at": "2026-07-25T11:24:34.866947+00:00", - "completed_at": "2026-07-25T11:27:23.079104+00:00", - "compile_started_at": "2026-07-25T11:24:44.122481+00:00", - "compile_ended_at": "2026-07-25T11:27:21.560400+00:00", - "exit_code": 0, - "error": null, - "port": "", - "flash_bootloader": false, - "is_deferred_install": false, - "new_name": "", - "depends_on": "", - "dependency_released": false, - "progress": null, - "remote_peer": "", - "remote_job_id": "", - "remote_peer_label": "", - "device_name": "", - "device_friendly_name": "", - "source": "local", - "source_pin_sha256": "", - "source_label": "", - "source_esphome_version": "", - "target_esphome_version": "", - "failure_reason": "" - }, - { - "job_id": "284fe8c1436b", - "configuration": "esp-mainbathroomlights.yaml", - "job_type": "upload", - "status": "completed", - "created_at": "2026-07-25T10:29:26.316177+00:00", - "started_at": "2026-07-25T11:24:34.836144+00:00", - "completed_at": "2026-07-25T11:24:56.271152+00:00", - "compile_started_at": null, - "compile_ended_at": null, - "exit_code": 0, - "error": null, - "port": "OTA", - "flash_bootloader": false, - "is_deferred_install": false, - "new_name": "", - "depends_on": "4745762e0834", - "dependency_released": true, - "progress": 100, - "remote_peer": "", - "remote_job_id": "", - "remote_peer_label": "", - "device_name": "", - "device_friendly_name": "", - "source": "local", - "source_pin_sha256": "", - "source_label": "", - "source_esphome_version": "", - "target_esphome_version": "", - "failure_reason": "" - }, - { - "job_id": "4745762e0834", - "configuration": "esp-mainbathroomlights.yaml", - "job_type": "compile", - "status": "completed", - "created_at": "2026-07-25T10:29:26.316139+00:00", - "started_at": "2026-07-25T11:21:24.163571+00:00", - "completed_at": "2026-07-25T11:24:34.832630+00:00", - "compile_started_at": "2026-07-25T11:21:39.585414+00:00", - "compile_ended_at": "2026-07-25T11:24:32.163714+00:00", - "exit_code": 0, - "error": null, - "port": "", - "flash_bootloader": false, - "is_deferred_install": false, - "new_name": "", - "depends_on": "", - "dependency_released": false, - "progress": null, - "remote_peer": "", - "remote_job_id": "", - "remote_peer_label": "", - "device_name": "", - "device_friendly_name": "", - "source": "local", - "source_pin_sha256": "", - "source_label": "", - "source_esphome_version": "", - "target_esphome_version": "", - "failure_reason": "" - }, - { - "job_id": "6a9910c117c0", - "configuration": "esp-entrancelightswitch.yaml", - "job_type": "upload", - "status": "completed", - "created_at": "2026-07-25T10:29:19.905740+00:00", - "started_at": "2026-07-25T11:21:24.154296+00:00", - "completed_at": "2026-07-25T11:21:34.701233+00:00", - "compile_started_at": null, - "compile_ended_at": null, - "exit_code": 0, - "error": null, - "port": "OTA", - "flash_bootloader": false, - "is_deferred_install": false, - "new_name": "", - "depends_on": "971feff08399", - "dependency_released": true, - "progress": 100, - "remote_peer": "", - "remote_job_id": "", - "remote_peer_label": "", - "device_name": "", - "device_friendly_name": "", - "source": "local", - "source_pin_sha256": "", - "source_label": "", - "source_esphome_version": "", - "target_esphome_version": "", - "failure_reason": "" - }, - { - "job_id": "971feff08399", - "configuration": "esp-entrancelightswitch.yaml", - "job_type": "compile", - "status": "completed", - "created_at": "2026-07-25T10:29:19.905690+00:00", - "started_at": "2026-07-25T11:18:42.314688+00:00", - "completed_at": "2026-07-25T11:21:24.151475+00:00", - "compile_started_at": "2026-07-25T11:18:47.601851+00:00", - "compile_ended_at": "2026-07-25T11:21:22.608953+00:00", - "exit_code": 0, - "error": null, - "port": "", - "flash_bootloader": false, - "is_deferred_install": false, - "new_name": "", - "depends_on": "", - "dependency_released": false, - "progress": null, - "remote_peer": "", - "remote_job_id": "", - "remote_peer_label": "", - "device_name": "", - "device_friendly_name": "", - "source": "local", - "source_pin_sha256": "", - "source_label": "", - "source_esphome_version": "", - "target_esphome_version": "", - "failure_reason": "" - }, - { - "job_id": "a1155e49d194", - "configuration": "esp-mainhallwaymainlights.yaml", - "job_type": "upload", - "status": "completed", - "created_at": "2026-07-25T10:29:08.259049+00:00", - "started_at": "2026-07-25T11:18:42.303701+00:00", - "completed_at": "2026-07-25T11:18:50.903983+00:00", - "compile_started_at": null, - "compile_ended_at": null, - "exit_code": 0, - "error": null, - "port": "OTA", - "flash_bootloader": false, - "is_deferred_install": false, - "new_name": "", - "depends_on": "ea01dcbf4b9b", - "dependency_released": true, - "progress": 100, - "remote_peer": "", - "remote_job_id": "", - "remote_peer_label": "", - "device_name": "", - "device_friendly_name": "", - "source": "local", - "source_pin_sha256": "", - "source_label": "", - "source_esphome_version": "", - "target_esphome_version": "", - "failure_reason": "" - }, - { - "job_id": "ea01dcbf4b9b", - "configuration": "esp-mainhallwaymainlights.yaml", - "job_type": "compile", - "status": "completed", - "created_at": "2026-07-25T10:29:08.258997+00:00", - "started_at": "2026-07-25T11:16:03.838953+00:00", - "completed_at": "2026-07-25T11:18:42.300882+00:00", - "compile_started_at": "2026-07-25T11:16:09.414274+00:00", - "compile_ended_at": "2026-07-25T11:18:40.729243+00:00", - "exit_code": 0, - "error": null, - "port": "", - "flash_bootloader": false, - "is_deferred_install": false, - "new_name": "", - "depends_on": "", - "dependency_released": false, - "progress": null, - "remote_peer": "", - "remote_job_id": "", - "remote_peer_label": "", - "device_name": "", - "device_friendly_name": "", - "source": "local", - "source_pin_sha256": "", - "source_label": "", - "source_esphome_version": "", - "target_esphome_version": "", - "failure_reason": "" - }, - { - "job_id": "288a4d3685c7", - "configuration": "esp-mainhallwaynightlights.yaml", - "job_type": "upload", - "status": "completed", - "created_at": "2026-07-25T10:29:00.874023+00:00", - "started_at": "2026-07-25T11:16:03.830461+00:00", - "completed_at": "2026-07-25T11:16:27.192321+00:00", - "compile_started_at": null, - "compile_ended_at": null, - "exit_code": 0, - "error": null, - "port": "OTA", - "flash_bootloader": false, - "is_deferred_install": false, - "new_name": "", - "depends_on": "51c7242e8d94", - "dependency_released": true, - "progress": 100, - "remote_peer": "", - "remote_job_id": "", - "remote_peer_label": "", - "device_name": "", - "device_friendly_name": "", - "source": "local", - "source_pin_sha256": "", - "source_label": "", - "source_esphome_version": "", - "target_esphome_version": "", - "failure_reason": "" - }, - { - "job_id": "51c7242e8d94", - "configuration": "esp-mainhallwaynightlights.yaml", - "job_type": "compile", - "status": "completed", - "created_at": "2026-07-25T10:29:00.873980+00:00", - "started_at": "2026-07-25T11:11:56.765645+00:00", - "completed_at": "2026-07-25T11:16:03.825764+00:00", - "compile_started_at": "2026-07-25T11:12:57.007311+00:00", - "compile_ended_at": "2026-07-25T11:16:01.204480+00:00", - "exit_code": 0, - "error": null, - "port": "", - "flash_bootloader": false, - "is_deferred_install": false, - "new_name": "", - "depends_on": "", - "dependency_released": false, - "progress": null, - "remote_peer": "", - "remote_job_id": "", - "remote_peer_label": "", - "device_name": "", - "device_friendly_name": "", - "source": "local", - "source_pin_sha256": "", - "source_label": "", - "source_esphome_version": "", - "target_esphome_version": "", - "failure_reason": "" - }, - { - "job_id": "be88d02d6953", - "configuration": "esp-mainhallwaynorthlightswitch.yaml", - "job_type": "upload", - "status": "completed", - "created_at": "2026-07-25T10:28:53.291993+00:00", - "started_at": "2026-07-25T11:11:56.757251+00:00", - "completed_at": "2026-07-25T11:12:07.995815+00:00", - "compile_started_at": null, - "compile_ended_at": null, - "exit_code": 0, - "error": null, - "port": "OTA", - "flash_bootloader": false, - "is_deferred_install": false, - "new_name": "", - "depends_on": "d1d29ba8b799", - "dependency_released": true, - "progress": 100, - "remote_peer": "", - "remote_job_id": "", - "remote_peer_label": "", - "device_name": "", - "device_friendly_name": "", - "source": "local", - "source_pin_sha256": "", - "source_label": "", - "source_esphome_version": "", - "target_esphome_version": "", - "failure_reason": "" - }, - { - "job_id": "d1d29ba8b799", - "configuration": "esp-mainhallwaynorthlightswitch.yaml", - "job_type": "compile", - "status": "completed", - "created_at": "2026-07-25T10:28:53.291955+00:00", - "started_at": "2026-07-25T11:09:03.648698+00:00", - "completed_at": "2026-07-25T11:11:56.752853+00:00", - "compile_started_at": "2026-07-25T11:09:09.240937+00:00", - "compile_ended_at": "2026-07-25T11:11:55.124735+00:00", - "exit_code": 0, - "error": null, - "port": "", - "flash_bootloader": false, - "is_deferred_install": false, - "new_name": "", - "depends_on": "", - "dependency_released": false, - "progress": null, - "remote_peer": "", - "remote_job_id": "", - "remote_peer_label": "", - "device_name": "", - "device_friendly_name": "", - "source": "local", - "source_pin_sha256": "", - "source_label": "", - "source_esphome_version": "", - "target_esphome_version": "", - "failure_reason": "" - }, - { - "job_id": "b8aea995bcba", - "configuration": "esp-mainkitchenlights.yaml", - "job_type": "upload", - "status": "completed", - "created_at": "2026-07-25T10:28:43.961933+00:00", - "started_at": "2026-07-25T11:09:03.638724+00:00", - "completed_at": "2026-07-25T11:09:12.630586+00:00", - "compile_started_at": null, - "compile_ended_at": null, - "exit_code": 0, - "error": null, - "port": "OTA", - "flash_bootloader": false, - "is_deferred_install": false, - "new_name": "", - "depends_on": "b7e24a5e88af", - "dependency_released": true, - "progress": 100, - "remote_peer": "", - "remote_job_id": "", - "remote_peer_label": "", - "device_name": "", - "device_friendly_name": "", - "source": "local", - "source_pin_sha256": "", - "source_label": "", - "source_esphome_version": "", - "target_esphome_version": "", - "failure_reason": "" - }, - { - "job_id": "b7e24a5e88af", - "configuration": "esp-mainkitchenlights.yaml", - "job_type": "compile", - "status": "completed", - "created_at": "2026-07-25T10:28:43.961895+00:00", - "started_at": "2026-07-25T11:06:10.703139+00:00", - "completed_at": "2026-07-25T11:09:03.635242+00:00", - "compile_started_at": "2026-07-25T11:06:15.819449+00:00", - "compile_ended_at": "2026-07-25T11:09:01.953213+00:00", - "exit_code": 0, - "error": null, - "port": "", - "flash_bootloader": false, - "is_deferred_install": false, - "new_name": "", - "depends_on": "", - "dependency_released": false, - "progress": null, - "remote_peer": "", - "remote_job_id": "", - "remote_peer_label": "", - "device_name": "", - "device_friendly_name": "", - "source": "local", - "source_pin_sha256": "", - "source_label": "", - "source_esphome_version": "", - "target_esphome_version": "", - "failure_reason": "" - }, - { - "job_id": "bdf395fc6f89", - "configuration": "esp-underhouselights.yaml", - "job_type": "upload", - "status": "completed", - "created_at": "2026-07-25T10:28:11.606696+00:00", - "started_at": "2026-07-25T11:04:19.438618+00:00", - "completed_at": "2026-07-25T11:04:36.332547+00:00", - "compile_started_at": null, - "compile_ended_at": null, - "exit_code": 0, - "error": null, - "port": "OTA", - "flash_bootloader": false, - "is_deferred_install": false, - "new_name": "", - "depends_on": "3a5f319c95aa", - "dependency_released": true, - "progress": 100, - "remote_peer": "", - "remote_job_id": "", - "remote_peer_label": "", - "device_name": "", - "device_friendly_name": "", - "source": "local", - "source_pin_sha256": "", - "source_label": "", - "source_esphome_version": "", - "target_esphome_version": "", - "failure_reason": "" - }, - { - "job_id": "3a5f319c95aa", - "configuration": "esp-underhouselights.yaml", - "job_type": "compile", - "status": "completed", - "created_at": "2026-07-25T10:28:11.606651+00:00", - "started_at": "2026-07-25T11:01:03.037913+00:00", - "completed_at": "2026-07-25T11:04:19.435863+00:00", - "compile_started_at": "2026-07-25T11:01:08.298121+00:00", - "compile_ended_at": "2026-07-25T11:04:17.643824+00:00", - "exit_code": 0, - "error": null, - "port": "", - "flash_bootloader": false, - "is_deferred_install": false, - "new_name": "", - "depends_on": "", - "dependency_released": false, - "progress": null, - "remote_peer": "", - "remote_job_id": "", - "remote_peer_label": "", - "device_name": "", - "device_friendly_name": "", - "source": "local", - "source_pin_sha256": "", - "source_label": "", - "source_esphome_version": "", - "target_esphome_version": "", - "failure_reason": "" - }, - { - "job_id": "b308e124fcfd", - "configuration": "esp-downstmasterbedrmlights.yaml", - "job_type": "upload", - "status": "completed", - "created_at": "2026-07-25T10:27:17.339077+00:00", - "started_at": "2026-07-25T11:01:03.035651+00:00", - "completed_at": "2026-07-25T11:01:13.038597+00:00", - "compile_started_at": null, - "compile_ended_at": null, - "exit_code": 0, - "error": null, - "port": "OTA", - "flash_bootloader": false, - "is_deferred_install": false, - "new_name": "", - "depends_on": "380b2537729e", - "dependency_released": true, - "progress": 100, - "remote_peer": "", - "remote_job_id": "", - "remote_peer_label": "", - "device_name": "", - "device_friendly_name": "", - "source": "local", - "source_pin_sha256": "", - "source_label": "", - "source_esphome_version": "", - "target_esphome_version": "", - "failure_reason": "" - }, - { - "job_id": "380b2537729e", - "configuration": "esp-downstmasterbedrmlights.yaml", - "job_type": "compile", - "status": "completed", - "created_at": "2026-07-25T10:27:17.339038+00:00", - "started_at": "2026-07-25T10:58:06.867597+00:00", - "completed_at": "2026-07-25T11:01:03.017436+00:00", - "compile_started_at": "2026-07-25T10:58:12.635913+00:00", - "compile_ended_at": "2026-07-25T11:01:01.447532+00:00", - "exit_code": 0, - "error": null, - "port": "", - "flash_bootloader": false, - "is_deferred_install": false, - "new_name": "", - "depends_on": "", - "dependency_released": false, - "progress": null, - "remote_peer": "", - "remote_job_id": "", - "remote_peer_label": "", - "device_name": "", - "device_friendly_name": "", - "source": "local", - "source_pin_sha256": "", - "source_label": "", - "source_esphome_version": "", - "target_esphome_version": "", - "failure_reason": "" - }, - { - "job_id": "d0738227332f", - "configuration": "esp-downstkitchlights.yaml", - "job_type": "upload", - "status": "completed", - "created_at": "2026-07-25T10:27:00.779224+00:00", - "started_at": "2026-07-25T10:58:06.863627+00:00", - "completed_at": "2026-07-25T10:58:16.338854+00:00", - "compile_started_at": null, - "compile_ended_at": null, - "exit_code": 0, - "error": null, - "port": "OTA", - "flash_bootloader": false, - "is_deferred_install": false, - "new_name": "", - "depends_on": "4b0216f0dedd", - "dependency_released": true, - "progress": 100, - "remote_peer": "", - "remote_job_id": "", - "remote_peer_label": "", - "device_name": "", - "device_friendly_name": "", - "source": "local", - "source_pin_sha256": "", - "source_label": "", - "source_esphome_version": "", - "target_esphome_version": "", - "failure_reason": "" - }, - { - "job_id": "4b0216f0dedd", - "configuration": "esp-downstkitchlights.yaml", - "job_type": "compile", - "status": "completed", - "created_at": "2026-07-25T10:27:00.779184+00:00", - "started_at": "2026-07-25T10:55:08.356491+00:00", - "completed_at": "2026-07-25T10:58:06.853988+00:00", - "compile_started_at": "2026-07-25T10:55:11.858941+00:00", - "compile_ended_at": "2026-07-25T10:58:05.262726+00:00", - "exit_code": 0, - "error": null, - "port": "", - "flash_bootloader": false, - "is_deferred_install": false, - "new_name": "", - "depends_on": "", - "dependency_released": false, - "progress": null, - "remote_peer": "", - "remote_job_id": "", - "remote_peer_label": "", - "device_name": "", - "device_friendly_name": "", - "source": "local", - "source_pin_sha256": "", - "source_label": "", - "source_esphome_version": "", - "target_esphome_version": "", - "failure_reason": "" - }, - { - "job_id": "114cdccfe5a1", - "configuration": "esp-downstairsdishwasher.yaml", - "job_type": "upload", - "status": "completed", - "created_at": "2026-07-25T10:26:45.783076+00:00", - "started_at": "2026-07-25T10:51:49.623004+00:00", - "completed_at": "2026-07-25T10:51:59.714141+00:00", - "compile_started_at": null, - "compile_ended_at": null, - "exit_code": 0, - "error": null, - "port": "OTA", - "flash_bootloader": false, - "is_deferred_install": false, - "new_name": "", - "depends_on": "94bff4ee205b", - "dependency_released": true, - "progress": 100, - "remote_peer": "", - "remote_job_id": "", - "remote_peer_label": "", - "device_name": "", - "device_friendly_name": "", - "source": "local", - "source_pin_sha256": "", - "source_label": "", - "source_esphome_version": "", - "target_esphome_version": "", - "failure_reason": "" - }, - { - "job_id": "94bff4ee205b", - "configuration": "esp-downstairsdishwasher.yaml", - "job_type": "compile", - "status": "completed", - "created_at": "2026-07-25T10:26:45.783027+00:00", - "started_at": "2026-07-25T10:48:46.227487+00:00", - "completed_at": "2026-07-25T10:51:49.620802+00:00", - "compile_started_at": "2026-07-25T10:48:52.059073+00:00", - "compile_ended_at": "2026-07-25T10:51:47.944309+00:00", - "exit_code": 0, - "error": null, - "port": "", - "flash_bootloader": false, - "is_deferred_install": false, - "new_name": "", - "depends_on": "", - "dependency_released": false, - "progress": null, - "remote_peer": "", - "remote_job_id": "", - "remote_peer_label": "", - "device_name": "", - "device_friendly_name": "", - "source": "local", - "source_pin_sha256": "", - "source_label": "", - "source_esphome_version": "", - "target_esphome_version": "", - "failure_reason": "" - }, - { - "job_id": "7a3f6cbf0f61", - "configuration": "esp-downstbedrm2lights.yaml", - "job_type": "upload", - "status": "completed", - "created_at": "2026-07-25T10:26:37.185488+00:00", - "started_at": "2026-07-25T10:48:46.224836+00:00", - "completed_at": "2026-07-25T10:48:56.832949+00:00", - "compile_started_at": null, - "compile_ended_at": null, - "exit_code": 0, - "error": null, - "port": "OTA", - "flash_bootloader": false, - "is_deferred_install": false, - "new_name": "", - "depends_on": "1541d20d3796", - "dependency_released": true, - "progress": 100, - "remote_peer": "", - "remote_job_id": "", - "remote_peer_label": "", - "device_name": "", - "device_friendly_name": "", - "source": "local", - "source_pin_sha256": "", - "source_label": "", - "source_esphome_version": "", - "target_esphome_version": "", - "failure_reason": "" - }, - { - "job_id": "1541d20d3796", - "configuration": "esp-downstbedrm2lights.yaml", - "job_type": "compile", - "status": "completed", - "created_at": "2026-07-25T10:26:37.185452+00:00", - "started_at": "2026-07-25T10:45:52.062299+00:00", - "completed_at": "2026-07-25T10:48:46.217807+00:00", - "compile_started_at": "2026-07-25T10:45:57.542332+00:00", - "compile_ended_at": "2026-07-25T10:48:44.556184+00:00", - "exit_code": 0, - "error": null, - "port": "", - "flash_bootloader": false, - "is_deferred_install": false, - "new_name": "", - "depends_on": "", - "dependency_released": false, - "progress": null, - "remote_peer": "", - "remote_job_id": "", - "remote_peer_label": "", - "device_name": "", - "device_friendly_name": "", - "source": "local", - "source_pin_sha256": "", - "source_label": "", - "source_esphome_version": "", - "target_esphome_version": "", - "failure_reason": "" - }, { "job_id": "f646f488d5a7", "configuration": "esp-downstbathtowelrail.yaml", @@ -4439,626 +5059,6 @@ "target_esphome_version": "", "failure_reason": "" }, - { - "job_id": "4433db694627", - "configuration": "esp-downstbathswitch.yaml", - "job_type": "upload", - "status": "completed", - "created_at": "2026-07-25T10:21:44.479200+00:00", - "started_at": "2026-07-25T10:40:18.298723+00:00", - "completed_at": "2026-07-25T10:40:28.425729+00:00", - "compile_started_at": null, - "compile_ended_at": null, - "exit_code": 0, - "error": null, - "port": "OTA", - "flash_bootloader": false, - "is_deferred_install": false, - "new_name": "", - "depends_on": "9d00229a4133", - "dependency_released": true, - "progress": 100, - "remote_peer": "", - "remote_job_id": "", - "remote_peer_label": "", - "device_name": "", - "device_friendly_name": "", - "source": "local", - "source_pin_sha256": "", - "source_label": "", - "source_esphome_version": "", - "target_esphome_version": "", - "failure_reason": "" - }, - { - "job_id": "9d00229a4133", - "configuration": "esp-downstbathswitch.yaml", - "job_type": "compile", - "status": "completed", - "created_at": "2026-07-25T10:21:44.479099+00:00", - "started_at": "2026-07-25T10:37:31.454824+00:00", - "completed_at": "2026-07-25T10:40:18.296407+00:00", - "compile_started_at": "2026-07-25T10:37:37.001764+00:00", - "compile_ended_at": "2026-07-25T10:40:16.753291+00:00", - "exit_code": 0, - "error": null, - "port": "", - "flash_bootloader": false, - "is_deferred_install": false, - "new_name": "", - "depends_on": "", - "dependency_released": false, - "progress": null, - "remote_peer": "", - "remote_job_id": "", - "remote_peer_label": "", - "device_name": "", - "device_friendly_name": "", - "source": "local", - "source_pin_sha256": "", - "source_label": "", - "source_esphome_version": "", - "target_esphome_version": "", - "failure_reason": "" - }, - { - "job_id": "9ffdf3f719fc", - "configuration": "esp-bedrm3fanswitch.yaml", - "job_type": "upload", - "status": "completed", - "created_at": "2026-07-25T10:21:17.175253+00:00", - "started_at": "2026-07-25T10:37:31.449686+00:00", - "completed_at": "2026-07-25T10:37:42.984618+00:00", - "compile_started_at": null, - "compile_ended_at": null, - "exit_code": 0, - "error": null, - "port": "OTA", - "flash_bootloader": false, - "is_deferred_install": false, - "new_name": "", - "depends_on": "a6d024329932", - "dependency_released": true, - "progress": 100, - "remote_peer": "", - "remote_job_id": "", - "remote_peer_label": "", - "device_name": "", - "device_friendly_name": "", - "source": "local", - "source_pin_sha256": "", - "source_label": "", - "source_esphome_version": "", - "target_esphome_version": "", - "failure_reason": "" - }, - { - "job_id": "a6d024329932", - "configuration": "esp-bedrm3fanswitch.yaml", - "job_type": "compile", - "status": "completed", - "created_at": "2026-07-25T10:21:17.175209+00:00", - "started_at": "2026-07-25T10:34:44.455827+00:00", - "completed_at": "2026-07-25T10:37:31.447016+00:00", - "compile_started_at": "2026-07-25T10:34:50.020314+00:00", - "compile_ended_at": "2026-07-25T10:37:29.877502+00:00", - "exit_code": 0, - "error": null, - "port": "", - "flash_bootloader": false, - "is_deferred_install": false, - "new_name": "", - "depends_on": "", - "dependency_released": false, - "progress": null, - "remote_peer": "", - "remote_job_id": "", - "remote_peer_label": "", - "device_name": "", - "device_friendly_name": "", - "source": "local", - "source_pin_sha256": "", - "source_label": "", - "source_esphome_version": "", - "target_esphome_version": "", - "failure_reason": "" - }, - { - "job_id": "5426487d5ac9", - "configuration": "esp-bedrm2ceilingfan.yaml", - "job_type": "upload", - "status": "completed", - "created_at": "2026-07-25T10:19:23.667762+00:00", - "started_at": "2026-07-25T10:23:06.368076+00:00", - "completed_at": "2026-07-25T10:23:24.052214+00:00", - "compile_started_at": null, - "compile_ended_at": null, - "exit_code": 0, - "error": null, - "port": "OTA", - "flash_bootloader": false, - "is_deferred_install": false, - "new_name": "", - "depends_on": "ff325255551b", - "dependency_released": true, - "progress": 100, - "remote_peer": "", - "remote_job_id": "", - "remote_peer_label": "", - "device_name": "", - "device_friendly_name": "", - "source": "local", - "source_pin_sha256": "", - "source_label": "", - "source_esphome_version": "", - "target_esphome_version": "", - "failure_reason": "" - }, - { - "job_id": "ff325255551b", - "configuration": "esp-bedrm2ceilingfan.yaml", - "job_type": "compile", - "status": "completed", - "created_at": "2026-07-25T10:19:23.666638+00:00", - "started_at": "2026-07-25T10:19:23.668820+00:00", - "completed_at": "2026-07-25T10:23:06.367072+00:00", - "compile_started_at": "2026-07-25T10:19:42.086727+00:00", - "compile_ended_at": "2026-07-25T10:23:04.575028+00:00", - "exit_code": 0, - "error": null, - "port": "", - "flash_bootloader": false, - "is_deferred_install": false, - "new_name": "", - "depends_on": "", - "dependency_released": false, - "progress": null, - "remote_peer": "", - "remote_job_id": "", - "remote_peer_label": "", - "device_name": "", - "device_friendly_name": "", - "source": "local", - "source_pin_sha256": "", - "source_label": "", - "source_esphome_version": "", - "target_esphome_version": "", - "failure_reason": "" - }, - { - "job_id": "368fa5900efc", - "configuration": "esp-downstloungemain.yaml", - "job_type": "upload", - "status": "completed", - "created_at": "2026-07-25T09:18:25.136789+00:00", - "started_at": "2026-07-25T09:18:31.139672+00:00", - "completed_at": "2026-07-25T09:18:41.342746+00:00", - "compile_started_at": null, - "compile_ended_at": null, - "exit_code": 0, - "error": null, - "port": "OTA", - "flash_bootloader": false, - "is_deferred_install": false, - "new_name": "", - "depends_on": "de42d91cdf8c", - "dependency_released": true, - "progress": 100, - "remote_peer": "", - "remote_job_id": "", - "remote_peer_label": "", - "device_name": "", - "device_friendly_name": "", - "source": "local", - "source_pin_sha256": "", - "source_label": "", - "source_esphome_version": "", - "target_esphome_version": "", - "failure_reason": "" - }, - { - "job_id": "de42d91cdf8c", - "configuration": "esp-downstloungemain.yaml", - "job_type": "compile", - "status": "completed", - "created_at": "2026-07-25T09:18:25.136747+00:00", - "started_at": "2026-07-25T09:18:25.138262+00:00", - "completed_at": "2026-07-25T09:18:31.137304+00:00", - "compile_started_at": "2026-07-25T09:18:29.011855+00:00", - "compile_ended_at": "2026-07-25T09:18:30.891212+00:00", - "exit_code": 0, - "error": null, - "port": "", - "flash_bootloader": false, - "is_deferred_install": false, - "new_name": "", - "depends_on": "", - "dependency_released": false, - "progress": null, - "remote_peer": "", - "remote_job_id": "", - "remote_peer_label": "", - "device_name": "", - "device_friendly_name": "", - "source": "local", - "source_pin_sha256": "", - "source_label": "", - "source_esphome_version": "", - "target_esphome_version": "", - "failure_reason": "" - }, - { - "job_id": "2e8cc9a5d9f8", - "configuration": "esp-downstloungeoutside.yaml", - "job_type": "upload", - "status": "completed", - "created_at": "2026-07-25T08:56:39.905820+00:00", - "started_at": "2026-07-25T08:59:18.757106+00:00", - "completed_at": "2026-07-25T08:59:29.648977+00:00", - "compile_started_at": null, - "compile_ended_at": null, - "exit_code": 0, - "error": null, - "port": "OTA", - "flash_bootloader": false, - "is_deferred_install": false, - "new_name": "", - "depends_on": "0cb4c4c31774", - "dependency_released": true, - "progress": 100, - "remote_peer": "", - "remote_job_id": "", - "remote_peer_label": "", - "device_name": "", - "device_friendly_name": "", - "source": "local", - "source_pin_sha256": "", - "source_label": "", - "source_esphome_version": "", - "target_esphome_version": "", - "failure_reason": "" - }, - { - "job_id": "0cb4c4c31774", - "configuration": "esp-downstloungeoutside.yaml", - "job_type": "compile", - "status": "completed", - "created_at": "2026-07-25T08:56:39.905770+00:00", - "started_at": "2026-07-25T08:56:39.906921+00:00", - "completed_at": "2026-07-25T08:59:18.754681+00:00", - "compile_started_at": "2026-07-25T08:56:57.437763+00:00", - "compile_ended_at": "2026-07-25T08:59:17.255674+00:00", - "exit_code": 0, - "error": null, - "port": "", - "flash_bootloader": false, - "is_deferred_install": false, - "new_name": "", - "depends_on": "", - "dependency_released": false, - "progress": null, - "remote_peer": "", - "remote_job_id": "", - "remote_peer_label": "", - "device_name": "", - "device_friendly_name": "", - "source": "local", - "source_pin_sha256": "", - "source_label": "", - "source_esphome_version": "", - "target_esphome_version": "", - "failure_reason": "" - }, - { - "job_id": "ec335d095177", - "configuration": "esp-officedeskrightgpo.yaml", - "job_type": "upload", - "status": "completed", - "created_at": "2026-07-25T05:19:41.294837+00:00", - "started_at": "2026-07-25T05:23:18.903285+00:00", - "completed_at": "2026-07-25T05:23:47.322626+00:00", - "compile_started_at": null, - "compile_ended_at": null, - "exit_code": 0, - "error": null, - "port": "OTA", - "flash_bootloader": false, - "is_deferred_install": false, - "new_name": "", - "depends_on": "9972b18a10e6", - "dependency_released": true, - "progress": 100, - "remote_peer": "", - "remote_job_id": "", - "remote_peer_label": "", - "device_name": "", - "device_friendly_name": "", - "source": "local", - "source_pin_sha256": "", - "source_label": "", - "source_esphome_version": "", - "target_esphome_version": "", - "failure_reason": "" - }, - { - "job_id": "9972b18a10e6", - "configuration": "esp-officedeskrightgpo.yaml", - "job_type": "compile", - "status": "completed", - "created_at": "2026-07-25T05:19:41.294801+00:00", - "started_at": "2026-07-25T05:20:12.830170+00:00", - "completed_at": "2026-07-25T05:23:18.895375+00:00", - "compile_started_at": "2026-07-25T05:20:28.944828+00:00", - "compile_ended_at": "2026-07-25T05:23:17.249251+00:00", - "exit_code": 0, - "error": null, - "port": "", - "flash_bootloader": false, - "is_deferred_install": false, - "new_name": "", - "depends_on": "", - "dependency_released": false, - "progress": null, - "remote_peer": "", - "remote_job_id": "", - "remote_peer_label": "", - "device_name": "", - "device_friendly_name": "", - "source": "local", - "source_pin_sha256": "", - "source_label": "", - "source_esphome_version": "", - "target_esphome_version": "", - "failure_reason": "" - }, - { - "job_id": "ef0afc9d1ee0", - "configuration": "esp-occupancyoffice.yaml", - "job_type": "upload", - "status": "completed", - "created_at": "2026-07-25T05:19:17.384850+00:00", - "started_at": "2026-07-25T05:20:12.786003+00:00", - "completed_at": "2026-07-25T05:20:27.140660+00:00", - "compile_started_at": null, - "compile_ended_at": null, - "exit_code": 0, - "error": null, - "port": "OTA", - "flash_bootloader": false, - "is_deferred_install": false, - "new_name": "", - "depends_on": "b4baef771205", - "dependency_released": true, - "progress": 100, - "remote_peer": "", - "remote_job_id": "", - "remote_peer_label": "", - "device_name": "", - "device_friendly_name": "", - "source": "local", - "source_pin_sha256": "", - "source_label": "", - "source_esphome_version": "", - "target_esphome_version": "", - "failure_reason": "" - }, - { - "job_id": "b4baef771205", - "configuration": "esp-occupancyoffice.yaml", - "job_type": "compile", - "status": "completed", - "created_at": "2026-07-25T05:19:17.384807+00:00", - "started_at": "2026-07-25T05:19:17.389687+00:00", - "completed_at": "2026-07-25T05:20:12.783516+00:00", - "compile_started_at": "2026-07-25T05:19:23.679077+00:00", - "compile_ended_at": "2026-07-25T05:20:12.563844+00:00", - "exit_code": 0, - "error": null, - "port": "", - "flash_bootloader": false, - "is_deferred_install": false, - "new_name": "", - "depends_on": "", - "dependency_released": false, - "progress": 20, - "remote_peer": "", - "remote_job_id": "", - "remote_peer_label": "", - "device_name": "", - "device_friendly_name": "", - "source": "local", - "source_pin_sha256": "", - "source_label": "", - "source_esphome_version": "", - "target_esphome_version": "", - "failure_reason": "" - }, - { - "job_id": "87c80b973409", - "configuration": "esp-officelights.yaml", - "job_type": "upload", - "status": "completed", - "created_at": "2026-07-25T05:18:57.574969+00:00", - "started_at": "2026-07-25T05:19:04.333883+00:00", - "completed_at": "2026-07-25T05:19:12.094550+00:00", - "compile_started_at": null, - "compile_ended_at": null, - "exit_code": 0, - "error": null, - "port": "OTA", - "flash_bootloader": false, - "is_deferred_install": false, - "new_name": "", - "depends_on": "c3445b5ab2cc", - "dependency_released": true, - "progress": 100, - "remote_peer": "", - "remote_job_id": "", - "remote_peer_label": "", - "device_name": "", - "device_friendly_name": "", - "source": "local", - "source_pin_sha256": "", - "source_label": "", - "source_esphome_version": "", - "target_esphome_version": "", - "failure_reason": "" - }, - { - "job_id": "c3445b5ab2cc", - "configuration": "esp-officelights.yaml", - "job_type": "compile", - "status": "completed", - "created_at": "2026-07-25T05:18:57.574921+00:00", - "started_at": "2026-07-25T05:18:57.576848+00:00", - "completed_at": "2026-07-25T05:19:04.322448+00:00", - "compile_started_at": "2026-07-25T05:19:01.947539+00:00", - "compile_ended_at": "2026-07-25T05:19:03.976378+00:00", - "exit_code": 0, - "error": null, - "port": "", - "flash_bootloader": false, - "is_deferred_install": false, - "new_name": "", - "depends_on": "", - "dependency_released": false, - "progress": null, - "remote_peer": "", - "remote_job_id": "", - "remote_peer_label": "", - "device_name": "", - "device_friendly_name": "", - "source": "local", - "source_pin_sha256": "", - "source_label": "", - "source_esphome_version": "", - "target_esphome_version": "", - "failure_reason": "" - }, - { - "job_id": "9f0a5663160c", - "configuration": "esp-officeelvcontrol.yaml", - "job_type": "upload", - "status": "completed", - "created_at": "2026-07-25T01:26:03.547906+00:00", - "started_at": "2026-07-25T01:42:03.911494+00:00", - "completed_at": "2026-07-25T01:42:14.636606+00:00", - "compile_started_at": null, - "compile_ended_at": null, - "exit_code": 0, - "error": null, - "port": "OTA", - "flash_bootloader": false, - "is_deferred_install": false, - "new_name": "", - "depends_on": "a2ebf77ddb76", - "dependency_released": true, - "progress": 100, - "remote_peer": "", - "remote_job_id": "", - "remote_peer_label": "", - "device_name": "", - "device_friendly_name": "", - "source": "local", - "source_pin_sha256": "", - "source_label": "", - "source_esphome_version": "", - "target_esphome_version": "", - "failure_reason": "" - }, - { - "job_id": "a2ebf77ddb76", - "configuration": "esp-officeelvcontrol.yaml", - "job_type": "compile", - "status": "completed", - "created_at": "2026-07-25T01:26:03.547867+00:00", - "started_at": "2026-07-25T01:39:17.986938+00:00", - "completed_at": "2026-07-25T01:42:03.909424+00:00", - "compile_started_at": "2026-07-25T01:39:23.230926+00:00", - "compile_ended_at": "2026-07-25T01:42:02.305431+00:00", - "exit_code": 0, - "error": null, - "port": "", - "flash_bootloader": false, - "is_deferred_install": false, - "new_name": "", - "depends_on": "", - "dependency_released": false, - "progress": null, - "remote_peer": "", - "remote_job_id": "", - "remote_peer_label": "", - "device_name": "", - "device_friendly_name": "", - "source": "local", - "source_pin_sha256": "", - "source_label": "", - "source_esphome_version": "", - "target_esphome_version": "", - "failure_reason": "" - }, - { - "job_id": "2bc064f33dd3", - "configuration": "esp-officeduallights.yaml", - "job_type": "upload", - "status": "completed", - "created_at": "2026-07-25T01:24:42.624918+00:00", - "started_at": "2026-07-25T01:28:15.733299+00:00", - "completed_at": "2026-07-25T01:28:25.638620+00:00", - "compile_started_at": null, - "compile_ended_at": null, - "exit_code": 0, - "error": null, - "port": "OTA", - "flash_bootloader": false, - "is_deferred_install": false, - "new_name": "", - "depends_on": "66dd53872005", - "dependency_released": true, - "progress": 100, - "remote_peer": "", - "remote_job_id": "", - "remote_peer_label": "", - "device_name": "", - "device_friendly_name": "", - "source": "local", - "source_pin_sha256": "", - "source_label": "", - "source_esphome_version": "", - "target_esphome_version": "", - "failure_reason": "" - }, - { - "job_id": "66dd53872005", - "configuration": "esp-officeduallights.yaml", - "job_type": "compile", - "status": "completed", - "created_at": "2026-07-25T01:24:42.622279+00:00", - "started_at": "2026-07-25T01:24:42.626262+00:00", - "completed_at": "2026-07-25T01:28:15.730459+00:00", - "compile_started_at": "2026-07-25T01:25:35.339675+00:00", - "compile_ended_at": "2026-07-25T01:28:14.189812+00:00", - "exit_code": 0, - "error": null, - "port": "", - "flash_bootloader": false, - "is_deferred_install": false, - "new_name": "", - "depends_on": "", - "dependency_released": false, - "progress": null, - "remote_peer": "", - "remote_job_id": "", - "remote_peer_label": "", - "device_name": "", - "device_friendly_name": "", - "source": "local", - "source_pin_sha256": "", - "source_label": "", - "source_esphome_version": "", - "target_esphome_version": "", - "failure_reason": "" - }, { "job_id": "c84bad09993e", "configuration": "esp-espnow_test_transmitter1.yaml", diff --git a/packages/Appliance_Monitoring/appliance_monitor_processor.yaml b/packages/Appliance_Monitoring/appliance_monitor_processor.yaml index 2e9a8a2..6ed3211 100644 --- a/packages/Appliance_Monitoring/appliance_monitor_processor.yaml +++ b/packages/Appliance_Monitoring/appliance_monitor_processor.yaml @@ -2,8 +2,8 @@ # PACKAGE: Appliance Monitor Processor ################################################################################ # -# Version: 1.5 -# Date: 2026-07-26 +# Version: 1.7 +# Date: 2026-08-17 # # Purpose: # Shared appliance power monitoring processor. @@ -29,7 +29,7 @@ # operating_power_min: 12 # paid_tariff_start: "00:00" # paid_tariff_end: "21:00" -# paid_tariff_cost: 0.2023 +# paid_tariff_cost: sensor.electricity_paid_rate (fallback 0.33235) # offpeak_tariff_cost: 0.0 # max_sample_gap_seconds: 900 # min_cycle_notify_seconds: 300 @@ -41,6 +41,14 @@ # Finished # # Notes: +# Version 1.7: +# - Use the central GST-inclusive electricity paid-rate sensor. +# - Update the fallback tariff from NZ$0.2023/kWh to NZ$0.33235/kWh. +# +# Version 1.6: +# - Preserve an explicit false power_available value instead of replacing +# it with the default true value. +# # Version 1.5: # - Standardized Sony TV and Pushover appliance notification titles as # "Appliance Notification". @@ -248,13 +256,21 @@ script: am_paid_tariff_start: "{{ paid_tariff_start | default('00:00', true) | string }}" am_paid_tariff_end: "{{ paid_tariff_end | default('21:00', true) | string }}" - am_paid_tariff_cost: "{{ paid_tariff_cost | default(0.2023, true) | float(0.2023) }}" + am_paid_tariff_cost: >- + {{ + paid_tariff_cost + | default( + states('sensor.electricity_paid_rate') | float(0.33235), + true + ) + | float(0.33235) + }} am_offpeak_tariff_cost: "{{ offpeak_tariff_cost | default(0.0, true) | float(0.0) }}" am_max_sample_gap_seconds: "{{ max_sample_gap_seconds | default(900, true) | int(900) }}" am_min_cycle_notify_seconds: "{{ min_cycle_notify_seconds | default(300, true) | int(300) }}" - am_power_available: "{{ power_available | default(true, true) | bool(true) }}" + am_power_available: "{{ power_available | default(true) | bool(true) }}" ########################################################################## # ANNOUNCEMENT DEFAULTS AND PASSED VALUES @@ -537,7 +553,7 @@ script: am_tariff_rate: >- {% if am_is_paid_interval | bool(false) %} - {{ am_paid_tariff_cost | float(0.2023) }} + {{ am_paid_tariff_cost | float(0.33235) }} {% else %} {{ am_offpeak_tariff_cost | float(0.0) }} {% endif %} @@ -679,7 +695,7 @@ script: {% endif %} am_cycle_offpeak_savings: >- - {% set val = ((am_cycle_energy_new_kwh | float(0)) * (am_paid_tariff_cost | float(0.2023))) - (am_cycle_cost_new | float(0)) %} + {% set val = ((am_cycle_energy_new_kwh | float(0)) * (am_paid_tariff_cost | float(0.33235))) - (am_cycle_cost_new | float(0)) %} {{ ([0, val] | max) | round(4) }} am_cycle_offpeak_savings_formatted: >- diff --git a/packages/Appliance_Monitoring/appliances_status_monitoring.yaml b/packages/Appliance_Monitoring/appliances_status_monitoring.yaml index a8f2110..9b6b413 100644 --- a/packages/Appliance_Monitoring/appliances_status_monitoring.yaml +++ b/packages/Appliance_Monitoring/appliances_status_monitoring.yaml @@ -6,7 +6,7 @@ # appliances_status_monitoring.yaml # # VERSION: -# V1.5 2026-07-11 +# V1.8 2026-08-15 # # PURPOSE: # Appliance status monitoring package for multiple appliances. @@ -51,6 +51,11 @@ # matrix_indicator. # # VERSION HISTORY: +# V1.8 2026-08-15 +# - Skip appliance processing while its power source is unavailable. +# - Preserve retained cycle state and rolling samples across HA restarts and +# source reconnects instead of treating missing measurements as zero. +# # V1.7 2026-08-12 # - Enabled MQTT activity-feed publication for every monitored appliance. # @@ -593,28 +598,32 @@ automation: am_power_available: >- {{ states(repeat.item.power_entity) not in ['unknown', 'unavailable'] }} - - action: script.appliance_monitor_process_sample - data: - appliance_id: "{{ repeat.item.appliance_id }}" - appliance_name: "{{ repeat.item.appliance_name }}" - appliance_action: "{{ repeat.item.appliance_action }}" + - if: + - condition: template + value_template: "{{ am_power_available | bool(false) }}" + then: + - action: script.appliance_monitor_process_sample + data: + appliance_id: "{{ repeat.item.appliance_id }}" + appliance_name: "{{ repeat.item.appliance_name }}" + appliance_action: "{{ repeat.item.appliance_action }}" - power_w: "{{ am_power_w }}" - power_available: "{{ am_power_available }}" - monitor_sensor: "{{ am_monitor_sensor }}" - state_topic: "{{ am_state_topic }}" + power_w: "{{ am_power_w }}" + power_available: "{{ am_power_available }}" + monitor_sensor: "{{ am_monitor_sensor }}" + state_topic: "{{ am_state_topic }}" - debug_flow: "{{ am_debug_flow }}" - resolution: "{{ am_resolution }}" - standby_power: "{{ am_standby_power }}" - operating_power_min: "{{ am_operating_power_min }}" - min_cycle_notify_seconds: "{{ am_min_cycle_notify_seconds }}" + debug_flow: "{{ am_debug_flow }}" + resolution: "{{ am_resolution }}" + standby_power: "{{ am_standby_power }}" + operating_power_min: "{{ am_operating_power_min }}" + min_cycle_notify_seconds: "{{ am_min_cycle_notify_seconds }}" - announcement_enabled: "{{ am_announcement_enabled }}" - announcement_channels: "{{ am_announcement_channels }}" - title: "{{ am_title }}" - short_announcement: "{{ am_short_announcement }}" - long_announcement: "{{ am_long_announcement }}" - announcement_payload: "{{ am_announcement_payload }}" - matrix_indicator: "{{ am_matrix_indicator }}" - mqtt_feed: "{{ am_mqtt_feed }}" + announcement_enabled: "{{ am_announcement_enabled }}" + announcement_channels: "{{ am_announcement_channels }}" + title: "{{ am_title }}" + short_announcement: "{{ am_short_announcement }}" + long_announcement: "{{ am_long_announcement }}" + announcement_payload: "{{ am_announcement_payload }}" + matrix_indicator: "{{ am_matrix_indicator }}" + mqtt_feed: "{{ am_mqtt_feed }}" diff --git a/packages/Lighting_2Way_Sync/office_lights_ha_fallback_sync.yaml b/packages/Lighting_2Way_Sync/office_lights_ha_fallback_sync.yaml new file mode 100644 index 0000000..a668183 --- /dev/null +++ b/packages/Lighting_2Way_Sync/office_lights_ha_fallback_sync.yaml @@ -0,0 +1,56 @@ +#:########################################################################################:# +# PACKAGE: Office Lights Home Assistant Fallback Synchronization +# FILE: Lighting_2Way_Sync/office_lights_ha_fallback_sync.yaml +# VERSION: v1.0.0 +# DATE: 2026-08-16 +#:########################################################################################:# +# +# PURPOSE: +# Provides the Home Assistant API transport for Office two-way light control +# when MQTT is unavailable. Direct MQTT remains the HA-down transport. +# +# OPERATION: +# - Synchronizes the Office bunker and overhead control pairs in both directions. +# - Uses idempotent Home Assistant actions, so MQTT and HA may both be online +# without creating a control loop. +# - Does not reconcile state during Home Assistant startup, preventing a stale +# restored entity state from changing a physical light. +# +# DEPENDENCIES: +# - Blueprint: zorruno/two_three_way_sync.yaml +# - esp-officelights and esp-officeduallights native ESPHome API connections. +# +# VERSION HISTORY: +# - v1.0.0 (2026-08-16): Initial MQTT-down HA fallback for Office lights. +#:########################################################################################:# + +automation: + #:##########################################################################:# + # BUNKER LIGHTS + #:##########################################################################:# + - id: office_bunker_lights_ha_fallback_sync + alias: "Office Bunker Lights HA Fallback Sync" + initial_state: true + use_blueprint: + path: zorruno/two_three_way_sync.yaml + input: + members: + - switch.office_office_main_lightswitch_3_relay_1_bunker_lights + - light.esp_officeduallights_light_1_right_hand_bunker_light + sync_on_start: false + startup_delay: 5 + + #:##########################################################################:# + # OVERHEAD LIGHTS + #:##########################################################################:# + - id: office_overhead_lights_ha_fallback_sync + alias: "Office Overhead Lights HA Fallback Sync" + initial_state: true + use_blueprint: + path: zorruno/two_three_way_sync.yaml + input: + members: + - switch.office_office_main_lightswitch_3_relay_2_overhead_lights + - light.esp_officeduallights_light_2_cool_white_overhead_lights + sync_on_start: false + startup_delay: 5 diff --git a/packages/alexa_tplink_actions.yaml b/packages/alexa_tplink_actions.yaml deleted file mode 100644 index 82c266c..0000000 --- a/packages/alexa_tplink_actions.yaml +++ /dev/null @@ -1,111 +0,0 @@ -#:########################################################################################:# -# TP-Link Deco Guest Wi-Fi Package # -#:########################################################################################:# -# -# TITLE: -# TP-Link Deco Guest Wi-Fi -# -# FILE: -# packages/alexa_tplink_actions.yaml -# -# VERSION: -# V2.1 2026-08-04 -# -# VERSION HISTORY: -# V2.1 2026-08-04 -# - Added sync automation so input_boolean.wifi_guest_network tracks the -# router's actual guest Wi-Fi status via the new guest-network -# binary sensor from the integration. -# -# V2.0 2026-08-04 -# - Switched from Alexa voice commands to direct Deco local API control. -# - Uses tplink_deco.set_guest_network service for reliable on/off. -# -# V1.1 2026-07-20 -# - Added structured documentation and automation descriptions. -# -# V1.0 -# - Initial Alexa-mediated TP-Link guest-network controls. -# -# PURPOSE: -# Enables or disables the TP-Link guest Wi-Fi network via the Deco's local -# API, using the tplink_deco custom integration's set_guest_network service. -# -# DEPENDENCIES: -# - tplink_deco integration must be configured and connected to the Deco. -# - input_boolean.wifi_guest_network is a UI-managed helper that represents -# the requested guest-network state. -# - binary_sensor.data_cupboard_new_sundamage_12_deco_guest_network reports -# the actual guest-network state from the router and keeps the helper in -# sync. -# -# OPERATION NOTES: -# - The helper records requested state; the sync automation below then -# reconciles it against the router's actual state so the helper tracks -# the real guest-network status. -# - If the Deco API call fails, the helper can disagree with the -# actual guest-network state. -# -#:########################################################################################:# - -automation: - - alias: "Turn on the Wifi Guest Network" - description: "Enables the TP-Link Deco guest Wi-Fi network via local API." - mode: single - triggers: - - trigger: state - entity_id: input_boolean.wifi_guest_network - to: "on" - actions: - - action: tplink_deco.set_guest_network - data: - enable: true - - - alias: "Turn off the Wifi Guest Network" - description: "Disables the TP-Link Deco guest Wi-Fi network via local API." - mode: single - triggers: - - trigger: state - entity_id: input_boolean.wifi_guest_network - to: "off" - actions: - - action: tplink_deco.set_guest_network - data: - enable: false - - - alias: "Sync Wifi Guest Network button with actual status" - description: > - Reconciles input_boolean.wifi_guest_network against the router's actual - guest Wi-Fi state reported by the guest-network binary sensor, so the - button reflects real status (including changes made outside HA). - mode: single - triggers: - - trigger: state - entity_id: binary_sensor.data_cupboard_new_sundamage_12_deco_guest_network - to: "on" - - trigger: state - entity_id: binary_sensor.data_cupboard_new_sundamage_12_deco_guest_network - to: "off" - conditions: - - condition: template - value_template: > - {{ states('input_boolean.wifi_guest_network') - != states('binary_sensor.data_cupboard_new_sundamage_12_deco_guest_network') }} - actions: - - choose: - - conditions: - - condition: template - value_template: > - {{ states('binary_sensor.data_cupboard_new_sundamage_12_deco_guest_network') == 'on' }} - sequence: - - action: input_boolean.turn_on - target: - entity_id: input_boolean.wifi_guest_network - - conditions: - - condition: template - value_template: > - {{ states('binary_sensor.data_cupboard_new_sundamage_12_deco_guest_network') == 'off' }} - sequence: - - action: input_boolean.turn_off - target: - entity_id: input_boolean.wifi_guest_network diff --git a/packages/battery_notes_alerts.yaml b/packages/battery_notes_alerts.yaml new file mode 100644 index 0000000..dfecbf3 --- /dev/null +++ b/packages/battery_notes_alerts.yaml @@ -0,0 +1,636 @@ +#:########################################################################################:# +# Battery Notes Alerts Package # +#:########################################################################################:# +# +# TITLE: +# Battery Notes Alerts +# +# FILE: +# packages/battery_notes_alerts.yaml +# +# VERSION: +# V1.1.0 2026-08-26 +# +# PURPOSE: +# Sends immediate Pushover alerts when a non-temporary Battery Notes device newly +# reports a low battery or becomes unavailable, plus a Thursday weekly digest. +# +# Immediate alerts are limited to one alert of each type per device per calendar day. +# +# SAFETY / PERFORMANCE DESIGN: +# - No automation-level templated variables. +# - Low battery detection uses the native Battery Notes threshold event. +# - Weekly Battery Notes checks use raise_events: false. +# - Immediate automations never scan all Home Assistant states. +# - Immediate automations never call device_entities(). +# - The offline watcher does only cheap filtering on state_changed events. +# - Offline alerts are inhibited for 10 minutes after Home Assistant starts. +# - Weekly list processing is bounded to 100 returned items per category. +# - Devices with "Temporary" anywhere in the Battery Notes note are always ignored. +# +# CONTROLS: +# - input_boolean.battery_notes_alerts_master_enable +# Master enable/disable for all notifications from this package. +# +# - Battery Notes - Immediate Low Alert +# May also be independently enabled/disabled in Automations. +# +# - Battery Notes - Immediate Offline Alert +# May also be independently enabled/disabled in Automations. +# +# - Battery Notes - Weekly Digest +# May also be independently enabled/disabled in Automations. +# +# OPERATION: +# - LOW: +# Native Battery Notes threshold event only. +# Reminder-generated events are ignored. +# Maximum one low alert per device per calendar day. +# +# - OFFLINE: +# Battery Notes Battery+ entities changing from a valid state to +# unknown/unavailable. +# Suppressed for 10 minutes after Home Assistant starts. +# Maximum one offline alert per device per calendar day. +# +# - WEEKLY: +# Thursday at 19:00. +# Reports current low batteries and batteries not reporting for 2+ days. +# Battery Notes devices marked Temporary are excluded. +# +# DEPENDENCIES: +# - Battery Notes integration +# - packages/view_road_announcement_router.yaml +# +# VERSION HISTORY: +# - V1.1.0 2026-08-26: Complete redesign using native Battery Notes events/actions. +# Removes high-frequency state scanning and top-level templates. +# Adds Temporary filtering, daily per-device alert suppression, +# startup offline suppression and master enable control. +# - V1.0.2 2026-08-25: RETIRED - unsafe high-frequency architecture. +# - V1.0.1 2026-08-25: RETIRED - unsafe high-frequency architecture. +# - V1.0.0 2026-08-25: RETIRED - unsafe high-frequency architecture. +# +#:########################################################################################:# + + +#:########################################################################################:# +# HELPERS # +#:########################################################################################:# + +input_boolean: + + # Master safety switch. + # + # No "initial" value is specified intentionally: + # - First creation defaults to OFF. + # - Thereafter Home Assistant restores the previous state. + battery_notes_alerts_master_enable: + name: "Battery Notes Alerts - Master Enable" + icon: mdi:battery-alert + + # Internal startup guard. + # + # This MUST start false on every Home Assistant restart. + battery_notes_offline_alerts_armed: + name: "Battery Notes Alerts - Offline Armed" + icon: mdi:shield-clock + initial: false + + +input_text: + + # Daily de-duplication caches. + # + # Format: + # YYYY-MM-DD|xxxxxxxxxx|xxxxxxxxxx|... + # + # Only the final 10 characters of the device identifier are stored. + # A maximum of the 20 most recent device tokens is retained. + # + # No initial value is set so the cache survives Home Assistant restarts. + battery_notes_low_alert_cache: + name: "Battery Notes - Low Alert Cache" + max: 255 + icon: mdi:battery-alert-variant + + battery_notes_offline_alert_cache: + name: "Battery Notes - Offline Alert Cache" + max: 255 + icon: mdi:battery-off-outline + + +#:########################################################################################:# +# AUTOMATIONS # +#:########################################################################################:# + +automation: + + #:######################################################################################:# + # Offline Alert Startup Guard # + #:######################################################################################:# + + - id: battery_notes_arm_offline_alerts + alias: "Battery Notes - Arm Offline Alerts" + description: > + Arms Battery Notes offline notifications 10 minutes after Home Assistant starts. + This prevents normal startup/integration initialisation from being interpreted as + devices suddenly going offline. + mode: restart + + triggers: + - trigger: homeassistant + event: start + + actions: + - action: input_boolean.turn_off + target: + entity_id: input_boolean.battery_notes_offline_alerts_armed + + - delay: "00:10:00" + + - action: input_boolean.turn_on + target: + entity_id: input_boolean.battery_notes_offline_alerts_armed + + + #:######################################################################################:# + # Immediate Low Battery Alert # + #:######################################################################################:# + + - id: battery_notes_immediate_low_alert + alias: "Battery Notes - Immediate Low Alert" + description: > + Sends one immediate Pushover alert when a non-temporary Battery Notes device + genuinely crosses into its low-battery state. Reminder-generated Battery Notes + events are ignored. A device can generate at most one low alert per calendar day. + mode: queued + max: 10 + + triggers: + - trigger: event + event_type: battery_notes_battery_threshold + event_data: + battery_low: true + reminder: false + + conditions: + + # Master control. + - condition: state + entity_id: input_boolean.battery_notes_alerts_master_enable + state: "on" + + # Temporary Battery Notes devices must never generate notifications. + - condition: template + value_template: >- + {% set note = trigger.event.data.note | default('', true) | lower %} + {{ 'temporary' not in note }} + + # Require some stable identifier for daily de-duplication. + - condition: template + value_template: >- + {{ (trigger.event.data.device_id | default('', true)) != '' + or (trigger.event.data.source_entity_id | default('', true)) != '' }} + + actions: + + # IMPORTANT: + # This de-duplication check is deliberately an ACTION condition rather than an + # automation-level condition. Because this automation is mode: queued, two events + # arriving together are serialised before checking/updating the cache. + - condition: template + value_template: >- + {% set identifier = + trigger.event.data.device_id | default('', true) + or trigger.event.data.source_entity_id | default('', true) %} + {% set token = identifier[-10:] %} + {% set today = now().date() | string %} + {% set cache = states('input_text.battery_notes_low_alert_cache') %} + {% set previous = + cache.split('|')[1:] + if cache.startswith(today ~ '|') + else [] %} + {{ token not in previous }} + + - action: script.view_road_announcement + data: + channels: "pushover_zorruno" + title: "Battery Alert" + short_announcement: >- + {% set name = + trigger.event.data.device_name + | default('Unknown Battery Device', true) %} + {% set level = + trigger.event.data.battery_level + | default(-1, true) + | float(-1) %} + {% set battery_type = + trigger.event.data.battery_type_and_quantity + | default('Not recorded', true) %} + New Alert: {{ name }}, Battery Low{% if level >= 0 %} + {{ level | round(0) | int }}%{% endif %} {{ battery_type }} + long_announcement: >- + {% set name = + trigger.event.data.device_name + | default('Unknown Battery Device', true) %} + {% set level = + trigger.event.data.battery_level + | default(-1, true) + | float(-1) %} + {% set battery_type = + trigger.event.data.battery_type_and_quantity + | default('Not recorded', true) %} + New Alert: {{ name }}, Battery Low{% if level >= 0 %} + {{ level | round(0) | int }}%{% endif %} {{ battery_type }} + + # Record this device only after the notification action has completed. + - action: input_text.set_value + target: + entity_id: input_text.battery_notes_low_alert_cache + data: + value: >- + {% set identifier = + trigger.event.data.device_id | default('', true) + or trigger.event.data.source_entity_id | default('', true) %} + {% set token = identifier[-10:] %} + {% set today = now().date() | string %} + {% set cache = states('input_text.battery_notes_low_alert_cache') %} + {% set previous = + cache.split('|')[1:] + if cache.startswith(today ~ '|') + else [] %} + {% set updated = (previous + [token])[-20:] %} + {{ today ~ '|' ~ updated | join('|') }} + + + #:######################################################################################:# + # Immediate Offline Alert # + #:######################################################################################:# + + - id: battery_notes_immediate_offline_alert + alias: "Battery Notes - Immediate Offline Alert" + description: > + Sends one immediate Pushover alert when a non-temporary Battery Notes Battery+ + entity genuinely changes from an available state to unknown/unavailable. + Alerts are inhibited for the first 10 minutes after Home Assistant starts. + A device can generate at most one offline alert per calendar day. + mode: queued + max: 20 + + triggers: + - trigger: event + event_type: state_changed + + conditions: + + # Keep the first checks extremely cheap because state_changed is a global event. + - condition: state + entity_id: input_boolean.battery_notes_alerts_master_enable + state: "on" + + - condition: state + entity_id: input_boolean.battery_notes_offline_alerts_armed + state: "on" + + # Only Battery Notes generated Battery+ entities are interesting. + # No regex and no global state lookup is required. + - condition: template + value_template: >- + {% set entity_id = trigger.event.data.entity_id | default('', true) %} + {{ (entity_id.startswith('sensor.') + and entity_id.endswith('_battery_plus')) + or + (entity_id.startswith('binary_sensor.') + and entity_id.endswith('_battery_plus_low')) }} + + # Require a genuine transition from available -> unavailable. + - condition: template + value_template: >- + {% set old = trigger.event.data.old_state %} + {% set new = trigger.event.data.new_state %} + {{ old is not none + and new is not none + and old.state not in ['unknown', 'unavailable'] + and new.state in ['unknown', 'unavailable'] }} + + # Temporary devices are ignored. + # + # Prefer the new state's note but fall back to the old state's attributes because + # integrations do not always retain every attribute on an unavailable state. + - condition: template + value_template: >- + {% set old = trigger.event.data.old_state %} + {% set new = trigger.event.data.new_state %} + {% set note = + new.attributes.get( + 'note', + old.attributes.get('note', '') + ) + | default('', true) + | lower %} + {{ 'temporary' not in note }} + + actions: + + # As with low alerts, do this after entering the queued action sequence so two + # related Battery+ entities becoming unavailable together cannot both notify. + - condition: template + value_template: >- + {% set old = trigger.event.data.old_state %} + {% set new = trigger.event.data.new_state %} + {% set identifier = + new.attributes.get('device_id', '') + or old.attributes.get('device_id', '') + or new.entity_id %} + {% set token = identifier[-10:] %} + {% set today = now().date() | string %} + {% set cache = states('input_text.battery_notes_offline_alert_cache') %} + {% set previous = + cache.split('|')[1:] + if cache.startswith(today ~ '|') + else [] %} + {{ token not in previous }} + + - action: script.view_road_announcement + data: + channels: "pushover_zorruno" + title: "Battery Alert" + short_announcement: >- + {% set old = trigger.event.data.old_state %} + {% set new = trigger.event.data.new_state %} + {% set name = + new.attributes.get('device_name') + or old.attributes.get('device_name') + or new.attributes.get('friendly_name') + or old.attributes.get('friendly_name') + or new.name %} + {% set battery_type = + new.attributes.get('battery_type_and_quantity') + or old.attributes.get('battery_type_and_quantity') + or 'Not recorded' %} + New Alert: {{ name }}, Battery Unavailable {{ battery_type }} + long_announcement: >- + {% set old = trigger.event.data.old_state %} + {% set new = trigger.event.data.new_state %} + {% set name = + new.attributes.get('device_name') + or old.attributes.get('device_name') + or new.attributes.get('friendly_name') + or old.attributes.get('friendly_name') + or new.name %} + {% set battery_type = + new.attributes.get('battery_type_and_quantity') + or old.attributes.get('battery_type_and_quantity') + or 'Not recorded' %} + New Alert: {{ name }}, Battery Unavailable {{ battery_type }} + + - action: input_text.set_value + target: + entity_id: input_text.battery_notes_offline_alert_cache + data: + value: >- + {% set old = trigger.event.data.old_state %} + {% set new = trigger.event.data.new_state %} + {% set identifier = + new.attributes.get('device_id', '') + or old.attributes.get('device_id', '') + or new.entity_id %} + {% set token = identifier[-10:] %} + {% set today = now().date() | string %} + {% set cache = states('input_text.battery_notes_offline_alert_cache') %} + {% set previous = + cache.split('|')[1:] + if cache.startswith(today ~ '|') + else [] %} + {% set updated = (previous + [token])[-20:] %} + {{ today ~ '|' ~ updated | join('|') }} + + + #:######################################################################################:# + # Weekly Digest # + #:######################################################################################:# + + - id: battery_notes_weekly_digest + alias: "Battery Notes - Weekly Digest" + description: > + Sends one Battery Notes summary every Thursday at 19:00. Reports current low + batteries and batteries which have not reported for at least two days. + Temporary Battery Notes devices are excluded. + mode: single + + triggers: + - trigger: time + at: "19:00:00" + + conditions: + - condition: time + weekday: + - thu + + - condition: state + entity_id: input_boolean.battery_notes_alerts_master_enable + state: "on" + + actions: + + # IMPORTANT: + # raise_events MUST remain false. + # + # This retrieves the current low list without creating Battery Notes threshold + # reminder events. + - action: battery_notes.check_battery_low + data: + raise_events: false + response_variable: battery_low_response + + # Ask Battery Notes for devices which have not reported for at least two days. + # Again, retrieve a response only; do not raise one event per device. + - action: battery_notes.check_battery_last_reported + data: + days_last_reported: 2 + raise_events: false + response_variable: battery_report_response + + - action: script.view_road_announcement + data: + channels: "pushover_zorruno" + title: "Weekly Battery Digest" + short_announcement: "Weekly Battery Digest" + long_announcement: >- + {# ------------------------------------------------------------------------- #} + {# Obtain response arrays. #} + {# #} + {# check_battery_battery_low is confirmed from this HA installation. #} + {# Two possible last-reported response keys are accepted defensively. #} + {# ------------------------------------------------------------------------- #} + + {% set low_items = + battery_low_response.get( + 'check_battery_battery_low', + battery_low_response.get('check_battery_low', []) + ) %} + + {% set report_items = + battery_report_response.get( + 'check_battery_last_reported', + battery_report_response.get( + 'check_battery_battery_last_reported', + [] + ) + ) %} + + {# ------------------------------------------------------------------------- #} + {# Resolve the Battery Notes note. #} + {# #} + {# The low action response on this installation does not include "note", #} + {# so fall back to the attributes of Battery Notes entities. #} + {# This lookup occurs ONCE PER WEEK ONLY and is bounded below. #} + {# ------------------------------------------------------------------------- #} + + {% macro battery_note(item) -%} + {% set ns = + namespace( + note=item.get('note', '') | default('', true) + ) %} + + {% if not ns.note %} + {% set item_device_id = + item.get('device_id', '') | default('', true) %} + {% set item_source_id = + item.get('source_entity_id', '') | default('', true) %} + + {% for entity_id in integration_entities('battery_notes') %} + {% if not ns.note %} + {% set entity_device_id = + state_attr(entity_id, 'device_id') + | default('', true) %} + {% set entity_source_id = + state_attr(entity_id, 'source_entity_id') + | default('', true) %} + + {% if + (item_device_id + and entity_device_id == item_device_id) + or + (item_source_id + and entity_source_id == item_source_id) %} + {% set found_note = + state_attr(entity_id, 'note') + | default('', true) %} + {% if found_note %} + {% set ns.note = found_note %} + {% endif %} + {% endif %} + {% endif %} + {% endfor %} + {% endif %} + + {{ ns.note }} + {%- endmacro %} + + {# ------------------------------------------------------------------------- #} + {# Build bounded problem lists, excluding Temporary devices. #} + {# ------------------------------------------------------------------------- #} + + {% set summary = namespace(low=[], not_reporting=[]) %} + + {% for item in low_items[:100] %} + {% set note = battery_note(item) | trim | lower %} + + {% if 'temporary' not in note %} + {% set name = + item.get('device_name', 'Unknown Battery Device') + | default('Unknown Battery Device', true) %} + {% set level = + item.get('battery_level', -1) + | default(-1, true) + | float(-1) %} + {% set battery_type = + item.get('battery_type_and_quantity', 'Not recorded') + | default('Not recorded', true) %} + + {% if level >= 0 %} + {% set line = + name + ~ ' - ' + ~ (level | round(0) | int) + ~ '% - ' + ~ battery_type %} + {% else %} + {% set line = + name + ~ ' - ' + ~ battery_type %} + {% endif %} + + {% set summary.low = summary.low + [line] %} + {% endif %} + {% endfor %} + + {% for item in report_items[:100] %} + {% set note = battery_note(item) | trim | lower %} + + {% if 'temporary' not in note %} + {% set name = + item.get('device_name', 'Unknown Battery Device') + | default('Unknown Battery Device', true) %} + {% set days = + item.get('battery_last_reported_days', 0) + | default(0, true) + | int(0) %} + {% set last_level = + item.get('battery_last_reported_level', -1) + | default(-1, true) + | float(-1) %} + {% set battery_type = + item.get('battery_type_and_quantity', 'Not recorded') + | default('Not recorded', true) %} + + {% if last_level >= 0 %} + {% set line = + name + ~ ' - ' + ~ days + ~ ' days - last ' + ~ (last_level | round(0) | int) + ~ '% - ' + ~ battery_type %} + {% else %} + {% set line = + name + ~ ' - ' + ~ days + ~ ' days - ' + ~ battery_type %} + {% endif %} + + {% set summary.not_reporting = + summary.not_reporting + [line] %} + {% endif %} + {% endfor %} + + Weekly Battery Digest + + {% if summary.low %} + Low Battery: {{ summary.low | count }} + {% for line in summary.low %} + • {{ line }} + {% endfor %} + {% else %} + Low Battery: 0 + {% endif %} + + {% if summary.not_reporting %} + Not Reporting (2+ days): {{ summary.not_reporting | count }} + {% for line in summary.not_reporting %} + • {{ line }} + {% endfor %} + {% else %} + Not Reporting (2+ days): 0 + {% endif %} + + {% if not summary.low and not summary.not_reporting %} + + All monitored Battery Notes devices are OK. + {% endif %} \ No newline at end of file diff --git a/packages/battery_notes_alerts.yaml.disabled b/packages/battery_notes_alerts.yaml.disabled new file mode 100644 index 0000000..bbf4167 --- /dev/null +++ b/packages/battery_notes_alerts.yaml.disabled @@ -0,0 +1,195 @@ +#:########################################################################################:# +# Battery Notes Alerts Package # +#:########################################################################################:# +# +# TITLE: +# Battery Notes Alerts +# +# FILE: +# packages/battery_notes_alerts.yaml +# +# VERSION: +# V1.0.0 2026-08-25 +# +# PURPOSE: +# Sends immediate and weekly Pushover alerts for non-temporary Battery Notes devices. +# Device lists are generated from Battery Notes at runtime, so adding a note starts +# monitoring the device without maintaining a second entity list. +# +# CONTROLS: +# - Battery Notes - Immediate Alert and Battery Notes - Weekly Digest are independent +# automation entities. Each can be enabled or disabled in Home Assistant Automations. +# +# DEPENDENCIES: +# - Battery Notes integration +# - packages/view_road_announcement_router.yaml +# +# VERSION HISTORY: +# - V1.0.0 2026-08-25: Initial immediate and Thursday weekly battery alerts. +# +#:########################################################################################:# + +automation: + - id: battery_notes_immediate_alert + alias: "Battery Notes - Immediate Alert" + description: > + Sends a Pushover alert when a monitored Battery Notes device newly reports + low battery or becomes unavailable. Temporary Battery Notes devices are ignored. + mode: queued + max: 10 + triggers: + - trigger: event + event_type: state_changed + conditions: + - condition: template + value_template: >- + {{ trigger.event.data.entity_id is match('^(sensor|binary_sensor)\\..*_battery_plus(?:_low)?$') }} + - condition: template + value_template: >- + {% set old = trigger.event.data.old_state %} + {% set new = trigger.event.data.new_state %} + {{ old is not none + and new is not none + and old.state not in ['unknown', 'unavailable'] + and old.state != new.state }} + - condition: template + value_template: >- + {% set note = trigger.event.data.new_state.attributes.note | default('', true) | lower %} + {{ trigger.event.data.new_state.attributes.device_id is defined + and 'temporary' not in note }} + - condition: template + value_template: >- + {% set old = trigger.event.data.old_state %} + {% set new = trigger.event.data.new_state %} + {% set device_id = new.attributes.device_id %} + {% set is_percentage = new.entity_id.startswith('sensor.') and new.entity_id.endswith('_battery_plus') %} + {% set companion = namespace(percentage=none) %} + {% for item in states %} + {% if item.attributes.device_id | default('') == device_id + and item.entity_id.startswith('sensor.') + and item.entity_id.endswith('_battery_plus') %} + {% set companion.percentage = item %} + {% endif %} + {% endfor %} + {% set source = companion.percentage if companion.percentage else new %} + {% set qualitative_id = source.entity_id + | replace('_battery_plus_low', '_battery_state') + | replace('_battery_plus', '_battery_state') %} + {% set qualitative = states[qualitative_id] %} + {% set qualitative_available = qualitative is not none + and qualitative.state in ['high', 'medium', 'low'] %} + {% set newly_low = (new.attributes.battery_low | default(false)) + and not (old.attributes.battery_low | default(false)) %} + {% set newly_binary_low = new.entity_id.startswith('binary_sensor.') + and new.state == 'on' %} + {% set newly_unavailable = new.state in ['unknown', 'unavailable'] + and source.entity_id == new.entity_id + and not qualitative_available %} + {{ newly_low or newly_binary_low or newly_unavailable }} + variables: + alert_name: >- + {% set new = trigger.event.data.new_state %} + {{ new.attributes.device_name | default(new.attributes.friendly_name, true) | default(new.name, true) }} + alert_type: >- + {% set new = trigger.event.data.new_state %} + {{ new.attributes.battery_type_and_quantity | default('Not recorded', true) }} + alert_level: >- + {% set new = trigger.event.data.new_state %} + {% set device_id = new.attributes.device_id %} + {% set level = namespace(value=none) %} + {% for item in states %} + {% if item.attributes.device_id | default('') == device_id + and item.entity_id.startswith('sensor.') + and item.entity_id.endswith('_battery_plus') + and item.state not in ['unknown', 'unavailable'] %} + {% set level.value = item.state %} + {% endif %} + {% endfor %} + {{ level.value ~ '%' if level.value is not none else '' }} + alert_line: >- + {% set new = trigger.event.data.new_state %} + {% if new.state in ['unknown', 'unavailable'] %} + New Alert: {{ alert_name }}, Battery Unavailable {{ alert_type }} + {% else %} + New Alert: {{ alert_name }}, Battery Low {{ alert_level }} {{ alert_type }} + {% endif %} + alert_summary: &battery_notes_summary >- + {% set monitored = namespace(device_ids=[], low=[], unavailable=[]) %} + {% for item in states %} + {% set note = item.attributes.note | default('', true) | lower %} + {% set device_id = item.attributes.device_id | default('') %} + {% if item.entity_id is match('^(sensor|binary_sensor)\\..*_battery_plus(?:_low)?$') + and device_id + and 'temporary' not in note + and device_id not in monitored.device_ids %} + {% set monitored.device_ids = monitored.device_ids + [device_id] %} + {% set device = namespace(percentage=none, low_sensor=none) %} + {% for candidate in states %} + {% if candidate.attributes.device_id | default('') == device_id %} + {% if candidate.entity_id.startswith('sensor.') and candidate.entity_id.endswith('_battery_plus') %} + {% set device.percentage = candidate %} + {% elif candidate.entity_id.startswith('binary_sensor.') and candidate.entity_id.endswith('_battery_plus_low') %} + {% set device.low_sensor = candidate %} + {% endif %} + {% endif %} + {% endfor %} + {% set source = device.percentage if device.percentage else device.low_sensor %} + {% set qualitative_id = source.entity_id + | replace('_battery_plus_low', '_battery_state') + | replace('_battery_plus', '_battery_state') %} + {% set qualitative = states[qualitative_id] %} + {% set qualitative_state = qualitative.state if qualitative is not none else '' %} + {% set name = source.attributes.device_name + | default(source.attributes.friendly_name, true) + | default(source.name, true) %} + {% set battery_type = source.attributes.battery_type_and_quantity | default('Not recorded', true) %} + {% set low = source.attributes.battery_low | default(false) + or (device.low_sensor is not none and device.low_sensor.state == 'on') + or qualitative_state == 'low' %} + {% set unavailable = source.state in ['unknown', 'unavailable'] + and qualitative_state not in ['high', 'medium', 'low'] %} + {% if low %} + {% set level = source.state ~ '%' if device.percentage is not none and source.state not in ['unknown', 'unavailable'] else '' %} + {% set monitored.low = monitored.low + [name ~ ' (' ~ level ~ (', ' if level else '') ~ battery_type ~ ')'] %} + {% endif %} + {% if unavailable %} + {% set monitored.unavailable = monitored.unavailable + [name ~ ' (' ~ battery_type ~ ')'] %} + {% endif %} + {% endif %} + {% endfor %} + Summary: {{ monitored.device_ids | count }} Battery Notes devices, {{ monitored.unavailable | count }} unavailable, {{ monitored.low | count }} battery low. + Low Battery Devices: {{ monitored.low | join(', ') if monitored.low else 'None' }} + Unavailable Devices: {{ monitored.unavailable | join(', ') if monitored.unavailable else 'None' }} + actions: + - action: script.view_road_announcement + data: + channels: "pushover_zorruno" + title: "Battery Alert" + short_announcement: "{{ alert_line }}" + long_announcement: >- + {{ alert_line }} + + {{ alert_summary }} + + - id: battery_notes_weekly_digest + alias: "Battery Notes - Weekly Digest" + description: > + Sends the Battery Notes health summary to Pushover every Thursday at 19:00. + Temporary Battery Notes devices are excluded. + mode: single + triggers: + - trigger: time + at: "19:00:00" + conditions: + - condition: time + weekday: + - thu + variables: + alert_summary: *battery_notes_summary + actions: + - action: script.view_road_announcement + data: + channels: "pushover_zorruno" + title: "Weekly Battery Digest" + short_announcement: "Weekly Battery Digest" + long_announcement: "{{ alert_summary }}" diff --git a/packages/battery_notes_alerts.yaml.disabled.failed b/packages/battery_notes_alerts.yaml.disabled.failed new file mode 100644 index 0000000..7067071 --- /dev/null +++ b/packages/battery_notes_alerts.yaml.disabled.failed @@ -0,0 +1,197 @@ +#:########################################################################################:# +# Battery Notes Alerts Package # +#:########################################################################################:# +# +# TITLE: +# Battery Notes Alerts +# +# FILE: +# packages/battery_notes_alerts.yaml +# +# VERSION: +# V1.0.1 2026-08-25 +# +# PURPOSE: +# Sends immediate and weekly Pushover alerts for non-temporary Battery Notes devices. +# Device lists are generated from Battery Notes at runtime, so adding a note starts +# monitoring the device without maintaining a second entity list. +# +# CONTROLS: +# - Battery Notes - Immediate Alert and Battery Notes - Weekly Digest are independent +# automation entities. Each can be enabled or disabled in Home Assistant Automations. +# +# DEPENDENCIES: +# - Battery Notes integration +# - packages/view_road_announcement_router.yaml +# +# VERSION HISTORY: +# - V1.0.1 2026-08-25: Bound companion lookups and prevent oversized template output. +# - V1.0.0 2026-08-25: Initial immediate and Thursday weekly battery alerts. +# +#:########################################################################################:# + +automation: + - id: battery_notes_immediate_alert + alias: "Battery Notes - Immediate Alert" + description: > + Sends a Pushover alert when a monitored Battery Notes device newly reports + low battery or becomes unavailable. Temporary Battery Notes devices are ignored. + mode: single + max_exceeded: silent + triggers: + - trigger: event + event_type: state_changed + conditions: + - condition: template + value_template: >- + {{ trigger.event.data.entity_id is match('^(sensor|binary_sensor)\\..*_battery_plus(?:_low)?$') }} + - condition: template + value_template: >- + {% set old = trigger.event.data.old_state %} + {% set new = trigger.event.data.new_state %} + {{ old is not none + and new is not none + and old.state not in ['unknown', 'unavailable'] + and old.state != new.state }} + - condition: template + value_template: >- + {% set new = trigger.event.data.new_state %} + {% set note = new.attributes.note | default('', true) | lower %} + {{ new.attributes.device_id | default('') | bool + and 'temporary' not in note }} + - condition: template + value_template: >- + {%- set old = trigger.event.data.old_state -%} + {%- set new = trigger.event.data.new_state -%} + {%- set device_id = new.attributes.device_id -%} + {%- set companions = namespace(percentage_id='', qualitative_id='') -%} + {%- for entity_id in device_entities(device_id) -%} + {%- if entity_id.startswith('sensor.') and entity_id.endswith('_battery_plus') -%} + {%- set companions.percentage_id = entity_id -%} + {%- elif entity_id.startswith('sensor.') and entity_id.endswith('_battery_state') -%} + {%- set companions.qualitative_id = entity_id -%} + {%- endif -%} + {%- endfor -%} + {%- set source_id = companions.percentage_id or new.entity_id -%} + {%- set qualitative_available = companions.qualitative_id + and states(companions.qualitative_id) in ['high', 'medium', 'low'] -%} + {%- set newly_low = new.attributes.battery_low | default(false) + and not old.attributes.battery_low | default(false) -%} + {%- set newly_binary_low = new.entity_id.startswith('binary_sensor.') + and new.state == 'on' -%} + {%- set newly_unavailable = new.state in ['unknown', 'unavailable'] + and source_id == new.entity_id + and not qualitative_available -%} + {{ newly_low or newly_binary_low or newly_unavailable }} + variables: + alert_name: >- + {% set new = trigger.event.data.new_state %} + {{ new.attributes.device_name + | default(new.attributes.friendly_name, true) + | default(new.name, true) }} + alert_type: >- + {{ trigger.event.data.new_state.attributes.battery_type_and_quantity + | default('Not recorded', true) }} + alert_level: >- + {%- set device_id = trigger.event.data.new_state.attributes.device_id -%} + {%- set level = namespace(value='') -%} + {%- for entity_id in device_entities(device_id) -%} + {%- if entity_id.startswith('sensor.') + and entity_id.endswith('_battery_plus') + and states(entity_id) not in ['unknown', 'unavailable'] -%} + {%- set level.value = states(entity_id) -%} + {%- endif -%} + {%- endfor -%} + {{ level.value ~ '%' if level.value else '' }} + alert_line: >- + {% if trigger.event.data.new_state.state in ['unknown', 'unavailable'] %} + New Alert: {{ alert_name }}, Battery Unavailable {{ alert_type }} + {% else %} + New Alert: {{ alert_name }}, Battery Low {{ alert_level }} {{ alert_type }} + {% endif %} + alert_summary: &battery_notes_summary >- + {%- set monitored = namespace(device_ids=[], low=[], unavailable=[]) -%} + {%- for item in states -%} + {%- set note = item.attributes.note | default('', true) | lower -%} + {%- set device_id = item.attributes.device_id | default('') -%} + {%- if item.entity_id is match('^(sensor|binary_sensor)\\..*_battery_plus(?:_low)?$') + and device_id + and 'temporary' not in note + and device_id not in monitored.device_ids -%} + {%- set monitored.device_ids = monitored.device_ids + [device_id] -%} + {%- endif -%} + {%- endfor -%} + {%- for device_id in monitored.device_ids -%} + {%- set device = namespace(percentage_id='', low_id='', qualitative_id='') -%} + {%- for entity_id in device_entities(device_id) -%} + {%- if entity_id.startswith('sensor.') and entity_id.endswith('_battery_plus') -%} + {%- set device.percentage_id = entity_id -%} + {%- elif entity_id.startswith('binary_sensor.') and entity_id.endswith('_battery_plus_low') -%} + {%- set device.low_id = entity_id -%} + {%- elif entity_id.startswith('sensor.') and entity_id.endswith('_battery_state') -%} + {%- set device.qualitative_id = entity_id -%} + {%- endif -%} + {%- endfor -%} + {%- set source_id = device.percentage_id or device.low_id -%} + {%- set source_state = states(source_id) -%} + {%- set qualitative_state = states(device.qualitative_id) if device.qualitative_id else '' -%} + {%- set name = state_attr(source_id, 'device_name') + or state_attr(source_id, 'friendly_name') + or source_id -%} + {%- set battery_type = state_attr(source_id, 'battery_type_and_quantity') + or 'Not recorded' -%} + {%- set low = state_attr(source_id, 'battery_low') | default(false, true) + or (device.low_id and is_state(device.low_id, 'on')) + or qualitative_state == 'low' -%} + {%- set unavailable = source_state in ['unknown', 'unavailable'] + and qualitative_state not in ['high', 'medium', 'low'] -%} + {%- if low -%} + {%- set level = source_state ~ '%' + if device.percentage_id and source_state not in ['unknown', 'unavailable'] + else '' -%} + {%- set monitored.low = monitored.low + + [name ~ ' (' ~ level ~ (', ' if level else '') ~ battery_type ~ ')'] -%} + {%- endif -%} + {%- if unavailable -%} + {%- set monitored.unavailable = monitored.unavailable + + [name ~ ' (' ~ battery_type ~ ')'] -%} + {%- endif -%} + {%- endfor -%} + Summary: {{ monitored.device_ids | count }} Battery Notes devices, + {{ monitored.unavailable | count }} unavailable, + {{ monitored.low | count }} battery low. + Low Battery Devices: {{ monitored.low | join(', ') if monitored.low else 'None' }} + Unavailable Devices: {{ monitored.unavailable | join(', ') if monitored.unavailable else 'None' }} + actions: + - action: script.view_road_announcement + data: + channels: "pushover_zorruno" + title: "Battery Alert" + short_announcement: "{{ alert_line }}" + long_announcement: >- + {{ alert_line }} + + {{ alert_summary }} + + - id: battery_notes_weekly_digest + alias: "Battery Notes - Weekly Digest" + description: > + Sends the Battery Notes health summary to Pushover every Thursday at 19:00. + Temporary Battery Notes devices are excluded. + mode: single + triggers: + - trigger: time + at: "19:00:00" + conditions: + - condition: time + weekday: + - thu + variables: + alert_summary: *battery_notes_summary + actions: + - action: script.view_road_announcement + data: + channels: "pushover_zorruno" + title: "Weekly Battery Digest" + short_announcement: "Weekly Battery Digest" + long_announcement: "{{ alert_summary }}" diff --git a/packages/bedroom_3_controls.yaml b/packages/bedroom_3_controls.yaml index 3ec3e37..280fb13 100644 --- a/packages/bedroom_3_controls.yaml +++ b/packages/bedroom_3_controls.yaml @@ -1,75 +1,85 @@ -########################################################################################## -# Bedroom 3 Morning Climate -########################################################################################## +# PACKAGE: Bedroom 3 Climate Controls # -# Turns on the Bedroom 3 heat pump at the selected morning time without -# changing its current HVAC mode, temperature, or other settings, then turns -# it off at 08:30. +# Purpose: Configurable automatic heat-pump schedule for Mollie's bedroom. +# Notes: The schedule runs only on enabled weekday and/or weekend day types. +# Version: 2.0.0 # -########################################################################################## +#:########################################################################################:# ---- input_boolean: bedroom_3_morning_climate_enabled: - name: Bedroom 3 Morning Climate - icon: mdi:weather-sunny - initial: true + name: "Bedroom 3 Heat Pump Auto Control" + icon: mdi:hvac -input_select: - bedroom_3_morning_climate_time: - name: Bedroom 3 Morning Climate Time + bedroom_3_morning_climate_weekdays: + name: "Bedroom 3 Heat Pump Weekdays" + icon: mdi:calendar-week + + bedroom_3_morning_climate_weekends: + name: "Bedroom 3 Heat Pump Weekends" + icon: mdi:calendar-weekend + +input_datetime: + bedroom_3_morning_climate_start_time: + name: "Bedroom 3 Heat Pump On Time" icon: mdi:clock-start - initial: "06:45" - options: - - "04:30" - - "04:45" - - "05:00" - - "05:15" - - "05:30" - - "05:45" - - "06:00" - - "06:15" - - "06:30" - - "06:45" - - "07:00" - - "07:15" - - "07:30" - - "07:45" - - "08:00" - - "08:15" - - "08:30" - - "08:45" - - "09:00" - - "09:15" - - "09:30" - - "09:45" - - "10:00" + has_date: false + has_time: true + + bedroom_3_morning_climate_stop_time: + name: "Bedroom 3 Heat Pump Off Time" + icon: mdi:clock-end + has_date: false + has_time: true + +#:########################################################################################:# +# Automations +#:########################################################################################:# automation: - id: bedroom_3_morning_climate_start - alias: Bedroom 3 Morning Climate Start - description: >- - Turns on the Bedroom 3 heat pump at the selected time when enabled, then - turns it off at 08:30. - trigger: + alias: "Bedroom 3 Heat Pump Auto Start" + description: "Starts the heat pump at the selected time on enabled day types." + triggers: - trigger: time_pattern - minutes: "/15" - condition: + minutes: "/1" + conditions: - condition: state entity_id: input_boolean.bedroom_3_morning_climate_enabled state: "on" - condition: template value_template: >- {{ now().strftime('%H:%M') == - states('input_select.bedroom_3_morning_climate_time') }} - action: + states('input_datetime.bedroom_3_morning_climate_start_time')[:5] }} + - condition: template + value_template: >- + {{ (now().weekday() < 5 and + is_state('input_boolean.bedroom_3_morning_climate_weekdays', 'on')) or + (now().weekday() >= 5 and + is_state('input_boolean.bedroom_3_morning_climate_weekends', 'on')) }} + actions: - action: climate.turn_on target: entity_id: climate.mollie_s_room - - wait_template: >- - {{ now().hour > 8 or (now().hour == 8 and now().minute >= 30) }} - + - id: bedroom_3_morning_climate_stop + alias: "Bedroom 3 Heat Pump Auto Stop" + description: "Stops the heat pump at the selected time on enabled day types." + triggers: + - trigger: time_pattern + minutes: "/1" + conditions: + - condition: template + value_template: >- + {{ now().strftime('%H:%M') == + states('input_datetime.bedroom_3_morning_climate_stop_time')[:5] }} + - condition: template + value_template: >- + {{ (now().weekday() < 5 and + is_state('input_boolean.bedroom_3_morning_climate_weekdays', 'on')) or + (now().weekday() >= 5 and + is_state('input_boolean.bedroom_3_morning_climate_weekends', 'on')) }} + actions: - action: climate.turn_off target: entity_id: climate.mollie_s_room diff --git a/packages/energy_cost_monitoring.yaml b/packages/energy_cost_monitoring.yaml new file mode 100644 index 0000000..6e8fe6a --- /dev/null +++ b/packages/energy_cost_monitoring.yaml @@ -0,0 +1,939 @@ +################################################################################ +# PACKAGE: Energy Cost Monitoring +################################################################################ +# +# Version: 1.3.0 +# Date: 2026-08-23 +# +# Purpose: +# Track GST-inclusive electricity costs for the three-phase grid supply and +# every appliance configured on the Energy dashboard. +# +# Notes: +# - Charged period: 00:00 to 21:00. +# - Free period: 21:00 to 00:00. +# - Bill rates are GST-exclusive; calculated costs include 15% GST. +# - Fixed daily charges are kept separate from appliance costs. +# - Integral sensors use the left method so tariff changes are applied at the +# boundary without averaging the old and new rates. +# +# Version history: +# 1.3.0 (2026-08-24): Add Drinks Fridge and Vertical Freezer energy and +# cost monitoring. +# 1.2.0 (2026-08-23): Add Downstairs Lounge North GPO (X48PM) energy and +# cost monitoring. +# 1.1.1 (2026-08-22): Use the Zigbee X31PP plug for Main Fridge power costs. +# 1.1.0 (2026-08-17): Add sorted daily, weekly, and monthly appliance ranking +# meters and dynamic chart scales. +# 1.0.0 (2026-08-17): Initial tariff, grid, appliance, and fixed-cost tracking. +# +#:########################################################################################:# +# TARIFF HELPERS +#:########################################################################################:# + +input_number: + electricity_paid_rate_ex_gst: + name: Electricity Paid Rate Ex GST + icon: mdi:cash + initial: 0.289 + min: 0 + max: 2 + step: 0.001 + mode: box + unit_of_measurement: "NZD/kWh" + + electricity_daily_charge_ex_gst: + name: Electricity Daily Charge Ex GST + icon: mdi:calendar-cash + initial: 3.036 + min: 0 + max: 20 + step: 0.001 + mode: box + unit_of_measurement: "NZD/day" + +#:########################################################################################:# +# TARIFF AND COST-RATE SENSORS +#:########################################################################################:# + +template: + - sensor: + - name: Electricity Paid Rate + default_entity_id: sensor.electricity_paid_rate + unique_id: electricity_paid_rate + icon: mdi:cash + unit_of_measurement: "NZD/kWh" + state_class: measurement + state: >- + {{ + ( + states('input_number.electricity_paid_rate_ex_gst') + | float(0.289) + * 1.15 + ) | round(5) + }} + attributes: + gst_rate: 0.15 + rate_ex_gst: >- + {{ + states('input_number.electricity_paid_rate_ex_gst') + | float(0.289) + }} + + - name: Electricity Current Price + default_entity_id: sensor.electricity_current_price + unique_id: electricity_current_price + icon: mdi:currency-usd + unit_of_measurement: "NZD/kWh" + state_class: measurement + state: >- + {% set minute = now().hour * 60 + now().minute %} + {{ + 0 + if minute >= 21 * 60 + else states('sensor.electricity_paid_rate') | float(0.33235) + }} + attributes: + tariff: >- + {{ "free" if now().hour >= 21 else "charged" }} + charged_period: "00:00-21:00" + free_period: "21:00-00:00" + gst_included: true + + - name: Electricity Daily Charge + default_entity_id: sensor.electricity_daily_charge + unique_id: electricity_daily_charge + icon: mdi:calendar-cash + unit_of_measurement: "NZD/day" + state_class: measurement + state: >- + {{ + ( + states('input_number.electricity_daily_charge_ex_gst') + | float(3.036) + * 1.15 + ) | round(5) + }} + attributes: + gst_rate: 0.15 + charge_ex_gst: >- + {{ + states('input_number.electricity_daily_charge_ex_gst') + | float(3.036) + }} + + - name: Electricity Grid Cost Rate + default_entity_id: sensor.electricity_grid_cost_rate + unique_id: electricity_grid_cost_rate + icon: mdi:transmission-tower + unit_of_measurement: "NZD/h" + state_class: measurement + availability: >- + {{ + has_value('sensor.main_house_3_phase_power_monitor_main_power_red_active_power') + and has_value('sensor.main_house_3_phase_power_monitor_main_power_yellow_active_power') + and has_value('sensor.main_house_3_phase_power_monitor_main_power_blue_active_power') + }} + state: >- + {% set red = states('sensor.main_house_3_phase_power_monitor_main_power_red_active_power') | float(0) %} + {% set yellow = states('sensor.main_house_3_phase_power_monitor_main_power_yellow_active_power') | float(0) %} + {% set blue = states('sensor.main_house_3_phase_power_monitor_main_power_blue_active_power') | float(0) %} + {% set price = states('sensor.electricity_current_price') | float(0) %} + {{ ([red + yellow + blue, 0] | max / 1000 * price) | round(6) }} + + - name: Energy Cost 16A EV Wallcharger Rate + default_entity_id: sensor.energy_cost_16a_ev_wallcharger_rate + unique_id: energy_cost_16a_ev_wallcharger_rate + unit_of_measurement: "NZD/h" + state_class: measurement + availability: "{{ has_value('sensor.garage_db_control_16a_wallcharger_power') }}" + state: >- + {{ + ( + states('sensor.garage_db_control_16a_wallcharger_power') | float(0) + / 1000 + * states('sensor.electricity_current_price') | float(0) + ) | round(6) + }} + + - name: Energy Cost 32A EV Charger Rate + default_entity_id: sensor.energy_cost_32a_ev_charger_rate + unique_id: energy_cost_32a_ev_charger_rate + unit_of_measurement: "NZD/h" + state_class: measurement + availability: "{{ has_value('sensor.main_house_3_phase_power_monitor_32a_wallcharger_power') }}" + state: >- + {{ + ( + states('sensor.main_house_3_phase_power_monitor_32a_wallcharger_power') | float(0) + / 1000 + * states('sensor.electricity_current_price') | float(0) + ) | round(6) + }} + + - name: Energy Cost Underhouse Dehumidifier Rate + default_entity_id: sensor.energy_cost_underhouse_dehumidifier_rate + unique_id: energy_cost_underhouse_dehumidifier_rate + unit_of_measurement: "NZD/h" + state_class: measurement + availability: "{{ has_value('sensor.underhouse_dehumidifier_power_plug_x10pp_power') }}" + state: >- + {{ + ( + states('sensor.underhouse_dehumidifier_power_plug_x10pp_power') | float(0) + / 1000 + * states('sensor.electricity_current_price') | float(0) + ) | round(6) + }} + + - name: Energy Cost Pool Pump Rate + default_entity_id: sensor.energy_cost_pool_pump_rate + unique_id: energy_cost_pool_pump_rate + unit_of_measurement: "NZD/h" + state_class: measurement + availability: "{{ has_value('sensor.esp_poolpumppower_power') }}" + state: >- + {{ + ( + states('sensor.esp_poolpumppower_power') | float(0) + / 1000 + * states('sensor.electricity_current_price') | float(0) + ) | round(6) + }} + + - name: Energy Cost Data Cupboard Left Rate + default_entity_id: sensor.energy_cost_data_cupboard_left_rate + unique_id: energy_cost_data_cupboard_left_rate + unit_of_measurement: "NZD/h" + state_class: measurement + availability: "{{ has_value('sensor.esp_datacupboardpowermon_left_power') }}" + state: >- + {{ + ( + states('sensor.esp_datacupboardpowermon_left_power') | float(0) + / 1000 + * states('sensor.electricity_current_price') | float(0) + ) | round(6) + }} + + - name: Energy Cost Data Cupboard Right Rate + default_entity_id: sensor.energy_cost_data_cupboard_right_rate + unique_id: energy_cost_data_cupboard_right_rate + unit_of_measurement: "NZD/h" + state_class: measurement + availability: "{{ has_value('sensor.esp_datacupboardpowermon_right_power') }}" + state: >- + {{ + ( + states('sensor.esp_datacupboardpowermon_right_power') | float(0) + / 1000 + * states('sensor.electricity_current_price') | float(0) + ) | round(6) + }} + + - name: Energy Cost Laundry Dryer Rate + default_entity_id: sensor.energy_cost_laundry_dryer_rate + unique_id: energy_cost_laundry_dryer_rate + unit_of_measurement: "NZD/h" + state_class: measurement + availability: "{{ has_value('sensor.esp_laundrydrypow_load_power') }}" + state: >- + {{ + ( + states('sensor.esp_laundrydrypow_load_power') | float(0) + / 1000 + * states('sensor.electricity_current_price') | float(0) + ) | round(6) + }} + + - name: Energy Cost Laundry Washing Machine Rate + default_entity_id: sensor.energy_cost_laundry_washing_machine_rate + unique_id: energy_cost_laundry_washing_machine_rate + unit_of_measurement: "NZD/h" + state_class: measurement + availability: "{{ has_value('sensor.esp_laundrywashpow_load_power') }}" + state: >- + {{ + ( + states('sensor.esp_laundrywashpow_load_power') | float(0) + / 1000 + * states('sensor.electricity_current_price') | float(0) + ) | round(6) + }} + + - name: Energy Cost Main Dishwasher Rate + default_entity_id: sensor.energy_cost_main_dishwasher_rate + unique_id: energy_cost_main_dishwasher_rate + unit_of_measurement: "NZD/h" + state_class: measurement + availability: "{{ has_value('sensor.esp_maindishwasherpower_power') }}" + state: >- + {{ + ( + states('sensor.esp_maindishwasherpower_power') | float(0) + / 1000 + * states('sensor.electricity_current_price') | float(0) + ) | round(6) + }} + + - name: Energy Cost 3D Printer Rate + default_entity_id: sensor.energy_cost_3d_printer_rate + unique_id: energy_cost_3d_printer_rate + unit_of_measurement: "NZD/h" + state_class: measurement + availability: "{{ has_value('sensor.esp_3dprinterpow_load_power') }}" + state: >- + {{ + ( + states('sensor.esp_3dprinterpow_load_power') | float(0) + / 1000 + * states('sensor.electricity_current_price') | float(0) + ) | round(6) + }} + + - name: Energy Cost Downstairs Dishwasher Rate + default_entity_id: sensor.energy_cost_downstairs_dishwasher_rate + unique_id: energy_cost_downstairs_dishwasher_rate + unit_of_measurement: "NZD/h" + state_class: measurement + availability: "{{ has_value('sensor.esp_downstdishwasher_power') }}" + state: >- + {{ + ( + states('sensor.esp_downstdishwasher_power') | float(0) + / 1000 + * states('sensor.electricity_current_price') | float(0) + ) | round(6) + }} + + - name: Energy Cost Main Fridge Rate + default_entity_id: sensor.energy_cost_main_fridge_rate + unique_id: energy_cost_main_fridge_rate + unit_of_measurement: "NZD/h" + state_class: measurement + availability: "{{ has_value('sensor.upstairs_fridge_power_x31pp_power') }}" + state: >- + {{ + ( + states('sensor.upstairs_fridge_power_x31pp_power') | float(0) + / 1000 + * states('sensor.electricity_current_price') | float(0) + ) | round(6) + }} + + - name: Energy Cost Downstairs Fridge Rate + default_entity_id: sensor.energy_cost_downstairs_fridge_rate + unique_id: energy_cost_downstairs_fridge_rate + unit_of_measurement: "NZD/h" + state_class: measurement + availability: "{{ has_value('sensor.downstairs_fridge_power_x41pp_power') }}" + state: >- + {{ + ( + states('sensor.downstairs_fridge_power_x41pp_power') | float(0) + / 1000 + * states('sensor.electricity_current_price') | float(0) + ) | round(6) + }} + + - name: Energy Cost Drinks Fridge Rate + default_entity_id: sensor.energy_cost_drinks_fridge_rate + unique_id: energy_cost_drinks_fridge_rate + unit_of_measurement: "NZD/h" + state_class: measurement + availability: "{{ has_value('sensor.drinks_fridge_power_x59pm_power') }}" + state: >- + {{ + ( + states('sensor.drinks_fridge_power_x59pm_power') | float(0) + / 1000 + * states('sensor.electricity_current_price') | float(0) + ) | round(6) + }} + + - name: Energy Cost Vertical Freezer Rate + default_entity_id: sensor.energy_cost_vertical_freezer_rate + unique_id: energy_cost_vertical_freezer_rate + unit_of_measurement: "NZD/h" + state_class: measurement + availability: "{{ has_value('sensor.vertical_freezer_power_x60pm_power') }}" + state: >- + {{ + ( + states('sensor.vertical_freezer_power_x60pm_power') | float(0) + / 1000 + * states('sensor.electricity_current_price') | float(0) + ) | round(6) + }} + + - name: Energy Cost Arcade Cabinet 1 Rate + default_entity_id: sensor.energy_cost_arcade_cabinet_1_rate + unique_id: energy_cost_arcade_cabinet_1_rate + unit_of_measurement: "NZD/h" + state_class: measurement + availability: "{{ has_value('sensor.downstairs_flat_arcade_cabinet_1_power') }}" + state: >- + {{ + ( + states('sensor.downstairs_flat_arcade_cabinet_1_power') | float(0) + / 1000 + * states('sensor.electricity_current_price') | float(0) + ) | round(6) + }} + + - name: Energy Cost Downstairs Lounge North GPO Rate + default_entity_id: sensor.energy_cost_downstairs_lounge_north_gpo_rate + unique_id: energy_cost_downstairs_lounge_north_gpo_rate + unit_of_measurement: "NZD/h" + state_class: measurement + availability: "{{ has_value('sensor.downstairs_lounge_north_gpo_x48pm_power') }}" + state: >- + {{ + ( + states('sensor.downstairs_lounge_north_gpo_x48pm_power') | float(0) + / 1000 + * states('sensor.electricity_current_price') | float(0) + ) | round(6) + }} + + - name: Electricity Total Cost + default_entity_id: sensor.electricity_total_cost + unique_id: electricity_total_cost + icon: mdi:cash-multiple + device_class: monetary + unit_of_measurement: "NZD" + state_class: total_increasing + availability: >- + {{ + has_value('sensor.electricity_grid_usage_cost') + and has_value('sensor.electricity_fixed_charges_total') + }} + state: >- + {{ + ( + states('sensor.electricity_grid_usage_cost') | float(0) + + states('sensor.electricity_fixed_charges_total') | float(0) + ) | round(5) + }} + attributes: + usage_cost: "{{ states('sensor.electricity_grid_usage_cost') | float(0) }}" + fixed_cost: "{{ states('sensor.electricity_fixed_charges_total') | float(0) }}" + gst_included: true + + - name: Energy Cost Daily Ranking Max + default_entity_id: sensor.energy_cost_daily_ranking_max + unique_id: energy_cost_daily_ranking_max + unit_of_measurement: "NZD" + state_class: measurement + state: >- + {% set values = [ + states('sensor.16a_ev_wallcharger') | float(0), + states('sensor.32a_ev_charger') | float(0), + states('sensor.underhouse_dehumidifier') | float(0), + states('sensor.pool_pump') | float(0), + states('sensor.data_cupboard_left') | float(0), + states('sensor.data_cupboard_right') | float(0), + states('sensor.laundry_dryer') | float(0), + states('sensor.washing_machine') | float(0), + states('sensor.main_dishwasher') | float(0), + states('sensor.3d_printer') | float(0), + states('sensor.downstairs_dishwasher') | float(0), + states('sensor.main_fridge') | float(0), + states('sensor.downstairs_fridge') | float(0), + states('sensor.drinks_fridge') | float(0), + states('sensor.vertical_freezer') | float(0), + states('sensor.arcade_cabinet_1') | float(0), + states('sensor.downstairs_lounge_north_gpo_x48pm') | float(0) + ] %} + {{ ([values | max * 1.1, 0.01] | max) | round(5) }} + + - name: Energy Cost Weekly Ranking Max + default_entity_id: sensor.energy_cost_weekly_ranking_max + unique_id: energy_cost_weekly_ranking_max + unit_of_measurement: "NZD" + state_class: measurement + state: >- + {% set values = [ + states('sensor.16a_ev_wallcharger_2') | float(0), + states('sensor.32a_ev_charger_2') | float(0), + states('sensor.underhouse_dehumidifier_2') | float(0), + states('sensor.pool_pump_2') | float(0), + states('sensor.data_cupboard_left_2') | float(0), + states('sensor.data_cupboard_right_2') | float(0), + states('sensor.laundry_dryer_2') | float(0), + states('sensor.washing_machine_2') | float(0), + states('sensor.main_dishwasher_2') | float(0), + states('sensor.3d_printer_2') | float(0), + states('sensor.downstairs_dishwasher_2') | float(0), + states('sensor.main_fridge_2') | float(0), + states('sensor.downstairs_fridge_2') | float(0), + states('sensor.drinks_fridge_2') | float(0), + states('sensor.vertical_freezer_2') | float(0), + states('sensor.arcade_cabinet_1_2') | float(0), + states('sensor.downstairs_lounge_north_gpo_x48pm_2') | float(0) + ] %} + {{ ([values | max * 1.1, 0.01] | max) | round(5) }} + + - name: Energy Cost Monthly Ranking Max + default_entity_id: sensor.energy_cost_monthly_ranking_max + unique_id: energy_cost_monthly_ranking_max + unit_of_measurement: "NZD" + state_class: measurement + state: >- + {% set values = [ + states('sensor.16a_ev_wallcharger_3') | float(0), + states('sensor.32a_ev_charger_3') | float(0), + states('sensor.underhouse_dehumidifier_3') | float(0), + states('sensor.pool_pump_3') | float(0), + states('sensor.data_cupboard_left_3') | float(0), + states('sensor.data_cupboard_right_3') | float(0), + states('sensor.laundry_dryer_3') | float(0), + states('sensor.washing_machine_3') | float(0), + states('sensor.main_dishwasher_3') | float(0), + states('sensor.3d_printer_3') | float(0), + states('sensor.downstairs_dishwasher_3') | float(0), + states('sensor.main_fridge_3') | float(0), + states('sensor.downstairs_fridge_3') | float(0), + states('sensor.drinks_fridge_3') | float(0), + states('sensor.vertical_freezer_3') | float(0), + states('sensor.arcade_cabinet_1_3') | float(0), + states('sensor.downstairs_lounge_north_gpo_x48pm_3') | float(0) + ] %} + {{ ([values | max * 1.1, 0.01] | max) | round(5) }} + + - triggers: + - trigger: homeassistant + event: start + - trigger: time + at: "00:00:00" + - trigger: event + event_type: event_template_reloaded + sensor: + - name: Electricity Fixed Charges Total + default_entity_id: sensor.electricity_fixed_charges_total + unique_id: electricity_fixed_charges_total + icon: mdi:calendar-cash + device_class: monetary + unit_of_measurement: "NZD" + state_class: total_increasing + state: >- + {% set rate = states('sensor.electricity_daily_charge') | float(3.4914) %} + {% set last = this.attributes.get('last_charge_date') %} + {% if last %} + {% set days = (now().date() - strptime(last, '%Y-%m-%d').date()).days %} + {{ + ( + this.state | float(0) + + ([days, 0] | max) * rate + ) | round(5) + }} + {% else %} + {{ rate | round(5) }} + {% endif %} + attributes: + last_charge_date: "{{ now().date() }}" + daily_charge: "{{ states('sensor.electricity_daily_charge') | float(3.4914) }}" + gst_included: true + +#:########################################################################################:# +# CUMULATIVE USAGE COSTS +#:########################################################################################:# + +sensor: + - platform: integration + source: sensor.electricity_grid_cost_rate + name: Electricity Grid Usage Cost + unique_id: electricity_grid_usage_cost + unit_time: h + method: left + round: 5 + max_sub_interval: + minutes: 5 + + - platform: integration + source: sensor.energy_cost_16a_ev_wallcharger_rate + name: Energy Cost 16A EV Wallcharger + unique_id: energy_cost_16a_ev_wallcharger + unit_time: h + method: left + round: 5 + max_sub_interval: + minutes: 5 + + - platform: integration + source: sensor.energy_cost_32a_ev_charger_rate + name: Energy Cost 32A EV Charger + unique_id: energy_cost_32a_ev_charger + unit_time: h + method: left + round: 5 + max_sub_interval: + minutes: 5 + + - platform: integration + source: sensor.energy_cost_underhouse_dehumidifier_rate + name: Energy Cost Underhouse Dehumidifier + unique_id: energy_cost_underhouse_dehumidifier + unit_time: h + method: left + round: 5 + max_sub_interval: + minutes: 5 + + - platform: integration + source: sensor.energy_cost_pool_pump_rate + name: Energy Cost Pool Pump + unique_id: energy_cost_pool_pump + unit_time: h + method: left + round: 5 + max_sub_interval: + minutes: 5 + + - platform: integration + source: sensor.energy_cost_data_cupboard_left_rate + name: Energy Cost Data Cupboard Left + unique_id: energy_cost_data_cupboard_left + unit_time: h + method: left + round: 5 + max_sub_interval: + minutes: 5 + + - platform: integration + source: sensor.energy_cost_data_cupboard_right_rate + name: Energy Cost Data Cupboard Right + unique_id: energy_cost_data_cupboard_right + unit_time: h + method: left + round: 5 + max_sub_interval: + minutes: 5 + + - platform: integration + source: sensor.energy_cost_laundry_dryer_rate + name: Energy Cost Laundry Dryer + unique_id: energy_cost_laundry_dryer + unit_time: h + method: left + round: 5 + max_sub_interval: + minutes: 5 + + - platform: integration + source: sensor.energy_cost_laundry_washing_machine_rate + name: Energy Cost Laundry Washing Machine + unique_id: energy_cost_laundry_washing_machine + unit_time: h + method: left + round: 5 + max_sub_interval: + minutes: 5 + + - platform: integration + source: sensor.energy_cost_main_dishwasher_rate + name: Energy Cost Main Dishwasher + unique_id: energy_cost_main_dishwasher + unit_time: h + method: left + round: 5 + max_sub_interval: + minutes: 5 + + - platform: integration + source: sensor.energy_cost_3d_printer_rate + name: Energy Cost 3D Printer + unique_id: energy_cost_3d_printer + unit_time: h + method: left + round: 5 + max_sub_interval: + minutes: 5 + + - platform: integration + source: sensor.energy_cost_downstairs_dishwasher_rate + name: Energy Cost Downstairs Dishwasher + unique_id: energy_cost_downstairs_dishwasher + unit_time: h + method: left + round: 5 + max_sub_interval: + minutes: 5 + + - platform: integration + source: sensor.energy_cost_main_fridge_rate + name: Energy Cost Main Fridge + unique_id: energy_cost_main_fridge + unit_time: h + method: left + round: 5 + max_sub_interval: + minutes: 5 + + - platform: integration + source: sensor.energy_cost_downstairs_fridge_rate + name: Energy Cost Downstairs Fridge + unique_id: energy_cost_downstairs_fridge + unit_time: h + method: left + round: 5 + max_sub_interval: + minutes: 5 + + - platform: integration + source: sensor.energy_cost_drinks_fridge_rate + name: Energy Cost Drinks Fridge + unique_id: energy_cost_drinks_fridge + unit_time: h + method: left + round: 5 + max_sub_interval: + minutes: 5 + + - platform: integration + source: sensor.energy_cost_vertical_freezer_rate + name: Energy Cost Vertical Freezer + unique_id: energy_cost_vertical_freezer + unit_time: h + method: left + round: 5 + max_sub_interval: + minutes: 5 + + - platform: integration + source: sensor.energy_cost_arcade_cabinet_1_rate + name: Energy Cost Arcade Cabinet 1 + unique_id: energy_cost_arcade_cabinet_1 + unit_time: h + method: left + round: 5 + max_sub_interval: + minutes: 5 + + - platform: integration + source: sensor.energy_cost_downstairs_lounge_north_gpo_rate + name: Energy Cost Downstairs Lounge North GPO + unique_id: energy_cost_downstairs_lounge_north_gpo + unit_time: h + method: left + round: 5 + max_sub_interval: + minutes: 5 + +#:########################################################################################:# +# APPLIANCE COST RANKING METERS +#:########################################################################################:# + +utility_meter: + energy_cost_daily_16a_ev_wallcharger: &energy_cost_daily_meter + source: sensor.energy_cost_16a_ev_wallcharger + name: 16A EV Wallcharger + cycle: daily + periodically_resetting: false + always_available: true + energy_cost_daily_32a_ev_charger: + <<: *energy_cost_daily_meter + source: sensor.energy_cost_32a_ev_charger + name: 32A EV Charger + energy_cost_daily_underhouse_dehumidifier: + <<: *energy_cost_daily_meter + source: sensor.energy_cost_underhouse_dehumidifier + name: Underhouse Dehumidifier + energy_cost_daily_pool_pump: + <<: *energy_cost_daily_meter + source: sensor.energy_cost_pool_pump + name: Pool Pump + energy_cost_daily_data_cupboard_left: + <<: *energy_cost_daily_meter + source: sensor.energy_cost_data_cupboard_left + name: Data Cupboard Left + energy_cost_daily_data_cupboard_right: + <<: *energy_cost_daily_meter + source: sensor.energy_cost_data_cupboard_right + name: Data Cupboard Right + energy_cost_daily_laundry_dryer: + <<: *energy_cost_daily_meter + source: sensor.energy_cost_laundry_dryer + name: Laundry Dryer + energy_cost_daily_laundry_washing_machine: + <<: *energy_cost_daily_meter + source: sensor.energy_cost_laundry_washing_machine + name: Washing Machine + energy_cost_daily_main_dishwasher: + <<: *energy_cost_daily_meter + source: sensor.energy_cost_main_dishwasher + name: Main Dishwasher + energy_cost_daily_3d_printer: + <<: *energy_cost_daily_meter + source: sensor.energy_cost_3d_printer + name: 3D Printer + energy_cost_daily_downstairs_dishwasher: + <<: *energy_cost_daily_meter + source: sensor.energy_cost_downstairs_dishwasher + name: Downstairs Dishwasher + energy_cost_daily_main_fridge: + <<: *energy_cost_daily_meter + source: sensor.energy_cost_main_fridge + name: Main Fridge + energy_cost_daily_downstairs_fridge: + <<: *energy_cost_daily_meter + source: sensor.energy_cost_downstairs_fridge + name: Downstairs Fridge + energy_cost_daily_drinks_fridge: + <<: *energy_cost_daily_meter + source: sensor.energy_cost_drinks_fridge + name: Drinks Fridge + energy_cost_daily_vertical_freezer: + <<: *energy_cost_daily_meter + source: sensor.energy_cost_vertical_freezer + name: Vertical Freezer + energy_cost_daily_arcade_cabinet_1: + <<: *energy_cost_daily_meter + source: sensor.energy_cost_arcade_cabinet_1 + name: Arcade Cabinet 1 + energy_cost_daily_downstairs_lounge_north_gpo: + <<: *energy_cost_daily_meter + source: sensor.energy_cost_downstairs_lounge_north_gpo + name: Downstairs Lounge North GPO (X48PM) + + energy_cost_weekly_16a_ev_wallcharger: &energy_cost_weekly_meter + source: sensor.energy_cost_16a_ev_wallcharger + name: 16A EV Wallcharger + cycle: weekly + periodically_resetting: false + always_available: true + energy_cost_weekly_32a_ev_charger: + <<: *energy_cost_weekly_meter + source: sensor.energy_cost_32a_ev_charger + name: 32A EV Charger + energy_cost_weekly_underhouse_dehumidifier: + <<: *energy_cost_weekly_meter + source: sensor.energy_cost_underhouse_dehumidifier + name: Underhouse Dehumidifier + energy_cost_weekly_pool_pump: + <<: *energy_cost_weekly_meter + source: sensor.energy_cost_pool_pump + name: Pool Pump + energy_cost_weekly_data_cupboard_left: + <<: *energy_cost_weekly_meter + source: sensor.energy_cost_data_cupboard_left + name: Data Cupboard Left + energy_cost_weekly_data_cupboard_right: + <<: *energy_cost_weekly_meter + source: sensor.energy_cost_data_cupboard_right + name: Data Cupboard Right + energy_cost_weekly_laundry_dryer: + <<: *energy_cost_weekly_meter + source: sensor.energy_cost_laundry_dryer + name: Laundry Dryer + energy_cost_weekly_laundry_washing_machine: + <<: *energy_cost_weekly_meter + source: sensor.energy_cost_laundry_washing_machine + name: Washing Machine + energy_cost_weekly_main_dishwasher: + <<: *energy_cost_weekly_meter + source: sensor.energy_cost_main_dishwasher + name: Main Dishwasher + energy_cost_weekly_3d_printer: + <<: *energy_cost_weekly_meter + source: sensor.energy_cost_3d_printer + name: 3D Printer + energy_cost_weekly_downstairs_dishwasher: + <<: *energy_cost_weekly_meter + source: sensor.energy_cost_downstairs_dishwasher + name: Downstairs Dishwasher + energy_cost_weekly_main_fridge: + <<: *energy_cost_weekly_meter + source: sensor.energy_cost_main_fridge + name: Main Fridge + energy_cost_weekly_downstairs_fridge: + <<: *energy_cost_weekly_meter + source: sensor.energy_cost_downstairs_fridge + name: Downstairs Fridge + energy_cost_weekly_drinks_fridge: + <<: *energy_cost_weekly_meter + source: sensor.energy_cost_drinks_fridge + name: Drinks Fridge + energy_cost_weekly_vertical_freezer: + <<: *energy_cost_weekly_meter + source: sensor.energy_cost_vertical_freezer + name: Vertical Freezer + energy_cost_weekly_arcade_cabinet_1: + <<: *energy_cost_weekly_meter + source: sensor.energy_cost_arcade_cabinet_1 + name: Arcade Cabinet 1 + energy_cost_weekly_downstairs_lounge_north_gpo: + <<: *energy_cost_weekly_meter + source: sensor.energy_cost_downstairs_lounge_north_gpo + name: Downstairs Lounge North GPO (X48PM) + + energy_cost_monthly_16a_ev_wallcharger: &energy_cost_monthly_meter + source: sensor.energy_cost_16a_ev_wallcharger + name: 16A EV Wallcharger + cycle: monthly + periodically_resetting: false + always_available: true + energy_cost_monthly_32a_ev_charger: + <<: *energy_cost_monthly_meter + source: sensor.energy_cost_32a_ev_charger + name: 32A EV Charger + energy_cost_monthly_underhouse_dehumidifier: + <<: *energy_cost_monthly_meter + source: sensor.energy_cost_underhouse_dehumidifier + name: Underhouse Dehumidifier + energy_cost_monthly_pool_pump: + <<: *energy_cost_monthly_meter + source: sensor.energy_cost_pool_pump + name: Pool Pump + energy_cost_monthly_data_cupboard_left: + <<: *energy_cost_monthly_meter + source: sensor.energy_cost_data_cupboard_left + name: Data Cupboard Left + energy_cost_monthly_data_cupboard_right: + <<: *energy_cost_monthly_meter + source: sensor.energy_cost_data_cupboard_right + name: Data Cupboard Right + energy_cost_monthly_laundry_dryer: + <<: *energy_cost_monthly_meter + source: sensor.energy_cost_laundry_dryer + name: Laundry Dryer + energy_cost_monthly_laundry_washing_machine: + <<: *energy_cost_monthly_meter + source: sensor.energy_cost_laundry_washing_machine + name: Washing Machine + energy_cost_monthly_main_dishwasher: + <<: *energy_cost_monthly_meter + source: sensor.energy_cost_main_dishwasher + name: Main Dishwasher + energy_cost_monthly_3d_printer: + <<: *energy_cost_monthly_meter + source: sensor.energy_cost_3d_printer + name: 3D Printer + energy_cost_monthly_downstairs_dishwasher: + <<: *energy_cost_monthly_meter + source: sensor.energy_cost_downstairs_dishwasher + name: Downstairs Dishwasher + energy_cost_monthly_main_fridge: + <<: *energy_cost_monthly_meter + source: sensor.energy_cost_main_fridge + name: Main Fridge + energy_cost_monthly_downstairs_fridge: + <<: *energy_cost_monthly_meter + source: sensor.energy_cost_downstairs_fridge + name: Downstairs Fridge + energy_cost_monthly_drinks_fridge: + <<: *energy_cost_monthly_meter + source: sensor.energy_cost_drinks_fridge + name: Drinks Fridge + energy_cost_monthly_vertical_freezer: + <<: *energy_cost_monthly_meter + source: sensor.energy_cost_vertical_freezer + name: Vertical Freezer + energy_cost_monthly_arcade_cabinet_1: + <<: *energy_cost_monthly_meter + source: sensor.energy_cost_arcade_cabinet_1 + name: Arcade Cabinet 1 + energy_cost_monthly_downstairs_lounge_north_gpo: + <<: *energy_cost_monthly_meter + source: sensor.energy_cost_downstairs_lounge_north_gpo + name: Downstairs Lounge North GPO (X48PM) diff --git a/packages/free_power_time_actions.yaml b/packages/free_power_time_actions.yaml index a052665..74e3f22 100644 --- a/packages/free_power_time_actions.yaml +++ b/packages/free_power_time_actions.yaml @@ -2,6 +2,11 @@ # PACKAGE: Free Power Time Automation # #:########################################################################################:# # VERSION: +# 1.2.1 - 2026-08-17 +# - Allow the configured end-time trigger to run without waiting for the +# Free Power Time Active template sensor to update at the same instant. +# The inactive-window check now applies only to startup catch-up. +# # 1.2.0 - 2026-07-24 # - Added startup catch-up to end_actions: when HA starts outside the # free power window, the end actions (chargers off, dehumidifier off) @@ -321,11 +326,15 @@ automation: triggers: - trigger: time at: input_datetime.free_power_end_time + id: scheduled_end - trigger: homeassistant event: start + id: startup conditions: - - condition: state - entity_id: binary_sensor.free_power_time_active - state: "off" + # The scheduled end must not race the template sensor's minute update. + # Startup catch-up still runs only outside the free power window. + - condition: template + value_template: >- + {{ trigger.id == 'scheduled_end' or is_state('binary_sensor.free_power_time_active', 'off') }} actions: - action: script.free_power_end_actions diff --git a/packages/fridge_freezer_monitoring.yaml b/packages/fridge_freezer_monitoring.yaml new file mode 100644 index 0000000..3dcfc40 --- /dev/null +++ b/packages/fridge_freezer_monitoring.yaml @@ -0,0 +1,914 @@ +#:########################################################################################:# +# PACKAGE: Fridge and Freezer Monitoring +# FILE: packages/fridge_freezer_monitoring.yaml +# VERSION: v1.10.0 2026-08-29 +# - Adds Downstairs Freezer temperature, battery, door, humidity, and shared +# Downstairs Fridge/Freezer plug monitoring. +# - Uses a four-hour sustained low-draw power-loss rule for all monitored +# fridges and freezers, including the shared Drinks Fridge/Freezer plug. +# - v1.8.4 2026-08-24: Flags a Drinks Fridge power loss only after six +# continuous hours below 1 W. +# - v1.8.3 2026-08-24: Excludes normal Drinks Fridge compressor-off cycles +# from power alerts. +# - v1.8.2 2026-08-24: Widens Drinks Fridge and Vertical Freezer adaptive +# temperature ceilings to accommodate confirmed normal compressor cycles. +# - v1.8.1 2026-08-24: Excludes normal Vertical Freezer compressor-off cycles +# from power alerts and widens its learned temperature allowance. +# - v1.8.0 2026-08-24: Adds Drinks Fridge and Vertical Freezer plug monitoring. +# - Adds illuminance-based door monitoring for the Downstairs Fridge. +# - Adds Drinks Fridge door detection from its illuminance sensor. +# - Makes an open door an issue after seven minutes and delays temperature +# alerts while the door is open or cooling recovers after closure. +# - v1.5.0 2026-08-22 +# - Requires five minutes of sub-1 W draw before reporting Main Kitchen Fridge power loss. +# - Moved Main Kitchen Fridge power monitoring to the Zigbee X31PP plug. +# - v1.3.0 2026-08-17: Uses the calibrated Main Kitchen Fridge temperature entity throughout. +# - Uses the calibrated Main Kitchen Fridge temperature entity throughout. +# - Added adaptive temperature, battery, humidity, and power monitoring for +# the Downstairs Fridge. +# - v1.1.0 2026-08-16: Reduced the adaptive temperature margin and issue persistence time. +#:########################################################################################:# +# PURPOSE: +# Detect missing monitoring, low batteries, loss of Main Fridge power, and +# abnormal warming, including door-aware handling where a sensor is fitted. +#:########################################################################################:# +# BEHAVIOUR: +# - Learns a continuously rolling seven-day average and 95th percentile. +# - Limits each learned threshold with an appliance-specific safety maximum. +# - Measures the temperature change rate over a smoothed 30-minute window. +# - Requires an issue condition to persist for one minute, except Main Kitchen +# Fridge low-power draw, which persists for five minutes. +# - Treats the Drinks and Downstairs Fridges as open at 10 lx or higher. An +# open door is an issue after seven minutes, while temperature alerting +# stays deferred through a 15-minute post-close recovery window. +# - Exposes one issue binary sensor per appliance and one summary sensor. +#:########################################################################################:# +# NOTES: +# - Learned thresholds use the lower of 95th percentile + 0.5 C or the fixed +# safety limit, so a cooling failure cannot gradually become normal. +# - A rise rate of at least 2 C/hour labels an over-temperature condition as +# possible open-door warming; slower warming is labelled loss of cooling. +# - Main Fridge power below 1 W is treated as loss only after five minutes to +# avoid normal compressor-off periods; unplugged or unavailable monitoring +# remains an issue after one minute. +# - Main Fridge temperature is adjusted by -0.84 C to match the reference +# thermometer. +# - Wine-fridge ESPHome telemetry is intentionally excluded. +#:########################################################################################:# +# DEPENDENCIES: +# - Seven configured fridge/freezer temperature and battery monitor pairs. +# - switch.upstairs_fridge_power_x31pp +# - sensor.upstairs_fridge_power_x31pp_power +# - switch.downstairs_fridge_power_x41pp +# - sensor.downstairs_fridge_power_x41pp_power +# - switch.drinks_fridge_power_x59pm +# - sensor.drinks_fridge_power_x59pm_power +# - switch.vertical_freezer_power_x60pm +# - sensor.vertical_freezer_power_x60pm_power +# - sensor.drinks_fridge_light_sensor_x35ls_illuminance +# - sensor.downstairs_fridge_light_sensor_x58ls_illuminance +# - sensor.downstairs_freezer_light_sensor_x61ls_illuminance +#:########################################################################################:# + +sensor: + #:######################################################################################:# + # MAIN KITCHEN FRIDGE + #:######################################################################################:# + - platform: statistics + name: "Main Kitchen Fridge Temperature Average 7 Days" + unique_id: main_kitchen_fridge_temperature_average_7_days + entity_id: sensor.main_kitchen_fridge_temperature_calibrated + state_characteristic: average_step + max_age: + days: 7 + precision: 1 + + - platform: statistics + name: "Main Kitchen Fridge Temperature 95th Percentile 7 Days" + unique_id: main_kitchen_fridge_temperature_95th_percentile_7_days + entity_id: sensor.main_kitchen_fridge_temperature_calibrated + state_characteristic: percentile + percentile: 95 + max_age: + days: 7 + precision: 1 + + - platform: derivative + name: "Main Kitchen Fridge Temperature Change Rate" + unique_id: main_kitchen_fridge_temperature_change_rate + source: sensor.main_kitchen_fridge_temperature_calibrated + unit_time: h + time_window: "00:30:00" + max_sub_interval: "00:05:00" + round: 1 + + #:######################################################################################:# + # DRINKS FRIDGE + #:######################################################################################:# + - platform: statistics + name: "Drinks Fridge Temperature Average 7 Days" + unique_id: drinks_fridge_temperature_average_7_days + entity_id: sensor.drinks_fridge_environment_lcd_btt01_temperature + state_characteristic: average_step + max_age: + days: 7 + precision: 1 + + - platform: statistics + name: "Drinks Fridge Temperature 95th Percentile 7 Days" + unique_id: drinks_fridge_temperature_95th_percentile_7_days + entity_id: sensor.drinks_fridge_environment_lcd_btt01_temperature + state_characteristic: percentile + percentile: 95 + max_age: + days: 7 + precision: 1 + + - platform: derivative + name: "Drinks Fridge Temperature Change Rate" + unique_id: drinks_fridge_temperature_change_rate + source: sensor.drinks_fridge_environment_lcd_btt01_temperature + unit_time: h + time_window: "00:30:00" + max_sub_interval: "00:05:00" + round: 1 + + #:######################################################################################:# + # DOWNSTAIRS FRIDGE + #:######################################################################################:# + - platform: statistics + name: "Downstairs Fridge Temperature Average 7 Days" + unique_id: downstairs_fridge_temperature_average_7_days + entity_id: sensor.downstairs_fridge_temperature_x43ts_temperature + state_characteristic: average_step + max_age: + days: 7 + precision: 1 + + - platform: statistics + name: "Downstairs Fridge Temperature 95th Percentile 7 Days" + unique_id: downstairs_fridge_temperature_95th_percentile_7_days + entity_id: sensor.downstairs_fridge_temperature_x43ts_temperature + state_characteristic: percentile + percentile: 95 + max_age: + days: 7 + precision: 1 + + - platform: derivative + name: "Downstairs Fridge Temperature Change Rate" + unique_id: downstairs_fridge_temperature_change_rate + source: sensor.downstairs_fridge_temperature_x43ts_temperature + unit_time: h + time_window: "00:30:00" + max_sub_interval: "00:05:00" + round: 1 + + #:######################################################################################:# + # DOWNSTAIRS FREEZER + #:######################################################################################:# + - platform: statistics + name: "Downstairs Freezer Temperature Average 7 Days" + unique_id: downstairs_freezer_temperature_average_7_days + entity_id: sensor.downstairs_freezer_temperature_x62ts_temperature + state_characteristic: average_step + max_age: + days: 7 + precision: 1 + + - platform: statistics + name: "Downstairs Freezer Temperature 95th Percentile 7 Days" + unique_id: downstairs_freezer_temperature_95th_percentile_7_days + entity_id: sensor.downstairs_freezer_temperature_x62ts_temperature + state_characteristic: percentile + percentile: 95 + max_age: + days: 7 + precision: 1 + + - platform: derivative + name: "Downstairs Freezer Temperature Change Rate" + unique_id: downstairs_freezer_temperature_change_rate + source: sensor.downstairs_freezer_temperature_x62ts_temperature + unit_time: h + time_window: "00:30:00" + max_sub_interval: "00:05:00" + round: 1 + + #:######################################################################################:# + # WINE FRIDGE + #:######################################################################################:# + - platform: statistics + name: "Wine Fridge Temperature Average 7 Days" + unique_id: wine_fridge_temperature_average_7_days + entity_id: sensor.lcd_temp_humidity_btt04_temperature + state_characteristic: average_step + max_age: + days: 7 + precision: 1 + + - platform: statistics + name: "Wine Fridge Temperature 95th Percentile 7 Days" + unique_id: wine_fridge_temperature_95th_percentile_7_days + entity_id: sensor.lcd_temp_humidity_btt04_temperature + state_characteristic: percentile + percentile: 95 + max_age: + days: 7 + precision: 1 + + - platform: derivative + name: "Wine Fridge Temperature Change Rate" + unique_id: wine_fridge_temperature_change_rate + source: sensor.lcd_temp_humidity_btt04_temperature + unit_time: h + time_window: "00:30:00" + max_sub_interval: "00:05:00" + round: 1 + + #:######################################################################################:# + # DRINKS FREEZER + #:######################################################################################:# + - platform: statistics + name: "Drinks Freezer Temperature Average 7 Days" + unique_id: drinks_freezer_temperature_average_7_days + entity_id: sensor.drinks_freezer_environment_lcd_btt02_temperature + state_characteristic: average_step + max_age: + days: 7 + precision: 1 + + - platform: statistics + name: "Drinks Freezer Temperature 95th Percentile 7 Days" + unique_id: drinks_freezer_temperature_95th_percentile_7_days + entity_id: sensor.drinks_freezer_environment_lcd_btt02_temperature + state_characteristic: percentile + percentile: 95 + max_age: + days: 7 + precision: 1 + + - platform: derivative + name: "Drinks Freezer Temperature Change Rate" + unique_id: drinks_freezer_temperature_change_rate + source: sensor.drinks_freezer_environment_lcd_btt02_temperature + unit_time: h + time_window: "00:30:00" + max_sub_interval: "00:05:00" + round: 1 + + #:######################################################################################:# + # VERTICAL FREEZER + #:######################################################################################:# + - platform: statistics + name: "Vertical Freezer Temperature Average 7 Days" + unique_id: vertical_freezer_temperature_average_7_days + entity_id: sensor.lcd_temp_humidity_btt03_temperature + state_characteristic: average_step + max_age: + days: 7 + precision: 1 + + - platform: statistics + name: "Vertical Freezer Temperature 95th Percentile 7 Days" + unique_id: vertical_freezer_temperature_95th_percentile_7_days + entity_id: sensor.lcd_temp_humidity_btt03_temperature + state_characteristic: percentile + percentile: 95 + max_age: + days: 7 + precision: 1 + + - platform: derivative + name: "Vertical Freezer Temperature Change Rate" + unique_id: vertical_freezer_temperature_change_rate + source: sensor.lcd_temp_humidity_btt03_temperature + unit_time: h + time_window: "00:30:00" + max_sub_interval: "00:05:00" + round: 1 + +template: + #:######################################################################################:# + # DOOR DETECTION + #:######################################################################################:# + - binary_sensor: + - name: "Drinks Fridge Door Open" + unique_id: drinks_fridge_door_open + device_class: door + state: >- + {{ + has_value('sensor.drinks_fridge_light_sensor_x35ls_illuminance') + and (states('sensor.drinks_fridge_light_sensor_x35ls_illuminance') | float(0)) >= 10 + }} + + # Retain the grace period after closure so the fridge can start cooling. + - name: "Drinks Fridge Temperature Recovery Grace" + unique_id: drinks_fridge_temperature_recovery_grace + delay_off: "00:15:00" + state: "{{ is_state('binary_sensor.drinks_fridge_door_open', 'on') }}" + + - name: "Drinks Fridge Door Open Too Long" + unique_id: drinks_fridge_door_open_too_long + device_class: problem + delay_on: "00:07:00" + state: "{{ is_state('binary_sensor.drinks_fridge_door_open', 'on') }}" + + - name: "Downstairs Fridge Door Open" + unique_id: downstairs_fridge_door_open + device_class: door + state: >- + {{ + has_value('sensor.downstairs_fridge_light_sensor_x58ls_illuminance') + and (states('sensor.downstairs_fridge_light_sensor_x58ls_illuminance') | float(0)) >= 10 + }} + + # Retain the grace period after closure so the fridge can start cooling. + - name: "Downstairs Fridge Temperature Recovery Grace" + unique_id: downstairs_fridge_temperature_recovery_grace + delay_off: "00:15:00" + state: "{{ is_state('binary_sensor.downstairs_fridge_door_open', 'on') }}" + + - name: "Downstairs Fridge Door Open Too Long" + unique_id: downstairs_fridge_door_open_too_long + device_class: problem + delay_on: "00:07:00" + state: "{{ is_state('binary_sensor.downstairs_fridge_door_open', 'on') }}" + + - name: "Downstairs Freezer Door Open" + unique_id: downstairs_freezer_door_open + device_class: door + state: >- + {{ + has_value('sensor.downstairs_freezer_light_sensor_x61ls_illuminance') + and (states('sensor.downstairs_freezer_light_sensor_x61ls_illuminance') | float(0)) >= 10 + }} + + # Retain the grace period after closure so the freezer can start cooling. + - name: "Downstairs Freezer Temperature Recovery Grace" + unique_id: downstairs_freezer_temperature_recovery_grace + delay_off: "00:15:00" + state: "{{ is_state('binary_sensor.downstairs_freezer_door_open', 'on') }}" + + - name: "Downstairs Freezer Door Open Too Long" + unique_id: downstairs_freezer_door_open_too_long + device_class: problem + delay_on: "00:07:00" + state: "{{ is_state('binary_sensor.downstairs_freezer_door_open', 'on') }}" + + #:######################################################################################:# + # APPLIANCE ISSUE SENSORS + #:######################################################################################:# + - binary_sensor: + - name: "Main Kitchen Fridge Power Draw Lost" + unique_id: main_kitchen_fridge_power_draw_lost + device_class: problem + delay_on: "04:00:00" + state: >- + {{ + is_state('switch.upstairs_fridge_power_x31pp', 'on') + and has_value('sensor.upstairs_fridge_power_x31pp_power') + and (states('sensor.upstairs_fridge_power_x31pp_power') | float(0)) < 1 + }} + + # A compressor-off interval is normal; measure the uninterrupted idle time + # explicitly so a template reload cannot restore this as an active fault. + - name: "Drinks Fridge Power Draw Lost" + unique_id: drinks_fridge_power_draw_lost + device_class: problem + state: >- + {% set power = states('sensor.drinks_fridge_power_x59pm_power') | float(none) %} + {% set changed = states.sensor.drinks_fridge_power_x59pm_power.last_changed %} + {{ + is_state('switch.drinks_fridge_power_x59pm', 'on') + and power is not none + and power < 1 + and (now() - changed).total_seconds() >= 4 * 60 * 60 + }} + + - name: "Downstairs Fridge Power Draw Lost" + unique_id: downstairs_fridge_power_draw_lost + device_class: problem + state: >- + {% set power = states('sensor.downstairs_fridge_power_x41pp_power') | float(none) %} + {% set changed = states.sensor.downstairs_fridge_power_x41pp_power.last_changed %} + {{ + is_state('switch.downstairs_fridge_power_x41pp', 'on') + and power is not none + and power < 1 + and (now() - changed).total_seconds() >= 4 * 60 * 60 + }} + + - name: "Vertical Freezer Power Draw Lost" + unique_id: vertical_freezer_power_draw_lost + device_class: problem + state: >- + {% set power = states('sensor.vertical_freezer_power_x60pm_power') | float(none) %} + {% set changed = states.sensor.vertical_freezer_power_x60pm_power.last_changed %} + {{ + is_state('switch.vertical_freezer_power_x60pm', 'on') + and power is not none + and power < 1 + and (now() - changed).total_seconds() >= 4 * 60 * 60 + }} + + - name: "Main Kitchen Fridge Issue" + unique_id: main_kitchen_fridge_issue + device_class: problem + delay_on: "00:01:00" + state: >- + {% set temperature_missing = not has_value('sensor.main_kitchen_fridge_temperature_calibrated') %} + {% set battery_missing = not has_value('sensor.unk_manufacturer_unk_model_battery') %} + {% set power_missing = not has_value('sensor.upstairs_fridge_power_x31pp_power') %} + {% set percentile = states('sensor.main_kitchen_fridge_temperature_95th_percentile_7_days') | float(none) %} + {% set threshold = [10, percentile + 0.5] | min if percentile is not none else 10 %} + {{ + temperature_missing + or battery_missing + or (states('sensor.unk_manufacturer_unk_model_battery') | float(-1)) <= 20 + or (not temperature_missing and (states('sensor.main_kitchen_fridge_temperature_calibrated') | float(0)) > threshold) + or states('switch.upstairs_fridge_power_x31pp') != 'on' + or power_missing + or is_state('binary_sensor.main_kitchen_fridge_power_draw_lost', 'on') + }} + attributes: + appliance: "Main Kitchen Fridge" + issues: >- + {% set ns = namespace(items=[]) %} + {% set temperature_missing = not has_value('sensor.main_kitchen_fridge_temperature_calibrated') %} + {% set battery_missing = not has_value('sensor.unk_manufacturer_unk_model_battery') %} + {% set power_missing = not has_value('sensor.upstairs_fridge_power_x31pp_power') %} + {% set percentile = states('sensor.main_kitchen_fridge_temperature_95th_percentile_7_days') | float(none) %} + {% set threshold = [10, percentile + 0.5] | min if percentile is not none else 10 %} + {% if temperature_missing or battery_missing %} + {% set ns.items = ns.items + ['Monitor offline'] %} + {% endif %} + {% if not battery_missing and (states('sensor.unk_manufacturer_unk_model_battery') | float(-1)) <= 20 %} + {% set ns.items = ns.items + ['Low monitor battery'] %} + {% endif %} + {% if states('switch.upstairs_fridge_power_x31pp') in ['unknown', 'unavailable'] or power_missing %} + {% set ns.items = ns.items + ['Power monitoring unavailable'] %} + {% elif not is_state('switch.upstairs_fridge_power_x31pp', 'on') %} + {% set ns.items = ns.items + ['Power switched off'] %} + {% elif is_state('binary_sensor.main_kitchen_fridge_power_draw_lost', 'on') %} + {% set ns.items = ns.items + ['Power lost - no power draw'] %} + {% endif %} + {% if not temperature_missing and (states('sensor.main_kitchen_fridge_temperature_calibrated') | float(0)) > threshold %} + {% if (states('sensor.main_kitchen_fridge_temperature_change_rate') | float(0)) >= 2 %} + {% set ns.items = ns.items + ['Warming rapidly - possible open door'] %} + {% else %} + {% set ns.items = ns.items + ['Temperature too high - possible loss of cooling'] %} + {% endif %} + {% endif %} + {{ ns.items }} + temperature: "{{ states('sensor.main_kitchen_fridge_temperature_calibrated') }}" + average_7_days: "{{ states('sensor.main_kitchen_fridge_temperature_average_7_days') }}" + alert_threshold: >- + {% set percentile = states('sensor.main_kitchen_fridge_temperature_95th_percentile_7_days') | float(none) %} + {{ [10, percentile + 0.5] | min if percentile is not none else 10 }} + change_rate: "{{ states('sensor.main_kitchen_fridge_temperature_change_rate') }}" + battery: "{{ states('sensor.unk_manufacturer_unk_model_battery') }}" + power: "{{ states('sensor.upstairs_fridge_power_x31pp_power') }}" + + - name: "Drinks Fridge Issue" + unique_id: drinks_fridge_issue + device_class: problem + delay_on: "00:01:00" + state: >- + {% set temperature_missing = not has_value('sensor.drinks_fridge_environment_lcd_btt01_temperature') %} + {% set battery_missing = not has_value('sensor.drinks_fridge_environment_lcd_btt01_battery') %} + {% set power_missing = not has_value('sensor.drinks_fridge_power_x59pm_power') %} + {% set percentile = states('sensor.drinks_fridge_temperature_95th_percentile_7_days') | float(none) %} + {% set threshold = [10, percentile + 3] | min if percentile is not none else 10 %} + {{ + temperature_missing + or battery_missing + or (states('sensor.drinks_fridge_environment_lcd_btt01_battery') | float(-1)) <= 20 + or states('switch.drinks_fridge_power_x59pm') != 'on' + or power_missing + or is_state('binary_sensor.drinks_fridge_power_draw_lost', 'on') + or is_state('binary_sensor.drinks_fridge_door_open_too_long', 'on') + or ( + not temperature_missing + and not is_state('binary_sensor.drinks_fridge_temperature_recovery_grace', 'on') + and (states('sensor.drinks_fridge_environment_lcd_btt01_temperature') | float(0)) > threshold + ) + }} + attributes: + appliance: "Drinks Fridge" + issues: >- + {% set ns = namespace(items=[]) %} + {% set temperature_missing = not has_value('sensor.drinks_fridge_environment_lcd_btt01_temperature') %} + {% set battery_missing = not has_value('sensor.drinks_fridge_environment_lcd_btt01_battery') %} + {% set power_missing = not has_value('sensor.drinks_fridge_power_x59pm_power') %} + {% set percentile = states('sensor.drinks_fridge_temperature_95th_percentile_7_days') | float(none) %} + {% set threshold = [10, percentile + 3] | min if percentile is not none else 10 %} + {% if temperature_missing or battery_missing %} + {% set ns.items = ns.items + ['Monitor offline'] %} + {% endif %} + {% if not battery_missing and (states('sensor.drinks_fridge_environment_lcd_btt01_battery') | float(-1)) <= 20 %} + {% set ns.items = ns.items + ['Low monitor battery'] %} + {% endif %} + {% if states('switch.drinks_fridge_power_x59pm') in ['unknown', 'unavailable'] or power_missing %} + {% set ns.items = ns.items + ['Power monitoring unavailable'] %} + {% elif not is_state('switch.drinks_fridge_power_x59pm', 'on') %} + {% set ns.items = ns.items + ['Power switched off'] %} + {% elif is_state('binary_sensor.drinks_fridge_power_draw_lost', 'on') %} + {% set ns.items = ns.items + ['Power lost - no power draw for 4 hours'] %} + {% endif %} + {% if is_state('binary_sensor.drinks_fridge_door_open_too_long', 'on') %} + {% set ns.items = ns.items + ['Door open too long'] %} + {% elif not temperature_missing and is_state('binary_sensor.drinks_fridge_temperature_recovery_grace', 'on') %} + {% set ns.items = ns.items + ['Temperature alert delayed - door recently open'] %} + {% elif not temperature_missing and (states('sensor.drinks_fridge_environment_lcd_btt01_temperature') | float(0)) > threshold %} + {% if (states('sensor.drinks_fridge_temperature_change_rate') | float(0)) >= 2 %} + {% set ns.items = ns.items + ['Warming rapidly - possible open door'] %} + {% else %} + {% set ns.items = ns.items + ['Temperature too high - possible loss of cooling'] %} + {% endif %} + {% endif %} + {{ ns.items }} + temperature: "{{ states('sensor.drinks_fridge_environment_lcd_btt01_temperature') }}" + average_7_days: "{{ states('sensor.drinks_fridge_temperature_average_7_days') }}" + alert_threshold: >- + {% set percentile = states('sensor.drinks_fridge_temperature_95th_percentile_7_days') | float(none) %} + {{ [10, percentile + 3] | min if percentile is not none else 10 }} + change_rate: "{{ states('sensor.drinks_fridge_temperature_change_rate') }}" + battery: "{{ states('sensor.drinks_fridge_environment_lcd_btt01_battery') }}" + power: "{{ states('sensor.drinks_fridge_power_x59pm_power') }}" + door_open: "{{ is_state('binary_sensor.drinks_fridge_door_open', 'on') }}" + illuminance: "{{ states('sensor.drinks_fridge_light_sensor_x35ls_illuminance') }}" + + - name: "Wine Fridge Issue" + unique_id: wine_fridge_issue + device_class: problem + delay_on: "00:01:00" + state: >- + {% set temperature_missing = not has_value('sensor.lcd_temp_humidity_btt04_temperature') %} + {% set battery_missing = not has_value('sensor.lcd_temp_humidity_btt04_battery') %} + {% set percentile = states('sensor.wine_fridge_temperature_95th_percentile_7_days') | float(none) %} + {% set threshold = [9, percentile + 0.5] | min if percentile is not none else 9 %} + {{ + temperature_missing + or battery_missing + or (states('sensor.lcd_temp_humidity_btt04_battery') | float(-1)) <= 20 + or (not temperature_missing and (states('sensor.lcd_temp_humidity_btt04_temperature') | float(0)) > threshold) + }} + attributes: + appliance: "Wine Fridge" + issues: >- + {% set ns = namespace(items=[]) %} + {% set temperature_missing = not has_value('sensor.lcd_temp_humidity_btt04_temperature') %} + {% set battery_missing = not has_value('sensor.lcd_temp_humidity_btt04_battery') %} + {% set percentile = states('sensor.wine_fridge_temperature_95th_percentile_7_days') | float(none) %} + {% set threshold = [9, percentile + 0.5] | min if percentile is not none else 9 %} + {% if temperature_missing or battery_missing %} + {% set ns.items = ns.items + ['Monitor offline'] %} + {% endif %} + {% if not battery_missing and (states('sensor.lcd_temp_humidity_btt04_battery') | float(-1)) <= 20 %} + {% set ns.items = ns.items + ['Low monitor battery'] %} + {% endif %} + {% if not temperature_missing and (states('sensor.lcd_temp_humidity_btt04_temperature') | float(0)) > threshold %} + {% if (states('sensor.wine_fridge_temperature_change_rate') | float(0)) >= 2 %} + {% set ns.items = ns.items + ['Warming rapidly - possible open door'] %} + {% else %} + {% set ns.items = ns.items + ['Temperature too high - possible loss of cooling'] %} + {% endif %} + {% endif %} + {{ ns.items }} + temperature: "{{ states('sensor.lcd_temp_humidity_btt04_temperature') }}" + average_7_days: "{{ states('sensor.wine_fridge_temperature_average_7_days') }}" + alert_threshold: >- + {% set percentile = states('sensor.wine_fridge_temperature_95th_percentile_7_days') | float(none) %} + {{ [9, percentile + 0.5] | min if percentile is not none else 9 }} + change_rate: "{{ states('sensor.wine_fridge_temperature_change_rate') }}" + battery: "{{ states('sensor.lcd_temp_humidity_btt04_battery') }}" + + - name: "Downstairs Fridge Issue" + unique_id: downstairs_fridge_issue + device_class: problem + delay_on: "00:01:00" + state: >- + {% set temperature_missing = not has_value('sensor.downstairs_fridge_temperature_x43ts_temperature') %} + {% set battery_missing = not has_value('sensor.downstairs_fridge_temperature_x43ts_battery') %} + {% set power_missing = not has_value('sensor.downstairs_fridge_power_x41pp_power') %} + {% set percentile = states('sensor.downstairs_fridge_temperature_95th_percentile_7_days') | float(none) %} + {% set threshold = [10, percentile + 0.5] | min if percentile is not none else 10 %} + {{ + temperature_missing + or battery_missing + or (states('sensor.downstairs_fridge_temperature_x43ts_battery') | float(-1)) <= 20 + or is_state('binary_sensor.downstairs_fridge_door_open_too_long', 'on') + or ( + not temperature_missing + and not is_state('binary_sensor.downstairs_fridge_temperature_recovery_grace', 'on') + and (states('sensor.downstairs_fridge_temperature_x43ts_temperature') | float(0)) > threshold + ) + or states('switch.downstairs_fridge_power_x41pp') != 'on' + or power_missing + or is_state('binary_sensor.downstairs_fridge_power_draw_lost', 'on') + }} + attributes: + appliance: "Downstairs Fridge" + issues: >- + {% set ns = namespace(items=[]) %} + {% set temperature_missing = not has_value('sensor.downstairs_fridge_temperature_x43ts_temperature') %} + {% set battery_missing = not has_value('sensor.downstairs_fridge_temperature_x43ts_battery') %} + {% set power_missing = not has_value('sensor.downstairs_fridge_power_x41pp_power') %} + {% set percentile = states('sensor.downstairs_fridge_temperature_95th_percentile_7_days') | float(none) %} + {% set threshold = [10, percentile + 0.5] | min if percentile is not none else 10 %} + {% if temperature_missing or battery_missing %} + {% set ns.items = ns.items + ['Monitor offline'] %} + {% endif %} + {% if not battery_missing and (states('sensor.downstairs_fridge_temperature_x43ts_battery') | float(-1)) <= 20 %} + {% set ns.items = ns.items + ['Low monitor battery'] %} + {% endif %} + {% if states('switch.downstairs_fridge_power_x41pp') in ['unknown', 'unavailable'] or power_missing %} + {% set ns.items = ns.items + ['Power monitoring unavailable'] %} + {% elif not is_state('switch.downstairs_fridge_power_x41pp', 'on') %} + {% set ns.items = ns.items + ['Power switched off'] %} + {% elif is_state('binary_sensor.downstairs_fridge_power_draw_lost', 'on') %} + {% set ns.items = ns.items + ['Power lost - no power draw for 4 hours'] %} + {% endif %} + {% if is_state('binary_sensor.downstairs_fridge_door_open_too_long', 'on') %} + {% set ns.items = ns.items + ['Door open too long'] %} + {% elif not temperature_missing and is_state('binary_sensor.downstairs_fridge_temperature_recovery_grace', 'on') %} + {% set ns.items = ns.items + ['Temperature alert delayed - door recently open'] %} + {% elif not temperature_missing and (states('sensor.downstairs_fridge_temperature_x43ts_temperature') | float(0)) > threshold %} + {% if (states('sensor.downstairs_fridge_temperature_change_rate') | float(0)) >= 2 %} + {% set ns.items = ns.items + ['Warming rapidly - possible open door'] %} + {% else %} + {% set ns.items = ns.items + ['Temperature too high - possible loss of cooling'] %} + {% endif %} + {% endif %} + {{ ns.items }} + temperature: "{{ states('sensor.downstairs_fridge_temperature_x43ts_temperature') }}" + humidity: "{{ states('sensor.downstairs_fridge_temperature_x43ts_humidity') }}" + average_7_days: "{{ states('sensor.downstairs_fridge_temperature_average_7_days') }}" + alert_threshold: >- + {% set percentile = states('sensor.downstairs_fridge_temperature_95th_percentile_7_days') | float(none) %} + {{ [10, percentile + 0.5] | min if percentile is not none else 10 }} + change_rate: "{{ states('sensor.downstairs_fridge_temperature_change_rate') }}" + battery: "{{ states('sensor.downstairs_fridge_temperature_x43ts_battery') }}" + power: "{{ states('sensor.downstairs_fridge_power_x41pp_power') }}" + door_open: "{{ is_state('binary_sensor.downstairs_fridge_door_open', 'on') }}" + illuminance: "{{ states('sensor.downstairs_fridge_light_sensor_x58ls_illuminance') }}" + + - name: "Downstairs Freezer Issue" + unique_id: downstairs_freezer_issue + device_class: problem + delay_on: "00:01:00" + state: >- + {% set temperature_missing = not has_value('sensor.downstairs_freezer_temperature_x62ts_temperature') %} + {% set battery_missing = not has_value('sensor.downstairs_freezer_temperature_x62ts_battery') %} + {% set power_missing = not has_value('sensor.downstairs_fridge_power_x41pp_power') %} + {% set percentile = states('sensor.downstairs_freezer_temperature_95th_percentile_7_days') | float(none) %} + {% set threshold = [-5, percentile + 0.5] | min if percentile is not none else -5 %} + {{ + temperature_missing + or battery_missing + or (states('sensor.downstairs_freezer_temperature_x62ts_battery') | float(-1)) <= 20 + or is_state('binary_sensor.downstairs_freezer_door_open_too_long', 'on') + or ( + not temperature_missing + and not is_state('binary_sensor.downstairs_freezer_temperature_recovery_grace', 'on') + and (states('sensor.downstairs_freezer_temperature_x62ts_temperature') | float(0)) > threshold + ) + or states('switch.downstairs_fridge_power_x41pp') != 'on' + or power_missing + or is_state('binary_sensor.downstairs_fridge_power_draw_lost', 'on') + }} + attributes: + appliance: "Downstairs Freezer" + issues: >- + {% set ns = namespace(items=[]) %} + {% set temperature_missing = not has_value('sensor.downstairs_freezer_temperature_x62ts_temperature') %} + {% set battery_missing = not has_value('sensor.downstairs_freezer_temperature_x62ts_battery') %} + {% set power_missing = not has_value('sensor.downstairs_fridge_power_x41pp_power') %} + {% set percentile = states('sensor.downstairs_freezer_temperature_95th_percentile_7_days') | float(none) %} + {% set threshold = [-5, percentile + 0.5] | min if percentile is not none else -5 %} + {% if temperature_missing or battery_missing %} + {% set ns.items = ns.items + ['Monitor offline'] %} + {% endif %} + {% if not battery_missing and (states('sensor.downstairs_freezer_temperature_x62ts_battery') | float(-1)) <= 20 %} + {% set ns.items = ns.items + ['Low monitor battery'] %} + {% endif %} + {% if states('switch.downstairs_fridge_power_x41pp') in ['unknown', 'unavailable'] or power_missing %} + {% set ns.items = ns.items + ['Shared power monitoring unavailable'] %} + {% elif not is_state('switch.downstairs_fridge_power_x41pp', 'on') %} + {% set ns.items = ns.items + ['Shared power switched off'] %} + {% elif is_state('binary_sensor.downstairs_fridge_power_draw_lost', 'on') %} + {% set ns.items = ns.items + ['Shared power lost - no power draw for 4 hours'] %} + {% endif %} + {% if is_state('binary_sensor.downstairs_freezer_door_open_too_long', 'on') %} + {% set ns.items = ns.items + ['Door open too long'] %} + {% elif not temperature_missing and is_state('binary_sensor.downstairs_freezer_temperature_recovery_grace', 'on') %} + {% set ns.items = ns.items + ['Temperature alert delayed - door recently open'] %} + {% elif not temperature_missing and (states('sensor.downstairs_freezer_temperature_x62ts_temperature') | float(0)) > threshold %} + {% if (states('sensor.downstairs_freezer_temperature_change_rate') | float(0)) >= 2 %} + {% set ns.items = ns.items + ['Warming rapidly - possible open door'] %} + {% else %} + {% set ns.items = ns.items + ['Temperature too high - possible loss of cooling'] %} + {% endif %} + {% endif %} + {{ ns.items }} + temperature: "{{ states('sensor.downstairs_freezer_temperature_x62ts_temperature') }}" + humidity: "{{ states('sensor.downstairs_freezer_temperature_x62ts_humidity') }}" + average_7_days: "{{ states('sensor.downstairs_freezer_temperature_average_7_days') }}" + alert_threshold: >- + {% set percentile = states('sensor.downstairs_freezer_temperature_95th_percentile_7_days') | float(none) %} + {{ [-5, percentile + 0.5] | min if percentile is not none else -5 }} + change_rate: "{{ states('sensor.downstairs_freezer_temperature_change_rate') }}" + battery: "{{ states('sensor.downstairs_freezer_temperature_x62ts_battery') }}" + power: "{{ states('sensor.downstairs_fridge_power_x41pp_power') }}" + door_open: "{{ is_state('binary_sensor.downstairs_freezer_door_open', 'on') }}" + illuminance: "{{ states('sensor.downstairs_freezer_light_sensor_x61ls_illuminance') }}" + + - name: "Drinks Freezer Issue" + unique_id: drinks_freezer_issue + device_class: problem + delay_on: "00:01:00" + state: >- + {% set temperature_missing = not has_value('sensor.drinks_freezer_environment_lcd_btt02_temperature') %} + {% set battery_missing = not has_value('sensor.drinks_freezer_environment_lcd_btt02_battery') %} + {% set power_missing = not has_value('sensor.drinks_fridge_power_x59pm_power') %} + {% set percentile = states('sensor.drinks_freezer_temperature_95th_percentile_7_days') | float(none) %} + {% set threshold = [-5, percentile + 0.5] | min if percentile is not none else -5 %} + {{ + temperature_missing + or battery_missing + or (states('sensor.drinks_freezer_environment_lcd_btt02_battery') | float(-1)) <= 20 + or states('switch.drinks_fridge_power_x59pm') != 'on' + or power_missing + or is_state('binary_sensor.drinks_fridge_power_draw_lost', 'on') + or (not temperature_missing and (states('sensor.drinks_freezer_environment_lcd_btt02_temperature') | float(0)) > threshold) + }} + attributes: + appliance: "Drinks Freezer" + issues: >- + {% set ns = namespace(items=[]) %} + {% set temperature_missing = not has_value('sensor.drinks_freezer_environment_lcd_btt02_temperature') %} + {% set battery_missing = not has_value('sensor.drinks_freezer_environment_lcd_btt02_battery') %} + {% set power_missing = not has_value('sensor.drinks_fridge_power_x59pm_power') %} + {% set percentile = states('sensor.drinks_freezer_temperature_95th_percentile_7_days') | float(none) %} + {% set threshold = [-5, percentile + 0.5] | min if percentile is not none else -5 %} + {% if temperature_missing or battery_missing %} + {% set ns.items = ns.items + ['Monitor offline'] %} + {% endif %} + {% if not battery_missing and (states('sensor.drinks_freezer_environment_lcd_btt02_battery') | float(-1)) <= 20 %} + {% set ns.items = ns.items + ['Low monitor battery'] %} + {% endif %} + {% if states('switch.drinks_fridge_power_x59pm') in ['unknown', 'unavailable'] or power_missing %} + {% set ns.items = ns.items + ['Power monitoring unavailable'] %} + {% elif not is_state('switch.drinks_fridge_power_x59pm', 'on') %} + {% set ns.items = ns.items + ['Power switched off'] %} + {% elif is_state('binary_sensor.drinks_fridge_power_draw_lost', 'on') %} + {% set ns.items = ns.items + ['Power lost - no power draw for 4 hours'] %} + {% endif %} + {% if not temperature_missing and (states('sensor.drinks_freezer_environment_lcd_btt02_temperature') | float(0)) > threshold %} + {% if (states('sensor.drinks_freezer_temperature_change_rate') | float(0)) >= 2 %} + {% set ns.items = ns.items + ['Warming rapidly - possible open door'] %} + {% else %} + {% set ns.items = ns.items + ['Temperature too high - possible loss of cooling'] %} + {% endif %} + {% endif %} + {{ ns.items }} + temperature: "{{ states('sensor.drinks_freezer_environment_lcd_btt02_temperature') }}" + average_7_days: "{{ states('sensor.drinks_freezer_temperature_average_7_days') }}" + alert_threshold: >- + {% set percentile = states('sensor.drinks_freezer_temperature_95th_percentile_7_days') | float(none) %} + {{ [-5, percentile + 0.5] | min if percentile is not none else -5 }} + change_rate: "{{ states('sensor.drinks_freezer_temperature_change_rate') }}" + battery: "{{ states('sensor.drinks_freezer_environment_lcd_btt02_battery') }}" + power: "{{ states('sensor.drinks_fridge_power_x59pm_power') }}" + + - name: "Vertical Freezer Issue" + unique_id: vertical_freezer_issue + device_class: problem + delay_on: "00:01:00" + state: >- + {% set temperature_missing = not has_value('sensor.lcd_temp_humidity_btt03_temperature') %} + {% set battery_missing = not has_value('sensor.lcd_temp_humidity_btt03_battery') %} + {% set power_missing = not has_value('sensor.vertical_freezer_power_x60pm_power') %} + {% set percentile = states('sensor.vertical_freezer_temperature_95th_percentile_7_days') | float(none) %} + {% set threshold = [-10, percentile + 6] | min if percentile is not none else -10 %} + {{ + temperature_missing + or battery_missing + or (states('sensor.lcd_temp_humidity_btt03_battery') | float(-1)) <= 20 + or states('switch.vertical_freezer_power_x60pm') != 'on' + or power_missing + or is_state('binary_sensor.vertical_freezer_power_draw_lost', 'on') + or (not temperature_missing and (states('sensor.lcd_temp_humidity_btt03_temperature') | float(0)) > threshold) + }} + attributes: + appliance: "Vertical Freezer" + issues: >- + {% set ns = namespace(items=[]) %} + {% set temperature_missing = not has_value('sensor.lcd_temp_humidity_btt03_temperature') %} + {% set battery_missing = not has_value('sensor.lcd_temp_humidity_btt03_battery') %} + {% set power_missing = not has_value('sensor.vertical_freezer_power_x60pm_power') %} + {% set percentile = states('sensor.vertical_freezer_temperature_95th_percentile_7_days') | float(none) %} + {% set threshold = [-10, percentile + 6] | min if percentile is not none else -10 %} + {% if temperature_missing or battery_missing %} + {% set ns.items = ns.items + ['Monitor offline'] %} + {% endif %} + {% if not battery_missing and (states('sensor.lcd_temp_humidity_btt03_battery') | float(-1)) <= 20 %} + {% set ns.items = ns.items + ['Low monitor battery'] %} + {% endif %} + {% if states('switch.vertical_freezer_power_x60pm') in ['unknown', 'unavailable'] or power_missing %} + {% set ns.items = ns.items + ['Power monitoring unavailable'] %} + {% elif not is_state('switch.vertical_freezer_power_x60pm', 'on') %} + {% set ns.items = ns.items + ['Power switched off'] %} + {% elif is_state('binary_sensor.vertical_freezer_power_draw_lost', 'on') %} + {% set ns.items = ns.items + ['Power lost - no power draw for 4 hours'] %} + {% endif %} + {% if not temperature_missing and (states('sensor.lcd_temp_humidity_btt03_temperature') | float(0)) > threshold %} + {% if (states('sensor.vertical_freezer_temperature_change_rate') | float(0)) >= 2 %} + {% set ns.items = ns.items + ['Warming rapidly - possible open door'] %} + {% else %} + {% set ns.items = ns.items + ['Temperature too high - possible loss of cooling'] %} + {% endif %} + {% endif %} + {{ ns.items }} + temperature: "{{ states('sensor.lcd_temp_humidity_btt03_temperature') }}" + average_7_days: "{{ states('sensor.vertical_freezer_temperature_average_7_days') }}" + alert_threshold: >- + {% set percentile = states('sensor.vertical_freezer_temperature_95th_percentile_7_days') | float(none) %} + {{ [-10, percentile + 6] | min if percentile is not none else -10 }} + change_rate: "{{ states('sensor.vertical_freezer_temperature_change_rate') }}" + battery: "{{ states('sensor.lcd_temp_humidity_btt03_battery') }}" + power: "{{ states('sensor.vertical_freezer_power_x60pm_power') }}" + + #:######################################################################################:# + # SUMMARY STATUS + #:######################################################################################:# + - sensor: + - name: "Fridge Freezer Monitor Status" + unique_id: fridge_freezer_monitor_status + icon: mdi:fridge-alert-outline + state: >- + {{ + 'Issue' + if is_state('binary_sensor.drinks_fridge_door_open_too_long', 'on') + or is_state('binary_sensor.downstairs_fridge_door_open_too_long', 'on') + else 'Open' + if is_state('binary_sensor.drinks_fridge_door_open', 'on') + or is_state('binary_sensor.downstairs_fridge_door_open', 'on') + else 'Issue' + if expand( + 'binary_sensor.main_kitchen_fridge_issue', + 'binary_sensor.drinks_fridge_issue', + 'binary_sensor.downstairs_fridge_issue', + 'binary_sensor.wine_fridge_issue', + 'binary_sensor.drinks_freezer_issue', + 'binary_sensor.vertical_freezer_issue' + ) + | selectattr('state', 'eq', 'on') + | list + | count > 0 + else 'OK' + }} + attributes: + issue_count: >- + {{ + expand( + 'binary_sensor.main_kitchen_fridge_issue', + 'binary_sensor.drinks_fridge_issue', + 'binary_sensor.downstairs_fridge_issue', + 'binary_sensor.wine_fridge_issue', + 'binary_sensor.drinks_freezer_issue', + 'binary_sensor.vertical_freezer_issue' + ) + | selectattr('state', 'eq', 'on') + | list + | count + }} + open_count: >- + {{ + [ + is_state('binary_sensor.drinks_fridge_door_open', 'on'), + is_state('binary_sensor.downstairs_fridge_door_open', 'on') + ] + | select + | list + | count + }} + issues: >- + {% set ns = namespace(items=[]) %} + {% set monitors = [ + 'binary_sensor.main_kitchen_fridge_issue', + 'binary_sensor.drinks_fridge_issue', + 'binary_sensor.downstairs_fridge_issue', + 'binary_sensor.wine_fridge_issue', + 'binary_sensor.drinks_freezer_issue', + 'binary_sensor.vertical_freezer_issue' + ] %} + {% for monitor in monitors if is_state(monitor, 'on') %} + {% set appliance = state_attr(monitor, 'appliance') or state_attr(monitor, 'friendly_name') %} + {% set reasons = state_attr(monitor, 'issues') or ['Issue detected'] %} + {% for reason in reasons %} + {% set ns.items = ns.items + [appliance ~ ': ' ~ reason] %} + {% endfor %} + {% endfor %} + {{ ns.items }} diff --git a/packages/fridge_temperatures.yaml b/packages/fridge_temperatures.yaml index 249f105..078a30d 100644 --- a/packages/fridge_temperatures.yaml +++ b/packages/fridge_temperatures.yaml @@ -1,15 +1,16 @@ #:########################################################################################:# # Package: Refrigerator Temperature MQTT Publishing # File: fridge_temperatures.yaml -# Version: v1.0.0 -# Date: 2024-09-04 +# Version: v1.1.0 +# Date: 2026-08-17 # # Purpose: # Publishes refrigerator and freezer temperature changes to household MQTT # status topics for use by external displays and consumers. # # Behaviour: -# - Publishes the source sensor state whenever a valid temperature changes. +# - Creates a calibrated main kitchen fridge temperature entity. +# - Publishes each valid temperature entity state whenever it changes. # - Suppresses unknown and unavailable source states. # - Covers the drinks fridge, drinks freezer, and main kitchen fridge. # @@ -18,9 +19,21 @@ # - Home Assistant MQTT integration and broker connectivity. # # Version History: +# - v1.1.0 (2026-08-17): Added the -0.84 C main fridge sensor calibration. # - v1.0.0 (2024-09-04): Initial refrigerator temperature publishing package. #:########################################################################################:# +template: + - sensor: + - name: "Main Kitchen Fridge Temperature Calibrated" + unique_id: main_kitchen_fridge_temperature_calibrated + device_class: temperature + state_class: measurement + unit_of_measurement: "°C" + availability: "{{ has_value('sensor.main_kitchen_fridge_temp_zth08') }}" + state: >- + {{ (states('sensor.main_kitchen_fridge_temp_zth08') | float - 0.84) | round(2) }} + automation: - id: publish_fridge_temps_drinks_fridge alias: publish_fridge_temps_drinks_fridge @@ -56,7 +69,7 @@ automation: alias: publish_main_kitchen_fridge_temp_zth08 trigger: - platform: state - entity_id: sensor.main_kitchen_fridge_temp_zth08 + entity_id: sensor.main_kitchen_fridge_temperature_calibrated not_to: - "unavailable" - "unknown" diff --git a/packages/health_checks.yaml b/packages/health_checks.yaml deleted file mode 100644 index 041fa19..0000000 --- a/packages/health_checks.yaml +++ /dev/null @@ -1,63 +0,0 @@ -#:########################################################################################:# -# Package: Node-RED Health Checks -# File: health_checks.yaml -# Version: v1.2.0 -# Date: 2025-08-25 -# -# Purpose: -# Monitors the Node-RED Panda instance through independent HTTP and MQTT health -# signals and combines them into one connectivity status. -# -# Behaviour: -# - Polls the HTTP health endpoint every 30 seconds with a three-second timeout. -# - Tracks the MQTT birth/will topic with QoS 1 and a 180-second expiry. -# - Reports the combined check as available when either source is available. -# - Reports the combined check as connected when either source is connected. -# -# Dependencies: -# - Reachability of the configured Node-RED HTTP health endpoint. -# - Home Assistant MQTT integration and the Node-RED birth/will publisher. -# -# Version History: -# - v1.2.0 (2025-08-25): Reduced MQTT expiry to 180 seconds and clarified the -# combined HTTP/MQTT sensor name. -# - v1.1.0 (2025-08-22): Split HTTP and MQTT probes and added a combined sensor. -# - v1.0.0 (2025-08-21): Initial Node-RED health-check package. -#:########################################################################################:# - -# ---- HTTP health probe ---- -binary_sensor: - - platform: rest - name: Node-RED Panda Up (HTTP) - resource: http://192.168.3.200:1880/healthz - method: GET - device_class: connectivity - value_template: "{{ value_json.status == 'ok' }}" - timeout: 3 - scan_interval: 30 - -# ---- MQTT Will/Birth probe ---- -mqtt: - binary_sensor: - - name: "Node-RED Panda Up (MQTT)" - unique_id: "nodered_panda_up_mqtt" - state_topic: "nodered/panda/status" - payload_on: "online" - payload_off: "offline" - device_class: connectivity - qos: 1 - # Optional: avoid stale 'online' if no updates arrive - expire_after: 180 - -# ---- Combine them (true if either is up) ---- -template: - - binary_sensor: - - name: "Node-RED Panda Up (HTTP/MQTT)" - unique_id: "nodered_panda_up_combined" - device_class: connectivity - state: > - {{ is_state('binary_sensor.node_red_panda_up_http','on') - or is_state('binary_sensor.node_red_panda_up_mqtt','on') }} - availability: > - {{ states('binary_sensor.node_red_panda_up_http') not in ['unknown','unavailable'] - or states('binary_sensor.node_red_panda_up_mqtt') not in ['unknown','unavailable'] }} diff --git a/packages/lounge_ir_sensor_actions.yaml b/packages/lounge_ir_sensor_actions.yaml index 1b2e4d0..b732775 100644 --- a/packages/lounge_ir_sensor_actions.yaml +++ b/packages/lounge_ir_sensor_actions.yaml @@ -163,7 +163,7 @@ automation: data: channels: "sony_tv_lounge" title: "View Road" - short_announcement: "Rinnai Gas Heater" + short_announcement: "Gas Fire {{ new_state_text }}" long_announcement: "" payload: "{{ new_state_text }}" indicator: "" diff --git a/packages/master_bedroom_4_button_switches.yaml b/packages/master_bedroom_4_button_switches.yaml index 8f4daec..ddc8a39 100644 --- a/packages/master_bedroom_4_button_switches.yaml +++ b/packages/master_bedroom_4_button_switches.yaml @@ -54,8 +54,8 @@ automation: max: 10 variables: - west_switch_mqtt_topic: "zigbee2mqtt/Master Bedroom 4 Button Switch (West)" - east_switch_mqtt_topic: "zigbee2mqtt/Master Bedroom 4 Button Switch (East)" + west_switch_mqtt_topic: "zigbee2mqtt/Master Bedroom Scene Switch West (X54SS)" + east_switch_mqtt_topic: "zigbee2mqtt/Master Bedroom Scene Switch East (X55SS)" bedside_light: "switch.master_bedroom_bedside_lamp_arlec_bulb_master_bedroom_bedside_lamp_arlec_bulb_jump_fade_up_down" main_bedroom_south_lights: "switch.master_bedroom_master_bedroom_main_lights_south_relay_2_master_bedroom_south_lights" @@ -64,50 +64,50 @@ automation: triggers: # West switch actions - trigger: mqtt - topic: "zigbee2mqtt/Master Bedroom 4 Button Switch (West)" + topic: "zigbee2mqtt/Master Bedroom Scene Switch West (X54SS)" value_template: "{{ value_json.action | default('') }}" payload: "1_single" id: west_top_left - trigger: mqtt - topic: "zigbee2mqtt/Master Bedroom 4 Button Switch (West)" + topic: "zigbee2mqtt/Master Bedroom Scene Switch West (X54SS)" value_template: "{{ value_json.action | default('') }}" payload: "2_single" id: west_top_right - trigger: mqtt - topic: "zigbee2mqtt/Master Bedroom 4 Button Switch (West)" + topic: "zigbee2mqtt/Master Bedroom Scene Switch West (X54SS)" value_template: "{{ value_json.action | default('') }}" payload: "3_single" id: west_bottom_left - trigger: mqtt - topic: "zigbee2mqtt/Master Bedroom 4 Button Switch (West)" + topic: "zigbee2mqtt/Master Bedroom Scene Switch West (X54SS)" value_template: "{{ value_json.action | default('') }}" payload: "4_single" id: west_bottom_right # East switch actions - trigger: mqtt - topic: "zigbee2mqtt/Master Bedroom 4 Button Switch (East)" + topic: "zigbee2mqtt/Master Bedroom Scene Switch East (X55SS)" value_template: "{{ value_json.action | default('') }}" payload: "1_single" id: east_top_left - trigger: mqtt - topic: "zigbee2mqtt/Master Bedroom 4 Button Switch (East)" + topic: "zigbee2mqtt/Master Bedroom Scene Switch East (X55SS)" value_template: "{{ value_json.action | default('') }}" payload: "2_single" id: east_top_right - trigger: mqtt - topic: "zigbee2mqtt/Master Bedroom 4 Button Switch (East)" + topic: "zigbee2mqtt/Master Bedroom Scene Switch East (X55SS)" value_template: "{{ value_json.action | default('') }}" payload: "3_single" id: east_bottom_left - trigger: mqtt - topic: "zigbee2mqtt/Master Bedroom 4 Button Switch (East)" + topic: "zigbee2mqtt/Master Bedroom Scene Switch East (X55SS)" value_template: "{{ value_json.action | default('') }}" payload: "4_single" id: east_bottom_right diff --git a/packages/network_monitoring.yaml b/packages/network_monitoring.yaml new file mode 100644 index 0000000..4a2f386 --- /dev/null +++ b/packages/network_monitoring.yaml @@ -0,0 +1,510 @@ +#:########################################################################################:# +# Package: Network Monitoring +# File: network_monitoring.yaml +# Version: v1.3.0 +# Date: 2026-08-28 +# +# Purpose: +# Supplies the calculated Internet, router, MQTT, and Home Assistant health +# information for general network monitoring, including the independent +# Panda and Beaver MQTT brokers, plus Node-RED Panda. +# +# Behaviour: +# - Tracks daily and seven-day Internet speed-test peaks. +# - Calculates rolling 24-hour and seven-day WAN traffic averages and peaks. +# - Measures external HTTP latency and tracks the current public IP address. +# - Monitors the Panda MQTT broker through Home Assistant's birth topic and +# Beaver's MQTT listener through a direct TCP probe. +# - Monitors Node-RED Panda through independent HTTP and MQTT signals. +# - Retains the latest outage time for each monitored network service. +# +# Dependencies: +# - packages/internet_monitoring.yaml +# - packages/edgerouter_snmp.yaml +# - MQTT integration with the default homeassistant/status birth topic. +# - Existing Zigbee2MQTT connectivity entity. +# +# Notes: +# - WAN traffic source values are kB/s and retain that unit in statistics. +# - The 24-hour and seven-day traffic values are rolling windows. +# - Home Assistant's own last outage is represented by sensor.uptime because +# Home Assistant cannot record an event while Core itself is offline. +# - Public IP data is fetched from api.ipify.org every five minutes. +# +# Version History: +# - v1.3.0 (2026-08-28): Renamed package for general network use. +# - v1.2.0 (2026-08-28): Consolidated Node-RED Panda monitoring. +# - v1.1.0 (2026-08-28): Added Beaver MQTT and HA Core health monitoring. +# - v1.0.0 (2026-08-15): Initial monitoring and outage tracking package. +#:########################################################################################:# + +command_line: + #:######################################################################################:# + # EXTERNAL NETWORK INFORMATION + #:######################################################################################:# + - sensor: + name: "Flounder External IP" + unique_id: flounder_external_ip + command: >- + curl --fail --silent --show-error --max-time 10 https://api.ipify.org + command_timeout: 15 + scan_interval: 300 + + - sensor: + name: "Flounder Internet Response Time" + unique_id: flounder_internet_response_time + command: >- + curl --fail --silent --show-error --max-time 10 --output /dev/null + --write-out "%{time_total}" https://one.one.one.one/cdn-cgi/trace + command_timeout: 15 + scan_interval: 60 + unit_of_measurement: "ms" + device_class: duration + state_class: measurement + value_template: "{{ ((value | float(0)) * 1000) | round(0) }}" + + - binary_sensor: + name: "Flounder Beaver MQTT Broker Connected" + unique_id: flounder_beaver_mqtt_broker_connected + command: >- + timeout 5 bash -c '>/dev/tcp/172.31.6.1/1883' && echo ON || echo OFF + command_timeout: 6 + scan_interval: 60 + device_class: connectivity + +mqtt: + #:######################################################################################:# + # MQTT BROKER CONNECTION + #:######################################################################################:# + binary_sensor: + - name: "Flounder MQTT Broker Connected" + unique_id: flounder_mqtt_broker_connected + state_topic: "homeassistant/status" + payload_on: "online" + payload_off: "offline" + device_class: connectivity + + - name: "Node-RED Panda Up (MQTT)" + unique_id: nodered_panda_up_mqtt + state_topic: "nodered/panda/status" + payload_on: "online" + payload_off: "offline" + device_class: connectivity + qos: 1 + expire_after: 180 + +binary_sensor: + #:######################################################################################:# + # NODE-RED PANDA HTTP HEALTH + #:######################################################################################:# + - platform: rest + name: "Node-RED Panda Up (HTTP)" + resource: http://192.168.3.200:1880/healthz + method: GET + device_class: connectivity + value_template: "{{ value_json.status == 'ok' }}" + timeout: 3 + scan_interval: 30 + +input_number: + #:######################################################################################:# + # DAILY SPEED-TEST PEAKS + #:######################################################################################:# + flounder_internet_download_peak_today: + name: "Flounder Internet Download Peak Today" + min: 0 + max: 10000 + step: 0.01 + mode: box + + flounder_internet_upload_peak_today: + name: "Flounder Internet Upload Peak Today" + min: 0 + max: 10000 + step: 0.01 + mode: box + +input_datetime: + #:######################################################################################:# + # LAST EXTERNAL IP CHANGE + #:######################################################################################:# + flounder_external_ip_last_changed: + name: "Flounder External IP Last Changed" + has_date: true + has_time: true + +input_text: + #:######################################################################################:# + # LAST OUTAGE TIMES + #:######################################################################################:# + flounder_internet_last_outage: + name: "Flounder Internet Last Outage" + max: 40 + + flounder_edgerouter_last_outage: + name: "Flounder EdgeRouter Last Outage" + max: 40 + + flounder_mqtt_broker_last_outage: + name: "Flounder MQTT Broker Last Outage" + max: 40 + + flounder_node_red_mqtt_last_outage: + name: "Flounder Node-RED MQTT Last Outage" + max: 40 + + flounder_zigbee2mqtt_2_last_outage: + name: "Flounder Zigbee2MQTT 2 Last Outage" + max: 40 + + flounder_zigbee2mqtt_3_last_outage: + name: "Flounder Zigbee2MQTT 3 Last Outage" + max: 40 + +template: + #:######################################################################################:# + # POPUP STATUS AND SPEED-TEST VALUES + #:######################################################################################:# + - binary_sensor: + - name: "Flounder EdgeRouter Online" + unique_id: flounder_edgerouter_online + device_class: connectivity + state: "{{ has_value('sensor.edgerouter_uptime') }}" + + - name: "Flounder HA Core Online" + unique_id: flounder_ha_core_online + device_class: connectivity + state: "{{ has_value('sensor.home_assistant_core_uptime') }}" + + - name: "Node-RED Panda Up (HTTP/MQTT)" + unique_id: nodered_panda_up_combined + device_class: connectivity + state: >- + {{ + is_state('binary_sensor.node_red_panda_up_http', 'on') + or is_state('binary_sensor.node_red_panda_up_mqtt', 'on') + }} + availability: >- + {{ + states('binary_sensor.node_red_panda_up_http') + not in ['unknown', 'unavailable'] + or states('binary_sensor.node_red_panda_up_mqtt') + not in ['unknown', 'unavailable'] + }} + + - sensor: + - name: "Flounder Internet Download Peak Today" + unique_id: flounder_internet_download_peak_today + unit_of_measurement: "Mbit/s" + device_class: data_rate + state_class: measurement + state: >- + {{ states('input_number.flounder_internet_download_peak_today') | float(0) }} + + - name: "Flounder Internet Upload Peak Today" + unique_id: flounder_internet_upload_peak_today + unit_of_measurement: "Mbit/s" + device_class: data_rate + state_class: measurement + state: >- + {{ states('input_number.flounder_internet_upload_peak_today') | float(0) }} + +sensor: + #:######################################################################################:# + # INTERNET SPEED-TEST PEAKS + #:######################################################################################:# + - platform: statistics + name: "Flounder Internet Download Peak 7 Days" + unique_id: flounder_internet_download_peak_7_days + entity_id: sensor.internet_speed_test + state_characteristic: value_max + max_age: + days: 7 + precision: 2 + + - platform: statistics + name: "Flounder Internet Upload Peak 7 Days" + unique_id: flounder_internet_upload_peak_7_days + entity_id: sensor.internet_upload_speed_test + state_characteristic: value_max + max_age: + days: 7 + precision: 2 + + #:######################################################################################:# + # WAN DOWNLOAD TRAFFIC STATISTICS + #:######################################################################################:# + - platform: statistics + name: "Flounder WAN Download Average 24 Hours" + unique_id: flounder_wan_download_average_24_hours + entity_id: sensor.edgerouter_wan_download_rate + state_characteristic: average_step + max_age: + hours: 24 + precision: 1 + + - platform: statistics + name: "Flounder WAN Download Peak 24 Hours" + unique_id: flounder_wan_download_peak_24_hours + entity_id: sensor.edgerouter_wan_download_rate + state_characteristic: value_max + max_age: + hours: 24 + precision: 1 + + - platform: statistics + name: "Flounder WAN Download Average 7 Days" + unique_id: flounder_wan_download_average_7_days + entity_id: sensor.edgerouter_wan_download_rate + state_characteristic: average_step + max_age: + days: 7 + precision: 1 + + - platform: statistics + name: "Flounder WAN Download Peak 7 Days" + unique_id: flounder_wan_download_peak_7_days + entity_id: sensor.edgerouter_wan_download_rate + state_characteristic: value_max + max_age: + days: 7 + precision: 1 + + #:######################################################################################:# + # WAN UPLOAD TRAFFIC STATISTICS + #:######################################################################################:# + - platform: statistics + name: "Flounder WAN Upload Average 24 Hours" + unique_id: flounder_wan_upload_average_24_hours + entity_id: sensor.edgerouter_wan_upload_rate + state_characteristic: average_step + max_age: + hours: 24 + precision: 1 + + - platform: statistics + name: "Flounder WAN Upload Peak 24 Hours" + unique_id: flounder_wan_upload_peak_24_hours + entity_id: sensor.edgerouter_wan_upload_rate + state_characteristic: value_max + max_age: + hours: 24 + precision: 1 + + - platform: statistics + name: "Flounder WAN Upload Average 7 Days" + unique_id: flounder_wan_upload_average_7_days + entity_id: sensor.edgerouter_wan_upload_rate + state_characteristic: average_step + max_age: + days: 7 + precision: 1 + + - platform: statistics + name: "Flounder WAN Upload Peak 7 Days" + unique_id: flounder_wan_upload_peak_7_days + entity_id: sensor.edgerouter_wan_upload_rate + state_characteristic: value_max + max_age: + days: 7 + precision: 1 + + #:######################################################################################:# + # EXTERNAL RESPONSE-TIME STATISTICS + #:######################################################################################:# + - platform: statistics + name: "Flounder Internet Response Time Average 24 Hours" + unique_id: flounder_internet_response_time_average_24_hours + entity_id: sensor.flounder_internet_response_time + state_characteristic: average_step + max_age: + hours: 24 + precision: 0 + + - platform: statistics + name: "Flounder Internet Response Time Peak 24 Hours" + unique_id: flounder_internet_response_time_peak_24_hours + entity_id: sensor.flounder_internet_response_time + state_characteristic: value_max + max_age: + hours: 24 + precision: 0 + +automation: + #:######################################################################################:# + # SPEED-TEST PEAK TRACKING + #:######################################################################################:# + - id: flounder_network_record_speed_test_peaks + alias: "Flounder Network: Record speed-test peaks" + triggers: + - trigger: state + entity_id: sensor.internet_speed_test + conditions: [] + actions: + - delay: + seconds: 1 + - condition: template + value_template: >- + {{ + has_value('sensor.internet_speed_test') + and has_value('sensor.internet_upload_speed_test') + }} + - action: input_number.set_value + target: + entity_id: input_number.flounder_internet_download_peak_today + data: + value: >- + {{ + [ + states('sensor.internet_speed_test') | float(0), + states('input_number.flounder_internet_download_peak_today') | float(0) + ] + | max + }} + - action: input_number.set_value + target: + entity_id: input_number.flounder_internet_upload_peak_today + data: + value: >- + {{ + [ + states('sensor.internet_upload_speed_test') | float(0), + states('input_number.flounder_internet_upload_peak_today') | float(0) + ] + | max + }} + mode: queued + + - id: flounder_network_reset_daily_speed_test_peaks + alias: "Flounder Network: Reset daily speed-test peaks" + triggers: + - trigger: time + at: "00:00:00" + conditions: [] + actions: + - action: input_number.set_value + target: + entity_id: + - input_number.flounder_internet_download_peak_today + - input_number.flounder_internet_upload_peak_today + data: + value: 0 + mode: single + + #:######################################################################################:# + # PUBLIC IP CHANGE TRACKING + #:######################################################################################:# + - id: flounder_network_record_external_ip_change + alias: "Flounder Network: Record external IP change" + triggers: + - trigger: state + entity_id: sensor.flounder_external_ip + conditions: + - condition: template + value_template: >- + {{ + trigger.to_state is not none + and trigger.to_state.state not in ['unknown', 'unavailable', 'none', ''] + and ( + trigger.from_state is none + or trigger.from_state.state != trigger.to_state.state + ) + }} + actions: + - action: input_datetime.set_datetime + target: + entity_id: input_datetime.flounder_external_ip_last_changed + data: + timestamp: "{{ now().timestamp() }}" + mode: single + + #:######################################################################################:# + # SERVICE OUTAGE TRACKING + #:######################################################################################:# + - id: flounder_network_record_service_outages + alias: "Flounder Network: Record service outages" + triggers: + - trigger: state + entity_id: binary_sensor.internet_connected + id: internet + - trigger: state + entity_id: binary_sensor.flounder_edgerouter_online + id: edgerouter + - trigger: state + entity_id: binary_sensor.flounder_mqtt_broker_connected + id: mqtt_broker + - trigger: state + entity_id: binary_sensor.flounder_beaver_mqtt_broker_connected + id: beaver_mqtt_broker + - trigger: state + entity_id: binary_sensor.node_red_panda_up_2 + id: node_red_mqtt + - trigger: state + entity_id: binary_sensor.zigbee2mqtt_bridge_connection_state_2 + id: zigbee2mqtt_2 + - trigger: state + entity_id: binary_sensor.zigbee2mqtt_bridge_connection_state_3 + id: zigbee2mqtt_3 + conditions: + - condition: template + value_template: >- + {{ + trigger.to_state is not none + and trigger.to_state.state in ['off', 'unavailable'] + and ( + trigger.from_state is none + or trigger.from_state.state not in ['off', 'unavailable'] + ) + }} + actions: + - choose: + - conditions: "{{ trigger.id == 'internet' }}" + sequence: + - action: input_text.set_value + target: + entity_id: input_text.flounder_internet_last_outage + data: + value: "{{ now().isoformat() }}" + - conditions: "{{ trigger.id == 'edgerouter' }}" + sequence: + - action: input_text.set_value + target: + entity_id: input_text.flounder_edgerouter_last_outage + data: + value: "{{ now().isoformat() }}" + - conditions: "{{ trigger.id == 'mqtt_broker' }}" + sequence: + - action: input_text.set_value + target: + entity_id: input_text.flounder_mqtt_broker_last_outage + data: + value: "{{ now().isoformat() }}" + - conditions: "{{ trigger.id == 'beaver_mqtt_broker' }}" + sequence: + - action: input_text.set_value + target: + entity_id: input_text.flounder_mqtt_broker_last_outage + data: + value: "{{ now().isoformat() }}" + - conditions: "{{ trigger.id == 'node_red_mqtt' }}" + sequence: + - action: input_text.set_value + target: + entity_id: input_text.flounder_node_red_mqtt_last_outage + data: + value: "{{ now().isoformat() }}" + - conditions: "{{ trigger.id == 'zigbee2mqtt_2' }}" + sequence: + - action: input_text.set_value + target: + entity_id: input_text.flounder_zigbee2mqtt_2_last_outage + data: + value: "{{ now().isoformat() }}" + - conditions: "{{ trigger.id == 'zigbee2mqtt_3' }}" + sequence: + - action: input_text.set_value + target: + entity_id: input_text.flounder_zigbee2mqtt_3_last_outage + data: + value: "{{ now().isoformat() }}" + mode: queued diff --git a/packages/office_lights_power_backup_occupancy.yaml b/packages/office_lights_power_backup_occupancy.yaml index 7cc08c2..22b743e 100644 --- a/packages/office_lights_power_backup_occupancy.yaml +++ b/packages/office_lights_power_backup_occupancy.yaml @@ -3,6 +3,11 @@ ################################################################################ # # Version: +# - 1.2 - 2026-08-16 +# - Removed the spare-button trigger after false presses caused unintended +# power toggles. +# - Retains occupancy-based backup control for Office power supplies. +# # - 1.1 - 2026-07-25 # - Stripped light control (now handled by direct MQTT) # - Retains power supply backup control only @@ -20,16 +25,9 @@ # - Turns Office power supplies off after the Office mmWave occupancy sensor # has been clear for the configured delay period. # -# - Provides a backup manual control path using the Office spare button. -# This is useful if the occupancy sensor is offline. -# # Notes: # - This is treated as a BACKUP automation for POWER SUPPLIES ONLY. # - Light control is handled by direct ESPHome/MQTT (see device YAMLs). -# - The physical spare button is read using: -# binary_sensor.esp_officelights_button_3_spare -# - The spare relay is used as the manual master/latch state: -# switch.esp_officelights_relay_3_spare # ################################################################################ @@ -58,9 +56,8 @@ automation: description: > Backup automation for Office power supplies. Turns power on when Office mmWave occupancy or movement is detected. Turns power off after the - occupancy sensor is clear for the configured delay period. Also allows - manual backup toggling using the Office spare button and spare relay. - Light control is handled by direct ESPHome/MQTT sync. + occupancy sensor is clear for the configured delay period. Light control + is handled by direct ESPHome/MQTT sync. mode: restart triggers: ########################################################################## @@ -79,19 +76,6 @@ automation: to: "off" id: occupancy_clear - ########################################################################## - # Manual backup button press. - # - # The spare relay state is used as the master/latch: - # - If spare relay is OFF when the button is pressed, turn power ON. - # - If spare relay is ON when the button is pressed, turn power OFF. - ########################################################################## - - trigger: state - entity_id: binary_sensor.esp_officelights_button_3_spare - from: "off" - to: "on" - id: backup_button_pressed - ########################################################################## # Startup check. # @@ -214,102 +198,3 @@ automation: - action: switch.turn_off target: entity_id: switch.esp_officelights_relay_3_spare - - ###################################################################### - # MANUAL BACKUP LOGIC: - # Button pressed while spare relay master is ON - turn power off. - ###################################################################### - - alias: "Backup button pressed - spare relay on, turn power off" - conditions: - - condition: trigger - id: backup_button_pressed - - condition: state - entity_id: switch.esp_officelights_relay_3_spare - state: "on" - sequence: - ############################################################## - # Power off. - ############################################################## - - alias: "Turn off Office right hand GPO if needed" - if: - - condition: state - entity_id: switch.esp_officedeskrightgpo_office_right_hand_gpo - state: "on" - then: - - action: switch.turn_off - target: - entity_id: switch.esp_officedeskrightgpo_office_right_hand_gpo - - - alias: "Turn off Office ELV power supply if needed" - if: - - condition: state - entity_id: switch.esp_officeelvcontrol_office_elv_power_supply - state: "on" - then: - - action: switch.turn_off - target: - entity_id: switch.esp_officeelvcontrol_office_elv_power_supply - - ############################################################## - # Manual master/latch relay off last. - ############################################################## - - alias: "Turn off Office spare relay master if needed" - if: - - condition: state - entity_id: switch.esp_officelights_relay_3_spare - state: "on" - then: - - action: switch.turn_off - target: - entity_id: switch.esp_officelights_relay_3_spare - - ###################################################################### - # MANUAL BACKUP LOGIC: - # Button pressed while spare relay master is OFF - turn power on. - # - # No off timer is started from this manual press. If the occupancy - # sensor later changes to clear, the normal clear-delay logic will run. - ###################################################################### - - alias: "Backup button pressed - spare relay off, turn power on" - conditions: - - condition: trigger - id: backup_button_pressed - - condition: state - entity_id: switch.esp_officelights_relay_3_spare - state: "off" - sequence: - ############################################################## - # Power supplies. - ############################################################## - - alias: "Turn on Office ELV power supply if needed" - if: - - condition: state - entity_id: switch.esp_officeelvcontrol_office_elv_power_supply - state: "off" - then: - - action: switch.turn_on - target: - entity_id: switch.esp_officeelvcontrol_office_elv_power_supply - - - alias: "Turn on Office right hand GPO if needed" - if: - - condition: state - entity_id: switch.esp_officedeskrightgpo_office_right_hand_gpo - state: "off" - then: - - action: switch.turn_on - target: - entity_id: switch.esp_officedeskrightgpo_office_right_hand_gpo - - ############################################################## - # Manual master/latch relay. - ############################################################## - - alias: "Turn on Office spare relay master if needed" - if: - - condition: state - entity_id: switch.esp_officelights_relay_3_spare - state: "off" - then: - - action: switch.turn_on - target: - entity_id: switch.esp_officelights_relay_3_spare diff --git a/packages/tplink_deco_guest_wifi.yaml b/packages/tplink_deco_guest_wifi.yaml new file mode 100644 index 0000000..3b51772 --- /dev/null +++ b/packages/tplink_deco_guest_wifi.yaml @@ -0,0 +1,101 @@ +#:########################################################################################:# +# TP-Link Deco Guest Wi-Fi Package # +#:########################################################################################:# +# +# TITLE: +# TP-Link Deco Guest Wi-Fi +# +# FILE: +# packages/tplink_deco_guest_wifi.yaml +# +# VERSION: +# V2.2 2026-08-24 +# +# VERSION HISTORY: +# V2.2 2026-08-24 +# - Replaced passive status sync with router-confirmed enforcement. +# - Repeats requests, reconciles at startup and hourly, and alerts when +# the Deco cannot confirm the requested state. +# +# V2.1 2026-08-04 +# - Added the original router-status sync automation. +# +# V2.0 2026-08-04 +# - Switched from Alexa voice commands to the Deco local API. +# +# PURPOSE: +# Enforces the requested TP-Link Deco guest Wi-Fi state and confirms it +# against the guest-network sensor reported by the router. +# +# DEPENDENCIES: +# - tplink_deco integration must be configured and connected to the Deco. +# - input_boolean.wifi_guest_network represents the requested guest-network +# state. +# - binary_sensor.data_cupboard_new_sundamage_12_deco_guest_network reports +# the actual guest-network state from the router. +# +#:########################################################################################:# + +automation: + - id: enforce_wifi_guest_network_state + alias: "Enforce Wifi Guest Network State" + description: > + Reconciles requested guest Wi-Fi with the Deco's reported state, repeats + the request once after 30 seconds, and alerts on an unconfirmed mismatch. + mode: restart + triggers: + - trigger: state + entity_id: input_boolean.wifi_guest_network + - trigger: state + entity_id: binary_sensor.data_cupboard_new_sundamage_12_deco_guest_network + - trigger: homeassistant + event: start + - trigger: time_pattern + hours: "*" + minutes: "0" + conditions: + - condition: template + value_template: > + {{ states('input_boolean.wifi_guest_network') in ['on', 'off'] + and states('binary_sensor.data_cupboard_new_sundamage_12_deco_guest_network') + in ['on', 'off'] + and states('input_boolean.wifi_guest_network') + != states('binary_sensor.data_cupboard_new_sundamage_12_deco_guest_network') }} + actions: + - repeat: + count: 2 + sequence: + - choose: + - conditions: + - condition: state + entity_id: input_boolean.wifi_guest_network + state: "on" + sequence: + - action: tplink_deco.set_guest_network + data: + enable: true + - conditions: + - condition: state + entity_id: input_boolean.wifi_guest_network + state: "off" + sequence: + - action: tplink_deco.set_guest_network + data: + enable: false + - wait_template: > + {{ states('input_boolean.wifi_guest_network') + == states('binary_sensor.data_cupboard_new_sundamage_12_deco_guest_network') }} + timeout: + seconds: 30 + continue_on_timeout: true + - condition: template + value_template: > + {{ states('input_boolean.wifi_guest_network') + != states('binary_sensor.data_cupboard_new_sundamage_12_deco_guest_network') }} + - action: persistent_notification.create + data: + notification_id: wifi_guest_network_state_mismatch + title: "Guest Wi-Fi state not confirmed" + message: > + The Deco still reports Guest Wi-Fi as {{ states('binary_sensor.data_cupboard_new_sundamage_12_deco_guest_network') }} + after two requests to set it {{ states('input_boolean.wifi_guest_network') }}.