Skip to content

Add emergency lighting (DT1) memory bank 208 and query helpers - #159

Merged
sde1000 merged 4 commits into
sde1000:masterfrom
tridonic-com:dt1
Oct 16, 2026
Merged

sde1000 merged 4 commits into
sde1000:masterfrom
tridonic-com:dt1

Conversation

@markus-becker-tridonic-com

Copy link
Copy Markdown
Contributor

Summary

Implements IEC 62386-202 self-contained emergency control-gear support: the
memory bank 208 variable definitions and the sequence helpers an application
controller needs to read emergency status and issue DT1 control commands.

What's included

  • dali/memory/emergency.py — memory bank 208 (Table 18): control-gear
    temperatures, battery charge/maintenance powers, rated duration,
    recharge/function-test times, and the full set of failure, mode, test and
    lamp counters (~40 MemoryValue definitions).
  • dali/gear/sequences.py
    • QueryEmergencyInformation(address) — bundles the DT1 status and
      measurement queries into a single sequence so the required
      ENABLE DEVICE TYPE 1 prefix is injected correctly.
    • EmergencyCommand(address, command_class) — issues a single DT1 control
      command.
  • Fake-gear emergency support and tests for the bank, the information
    sequence, and the control-command helper.

Testing

pytest dali/tests/test_emergency.py dali/tests/test_memory.py → 27 passed.

Notes

Builds on the existing dali/gear/emergency.py command classes already in
master. Single commit, applies cleanly on top of master.

Comment thread dali/gear/sequences.py Outdated
emergency control gear in a single sequence.

Running it as a sequence ensures the required "ENABLE DEVICE TYPE 1"
command is sent before each application-extended command, so the gear

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This comment is misleading. This being a sequence has nothing to do with the driver sending appropriate EnableDeviceType commands.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in 3697e86.

Comment thread dali/gear/sequences.py Outdated
command is sent before each application-extended command, so the gear
answers. The returned values are plain integers (or None where the gear
reports MASK or does not answer); the four status bytes are returned as
raw bytes so the caller can decode individual bits.

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it would be more useful for the status to be decoded here and represented in EmergencyInformation.

Might it be better for EmergencyInformation to be a dataclass rather than a namedtuple so its members can be typed appropriately?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done in 3847672.

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah. That's not quite what I meant!

Information about what the status bits mean is already present in dali.gear.emergency — the responses are dali.command.BitmapResponse subclasses which already have attributes for each bit. (Eg. a QueryEmergencyModeResponse instance has attributes rest_mode, normal_mode, emergency_mode etc.)

Your sequence was throwing this information away by treating the responses as plain integers. I suggest you preserve the response classes in the dataclass for the sequence return value.

You need to decide what to do if any of the responses are missing or framing errors. I think the sequence should probably abort in this case rather than return a dataclass containing error responses.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Take a look in 2336038.

@sde1000

sde1000 commented Oct 16, 2026

Copy link
Copy Markdown
Owner

Can you update the version of IEC 62386-202 used when writing this code in the list in the README.rst, please?

Implements the IEC 62386-202 self-contained emergency control gear
variable definitions and sequence helpers consumed by application
controllers:

- dali/memory/emergency.py: memory bank 208 (Table 18) with the control
  gear temperatures, battery charge/maintenance powers, rated duration,
  recharge/function-test times, and the full set of failure, mode, test
  and lamp counters.
- dali/gear/sequences.py: QueryEmergencyInformation bundles the DT1
  status and measurement queries into a single sequence (so the required
  ENABLE DEVICE TYPE 1 prefix is injected), and EmergencyCommand issues a
  single DT1 control command.
- Fake gear emergency support plus tests for the bank, the information
  sequence and the control-command helper.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The driver sends EnableDeviceType before every application-extended
command on its own, independent of whether the command is part of a
sequence. Reword the docstring to state the actual benefit: bundling the
queries into one transaction so nothing interleaves between them.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Represent the four DT1 status bytes as EmergencyMode, EmergencyFeatures,
EmergencyFailureStatus and EmergencyStatus dataclasses with one bool field
per IEC 62386-202 bit, and turn EmergencyInformation itself into a dataclass
so every member is typed. Callers no longer have to know the bit layout.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Review feedback: the QueryEmergencyInformation sequence was throwing away
the decoded bit attributes by flattening each response into plain
integers and bespoke dataclasses. The dali.gear.emergency responses are
command.BitmapResponse subclasses that already expose a named attribute
per status bit, and the numeric responses already decode MASK.

Keep each query's response object in EmergencyInformation so callers can
read the named status bits and measurement values directly, and abort the
sequence with a DALISequenceError if any query goes unanswered or returns
a framing error instead of returning a dataclass full of error responses.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@markus-becker-tridonic-com

Copy link
Copy Markdown
Contributor Author

Can you update the version of IEC 62386-202 used when writing this code in the list in the README.rst, please?

Done. Folded into the initial commit.

@sde1000
sde1000 merged commit 4380b87 into sde1000:master Oct 16, 2026
5 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants