Butterfly EDFA Rack: Home Assistant config and dashboard
Fresh repo holding only the Butterfly-rack HA side (the firmware and BOM live in koheron-esp32-bridge). Contents, pulled from the live HA host: - configuration.butterfly.yaml: dBm->mW template sensors + the YAML dashboard registration, to merge into /config/configuration.yaml - scripts.butterfly.yaml: the butterfly_edfa_shutdown emergency-off script - ui-lovelace-butterfly.yaml: the dashboard - deploy.sh: scp the dashboard, check_config, restart HA - .gitignore guards against committing the HA DB, logs and secrets Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.8
commit
abcb6b7553
+13
@@ -0,0 +1,13 @@
|
||||
# This repo holds only the Butterfly-rack HA config, not a full HA checkout.
|
||||
# Guard against accidentally committing runtime/DB/secret artefacts if someone
|
||||
# copies files in from a live /config.
|
||||
secrets.yaml
|
||||
home-assistant_v2.db*
|
||||
*.log
|
||||
*.log.*
|
||||
.storage/
|
||||
.cloud/
|
||||
__pycache__/
|
||||
*.pyc
|
||||
*.bak-*
|
||||
*~
|
||||
@@ -0,0 +1,37 @@
|
||||
# butterfly-rack-homeassistant
|
||||
|
||||
Home Assistant configuration for the **Butterfly EDFA Rack** (the 1550 nm MOPA: Koheron CTL200 seed + Agiltron M511 EYDFA booster, bridged to MQTT by an ESP32). The firmware and bill of materials live in the separate `koheron-esp32-bridge` repo; this repo is only the HA side.
|
||||
|
||||
Almost everything is auto-discovered over MQTT: the firmware publishes `homeassistant/.../config` topics, so the rack's sensors, switches and numbers appear by themselves under one device, `butterfly_edfa_rack`. These files add only what discovery cannot: the derived mW power sensors, the emergency-shutdown script, and the dashboard.
|
||||
|
||||
## Files
|
||||
|
||||
| File | Where it goes on the HA host | Purpose |
|
||||
|------|------------------------------|---------|
|
||||
| `configuration.butterfly.yaml` | merge into `/config/configuration.yaml` | mW template sensors (dBm→mW for the EDFA input, pre-amp and output PDs) + the `butterfly-rack` YAML-dashboard registration |
|
||||
| `scripts.butterfly.yaml` | merge into `/config/scripts.yaml` | `butterfly_edfa_shutdown` emergency-off script |
|
||||
| `ui-lovelace-butterfly.yaml` | copy whole to `/config/ui-lovelace-butterfly.yaml` | the dashboard itself |
|
||||
| `deploy.sh` | run from this repo | push the dashboard to the host, validate config, restart HA |
|
||||
|
||||
`configuration.butterfly.yaml` and `scripts.butterfly.yaml` hold top-level keys to merge into the matching HA files; they are not standalone configs. `ui-lovelace-butterfly.yaml` is copied whole.
|
||||
|
||||
## The HA host
|
||||
|
||||
HA runs in Docker on `lab-desktop.local` (broker host `192.168.0.102`). The compose file bind-mounts `~/HA/homeassistant/` on the host as the container's `/config`, and the container is named `homeassistant`. The MQTT broker is anonymous, so this config needs no secrets; `secrets.yaml` on the host is unrelated and is git-ignored here.
|
||||
|
||||
Reach it with `ssh lab@lab-desktop.local`. The web UI is `http://lab-desktop.local:8123`; the dashboard shows in the sidebar as **Butterfly Rack** at `/butterfly-rack`.
|
||||
|
||||
## Deploy
|
||||
|
||||
```bash
|
||||
./deploy.sh # scp the dashboard, check_config, restart HA
|
||||
./deploy.sh --dash-only # just the dashboard (no restart; browser refresh picks it up)
|
||||
```
|
||||
|
||||
The dashboard reloads on a browser refresh. Changes to `configuration.yaml` or `scripts.yaml` need the restart. Merge the two snippet files into their targets on the host by hand the first time (or whenever their keys change); `deploy.sh` does not merge them for you, so it does not clobber unrelated config.
|
||||
|
||||
## Notes
|
||||
|
||||
- The `*_mw` sensors derive from the internal-PD dBm telemetry, which reads ~0.5 dB optimistic. Indicative, not calibrated.
|
||||
- The seed temperature setpoint is the CTL200 thermistor resistance (`rtset`, in ohms); the °C readout is a firmware-side NTC β-model. See the firmware repo README.
|
||||
- Safety: Class 4, >1 W, invisible 1550 nm. The dashboard's PUMP OFF / SEED OFF / SHUTDOWN controls and the shutdown script drop the pump before the seed; they are operational conveniences, not hardware interlocks.
|
||||
@@ -0,0 +1,63 @@
|
||||
# Butterfly EDFA Rack: snippet to merge into Home Assistant's configuration.yaml.
|
||||
#
|
||||
# The rack's sensors, switches and numbers arrive automatically over MQTT
|
||||
# discovery (the ESP32 firmware publishes homeassistant/.../config topics), so
|
||||
# this file only adds what discovery cannot: mW optical-power sensors derived
|
||||
# from the dBm telemetry, and the YAML-mode dashboard registration.
|
||||
#
|
||||
# These are top-level keys. Merge them into the existing configuration.yaml on
|
||||
# the HA host (do not drop its default_config:, frontend:, etc.). If an `mqtt:`
|
||||
# key already exists there, merge the sensors into it rather than adding a
|
||||
# second `mqtt:` block.
|
||||
#
|
||||
# The internal PDs read ~0.5 dB optimistic, so treat the mW figures as
|
||||
# indicative, not calibrated.
|
||||
|
||||
mqtt:
|
||||
sensor:
|
||||
- name: "Output Power mW"
|
||||
unique_id: butterfly_edfa_rack_out_mw
|
||||
state_topic: "lab/laser/butterfly_edfa_rack/amp/output1_power_dbm"
|
||||
value_template: "{{ (10 ** (value | float / 10)) | round(1) }}"
|
||||
unit_of_measurement: "mW"
|
||||
device_class: power
|
||||
state_class: measurement
|
||||
availability_topic: "lab/laser/butterfly_edfa_rack/availability"
|
||||
payload_available: "online"
|
||||
payload_not_available: "offline"
|
||||
device: { identifiers: ["butterfly_edfa_rack"] }
|
||||
# EDFA input PD = seed AFTER the external attenuators (not seed output power).
|
||||
- name: "Amp Input Power mW"
|
||||
unique_id: butterfly_edfa_rack_ampin_mw
|
||||
state_topic: "lab/laser/butterfly_edfa_rack/amp/input_power_dbm"
|
||||
value_template: "{{ (10 ** (value | float / 10)) | round(3) }}"
|
||||
unit_of_measurement: "mW"
|
||||
device_class: power
|
||||
state_class: measurement
|
||||
availability_topic: "lab/laser/butterfly_edfa_rack/availability"
|
||||
payload_available: "online"
|
||||
payload_not_available: "offline"
|
||||
device: { identifiers: ["butterfly_edfa_rack"] }
|
||||
- name: "Pre-amp Power mW"
|
||||
unique_id: butterfly_edfa_rack_preamp_mw
|
||||
state_topic: "lab/laser/butterfly_edfa_rack/amp/preamp_power_dbm"
|
||||
value_template: "{{ (10 ** (value | float / 10)) | round(1) }}"
|
||||
unit_of_measurement: "mW"
|
||||
device_class: power
|
||||
state_class: measurement
|
||||
availability_topic: "lab/laser/butterfly_edfa_rack/availability"
|
||||
payload_available: "online"
|
||||
payload_not_available: "offline"
|
||||
device: { identifiers: ["butterfly_edfa_rack"] }
|
||||
|
||||
# YAML-mode dashboard registration. Points at ui-lovelace-butterfly.yaml, which
|
||||
# must sit next to configuration.yaml in HA's /config directory.
|
||||
lovelace:
|
||||
mode: storage
|
||||
dashboards:
|
||||
butterfly-rack:
|
||||
mode: yaml
|
||||
title: Butterfly Rack
|
||||
icon: mdi:laser-pointer
|
||||
show_in_sidebar: true
|
||||
filename: ui-lovelace-butterfly.yaml
|
||||
@@ -0,0 +1,32 @@
|
||||
#!/usr/bin/env bash
|
||||
# Deploy the Butterfly-rack dashboard to the lab HA host.
|
||||
#
|
||||
# ./deploy.sh push dashboard, validate config, restart HA
|
||||
# ./deploy.sh --dash-only push dashboard only (browser refresh picks it up)
|
||||
#
|
||||
# The snippet files (configuration.butterfly.yaml, scripts.butterfly.yaml) are
|
||||
# merged into /config by hand the first time; this script never edits them on
|
||||
# the host, so it cannot clobber unrelated config.
|
||||
set -euo pipefail
|
||||
|
||||
HOST="${HA_HOST:-lab@lab-desktop.local}"
|
||||
CONFIG_DIR="${HA_CONFIG_DIR:-/home/lab/HA/homeassistant}" # bind-mounted as /config
|
||||
CONTAINER="${HA_CONTAINER:-homeassistant}"
|
||||
DASH="ui-lovelace-butterfly.yaml"
|
||||
|
||||
cd "$(dirname "$0")"
|
||||
|
||||
echo "Copying $DASH to $HOST:$CONFIG_DIR/ ..."
|
||||
scp "$DASH" "$HOST:$CONFIG_DIR/$DASH"
|
||||
|
||||
if [[ "${1:-}" == "--dash-only" ]]; then
|
||||
echo "Dashboard copied. Refresh the browser to see it."
|
||||
exit 0
|
||||
fi
|
||||
|
||||
echo "Validating config in the container ..."
|
||||
ssh "$HOST" "docker exec $CONTAINER python -m homeassistant --script check_config -c /config"
|
||||
|
||||
echo "Restarting $CONTAINER ..."
|
||||
ssh "$HOST" "docker restart $CONTAINER"
|
||||
echo "Done. HA is restarting; the dashboard is at http://lab-desktop.local:8123/butterfly-rack"
|
||||
@@ -0,0 +1,16 @@
|
||||
butterfly_edfa_shutdown:
|
||||
alias: Butterfly EDFA emergency shutdown
|
||||
icon: mdi:alarm-light
|
||||
mode: single
|
||||
sequence:
|
||||
- service: number.set_value
|
||||
target:
|
||||
entity_id: number.butterfly_edfa_rack_amp_pump_current
|
||||
data:
|
||||
value: 0
|
||||
- service: switch.turn_off
|
||||
target:
|
||||
entity_id: switch.butterfly_edfa_rack_amp_pump
|
||||
- service: switch.turn_off
|
||||
target:
|
||||
entity_id: switch.butterfly_edfa_rack_seed_laser
|
||||
@@ -0,0 +1,136 @@
|
||||
# Butterfly EDFA Rack (MOPA) — YAML-mode dashboard.
|
||||
# Registered in configuration.yaml (lovelace: dashboards: butterfly-rack).
|
||||
# Entities auto-discovered over MQTT; the *_mw power sensors are MQTT template
|
||||
# sensors defined in configuration.yaml (dBm -> mW).
|
||||
title: Butterfly Rack
|
||||
views:
|
||||
- title: MOPA
|
||||
path: mopa
|
||||
icon: mdi:laser-pointer
|
||||
cards:
|
||||
- type: vertical-stack
|
||||
title: Butterfly EDFA Rack (MOPA, 1550 nm, Class 4)
|
||||
cards:
|
||||
# ===== Graphs at the top: powers (mW) and temperatures =====
|
||||
- type: history-graph
|
||||
title: EDFA output & pre-amp PD (mW)
|
||||
hours_to_show: 1
|
||||
entities:
|
||||
- entity: sensor.butterfly_edfa_rack_output_power_mw
|
||||
name: Output PD
|
||||
- entity: sensor.butterfly_edfa_rack_pre_amp_power_mw
|
||||
name: Pre-amp PD
|
||||
|
||||
- type: history-graph
|
||||
title: EDFA input PD (mW) — seed after attenuators
|
||||
hours_to_show: 1
|
||||
entities:
|
||||
- entity: sensor.butterfly_edfa_rack_amp_input_power_mw
|
||||
name: EDFA input
|
||||
|
||||
# Seed-side signal: CTL200 monitor photodiode current. Tracks seed
|
||||
# output relatively; NOT a calibrated optical power.
|
||||
- type: history-graph
|
||||
title: Seed monitor PD (mA — relative, uncalibrated)
|
||||
hours_to_show: 1
|
||||
entities:
|
||||
- entity: sensor.butterfly_edfa_rack_seed_photodiode_current
|
||||
name: Seed monitor PD
|
||||
|
||||
- type: history-graph
|
||||
title: Temperatures (°C)
|
||||
hours_to_show: 1
|
||||
entities:
|
||||
- entity: sensor.butterfly_edfa_rack_seed_temperature
|
||||
name: Seed
|
||||
- entity: sensor.butterfly_edfa_rack_seed_board_temperature
|
||||
name: Seed board
|
||||
- entity: sensor.butterfly_edfa_rack_amp_module_temperature
|
||||
name: Amp module
|
||||
- entity: sensor.butterfly_edfa_rack_amp_pre_amp_temperature
|
||||
name: Amp pre-amp
|
||||
|
||||
# ===== Status + headline values =====
|
||||
- type: glance
|
||||
columns: 3
|
||||
entities:
|
||||
- entity: binary_sensor.butterfly_edfa_rack_seed_link
|
||||
name: Seed link
|
||||
- entity: binary_sensor.butterfly_edfa_rack_amp_link
|
||||
name: Amp link
|
||||
- entity: sensor.butterfly_edfa_rack_amp_warnings
|
||||
name: Warnings
|
||||
|
||||
- type: glance
|
||||
title: Power now (internal PDs, indicative)
|
||||
columns: 3
|
||||
entities:
|
||||
- entity: sensor.butterfly_edfa_rack_amp_input_power_mw
|
||||
name: EDFA in mW
|
||||
- entity: sensor.butterfly_edfa_rack_output_power
|
||||
name: Out dBm
|
||||
- entity: sensor.butterfly_edfa_rack_output_power_mw
|
||||
name: Out mW
|
||||
|
||||
# ===== Stage 1: seed (Koheron CTL200) =====
|
||||
- type: entities
|
||||
title: Stage 1 — Seed (turn on FIRST)
|
||||
state_color: true
|
||||
entities:
|
||||
- entity: switch.butterfly_edfa_rack_seed_laser
|
||||
name: Seed laser
|
||||
- entity: number.butterfly_edfa_rack_seed_set_current
|
||||
name: Seed current set (<= 300 mA)
|
||||
- entity: sensor.butterfly_edfa_rack_seed_current
|
||||
name: Seed current (actual)
|
||||
- entity: number.butterfly_edfa_rack_seed_thermistor_setpoint
|
||||
name: Seed temp setpoint (Ω, rtset)
|
||||
- entity: sensor.butterfly_edfa_rack_seed_temperature
|
||||
name: Seed temperature (from thermistor)
|
||||
- entity: sensor.butterfly_edfa_rack_seed_photodiode_current
|
||||
name: Seed monitor PD (mA, relative)
|
||||
|
||||
# ===== Stage 2: booster (Agiltron M511, ACC) =====
|
||||
- type: entities
|
||||
title: Stage 2 — Booster (ACC; ramp gently, settles 2-4 s)
|
||||
state_color: true
|
||||
entities:
|
||||
- entity: switch.butterfly_edfa_rack_amp_pump
|
||||
name: Booster pump enable
|
||||
- entity: number.butterfly_edfa_rack_amp_pump_current
|
||||
name: Pump-1 current set (<= 4000 mA ~ 1 W)
|
||||
- entity: sensor.butterfly_edfa_rack_amp_pump_1_current
|
||||
name: Pump-1 current (actual)
|
||||
- entity: sensor.butterfly_edfa_rack_amp_module_temperature
|
||||
name: Module temp
|
||||
|
||||
# ===== Emergency off =====
|
||||
- type: horizontal-stack
|
||||
cards:
|
||||
- type: button
|
||||
name: PUMP OFF
|
||||
icon: mdi:power-off
|
||||
icon_height: 40px
|
||||
tap_action:
|
||||
action: call-service
|
||||
service: switch.turn_off
|
||||
target:
|
||||
entity_id: switch.butterfly_edfa_rack_amp_pump
|
||||
- type: button
|
||||
name: SEED OFF
|
||||
icon: mdi:power-off
|
||||
icon_height: 40px
|
||||
tap_action:
|
||||
action: call-service
|
||||
service: switch.turn_off
|
||||
target:
|
||||
entity_id: switch.butterfly_edfa_rack_seed_laser
|
||||
- type: button
|
||||
name: SHUTDOWN
|
||||
icon: mdi:alarm-light
|
||||
icon_height: 40px
|
||||
tap_action:
|
||||
action: call-service
|
||||
service: script.butterfly_edfa_shutdown
|
||||
confirmation:
|
||||
text: Ramp pump to 0, disable booster, then seed?
|
||||
Reference in New Issue
Block a user