fix(devices): zero out unassigned bell outputs when saving Bell Mechanisms
relay.set_config is a partial update on the firmware side — any bell index not present in the durations/outputs maps is left completely untouched. EditBellOutputsModal and OnboardDevice's bell config step both only sent entries for the currently-active bell count, so deselecting a bell (lowering the active count) never actually deactivated its output on the device — it stayed wired to whatever it was last set to. The only way to disable a bell was to reselect it and explicitly set it to "Disabled", which isn't obvious. Both now send all maxOutputs slots on every save, forcing output to 0 for anything beyond the active count, so lowering the active bell count reaches the firmware the way it visually appears to in the UI. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
@@ -51,11 +51,19 @@ export default function EditBellOutputsModal({ open, onClose, onSaved, attr, sub
|
|||||||
// Push to the device first — relay.set_config takes both maps in one call.
|
// Push to the device first — relay.set_config takes both maps in one call.
|
||||||
// Only write to Firestore once the device confirms it actually applied
|
// Only write to Firestore once the device confirms it actually applied
|
||||||
// and persisted the change (sendMqttCommand's toast reports the outcome).
|
// and persisted the change (sendMqttCommand's toast reports the outcome).
|
||||||
|
//
|
||||||
|
// relay.set_config is a partial update — any bell index NOT present in
|
||||||
|
// these maps is left untouched by the firmware. So every slot beyond
|
||||||
|
// activeBells must be sent explicitly as output 0 (disabled), or a bell
|
||||||
|
// that was previously active stays wired to its old output forever,
|
||||||
|
// even though it's no longer shown as active here. The only way to
|
||||||
|
// deactivate a bell today is to select it and set it to Disabled — this
|
||||||
|
// makes "deselect it" do the same thing implicitly.
|
||||||
const durations = {}
|
const durations = {}
|
||||||
const outputs = {}
|
const outputs = {}
|
||||||
activeRows.forEach((r, i) => {
|
rows.forEach((r, i) => {
|
||||||
durations[i] = r.timing
|
durations[i] = r.timing
|
||||||
outputs[i] = r.output
|
outputs[i] = i < activeBells ? r.output : 0
|
||||||
})
|
})
|
||||||
await sendMqttCommand('relay.set_config', { durations, outputs })
|
await sendMqttCommand('relay.set_config', { durations, outputs })
|
||||||
|
|
||||||
|
|||||||
@@ -1275,9 +1275,13 @@ function ConfigureStep({ device, onDeviceUpdated, onNext, onBack }) {
|
|||||||
// ── Build the command sequence + Firestore patch for each group ─────────
|
// ── Build the command sequence + Firestore patch for each group ─────────
|
||||||
const buildGroups = useCallback(() => {
|
const buildGroups = useCallback(() => {
|
||||||
const activeBellRows = bell.rows.slice(0, bell.activeBells)
|
const activeBellRows = bell.rows.slice(0, bell.activeBells)
|
||||||
|
// relay.set_config is a partial update — any bell index NOT present in
|
||||||
|
// these maps is left untouched by the firmware. Send every row (not just
|
||||||
|
// the active ones) so anything beyond activeBells is explicitly zeroed —
|
||||||
|
// same fix as EditBellOutputsModal.
|
||||||
const durations = {}
|
const durations = {}
|
||||||
const outputs = {}
|
const outputs = {}
|
||||||
activeBellRows.forEach((r, i) => { durations[i] = r.timing; outputs[i] = r.output })
|
bell.rows.forEach((r, i) => { durations[i] = r.timing; outputs[i] = i < bell.activeBells ? r.output : 0 })
|
||||||
|
|
||||||
return [
|
return [
|
||||||
{
|
{
|
||||||
|
|||||||
Reference in New Issue
Block a user