Free tool
ede-check — your EDE file, read by the parser that will import it
An EDE file that imports without an error is not the same as an EDE file that imports correctly. The parser Niagara ships needs five columns and silently replaces every later column left blank with a property default, so a file with no unit codes imports clean and lands unitless points. ede-check reads those rules out of the jar, then reads your file against them.
- BACnet EDE
- Reads the shipped jar
- Line by line
- Read-only
- Python 3
- MIT
Install and run
One file, standard library only. --template writes a correctly shaped
EDE file you can fill in; --check reads one you already have. Both read
the rules out of a Niagara installation first, so point it at one or set
NIAGARA_HOME.
# download it next to wherever you are working
curl -O https://plantroomlabs.com/tools/ede-check.py
# write a correctly shaped file to start from
python3 ede-check.py --template points.csv /opt/Niagara/Niagara-4.15.5.22
# or read the one a vendor sent
python3 ede-check.py --check points.csv /opt/Niagara/Niagara-4.15.5.22
What it printed here
The file in this run is the template above with two columns changed to what a point
list usually arrives as: the unit code left blank, and settable written
as yes rather than y. It imports with no error. What it
lands is three points with no units that cannot be written to.
$ python3 ede-check.py --check ahu1-ede.csv $NIAGARA_HOME
delimiter: ';' (detected)
note: BEdeConfig's delimiter property defaults to ','. Set it to ';' on the EdeConfig before importing this file, or every line arrives as one field.
ahu1-ede.csv: 3 point rows, 0 device rows, 0 trend-log rows, 8 header or comment lines
warn line 9: units (column 15) is empty - silently replaced by its property default, so this point arrives unitless
warn line 9: settable 'yes' reads as false - the test is equality with "y", so "yes", "1" and "TRUE" all mean no
warn line 10: units (column 15) is empty - silently replaced by its property default, so this point arrives unitless
warn line 10: settable 'yes' reads as false - the test is equality with "y", so "yes", "1" and "TRUE" all mean no
warn line 10: stateTextRange 'binary_active_inactive' but no state-text file given to check it against; if the EdeConfig has none either, the line is dropped
warn line 11: units (column 15) is empty - silently replaced by its property default, so this point arrives unitless
warn line 11: settable 'yes' reads as false - the test is equality with "y", so "yes", "1" and "TRUE" all mean no
warn line 11: stateTextRange 'occupancy_modes' but no state-text file given to check it against; if the EdeConfig has none either, the line is dropped
blank optional columns, each silently taking its property default: hiLimit x3, lowLimit x3, vendorSpecificAddress x3, notificationClass x3, minPresentValue x2, maxPresentValue x2, stateTextRange x1
Read from Niagara-4.15.5.22: 17 columns, first 5 mandatory, 269 unit codes, 13 object types that become points.
What it reads, and what that does not cover
It reads the EDE parser out of bacnetEDE-wb.jar with javap
— the column count, which columns are mandatory, the unit-code table and the
object types that become points — and then reads your file in Python. Nothing is
imported, no station is touched, and your file is not sent anywhere: the program runs
on your machine and prints to your terminal.
What it cannot tell you is whether the points are the right points. It reports what the parser will do with the file, not whether the file describes the plant. The unit code it flags as blank is a real omission; the object name beside it may still be wrong in a way no parser can see.
The rules above came from one installation, 4.15.5.22, and the output
names it rather than leaving it to this page. The controller this work usually
targets runs 4.14.0.162. A different Niagara version is a different
answer, so run it against yours before relying on either.
The repository
The same file, MIT licensed, at github.com/UsamaIqbal0304/ede-check, with the finding and example files in the repository rather than a description of them. Issues and pull requests are read.
The file you are downloading
Published here so the download is checkable rather than trusted. Both figures
are read off the file served at
/tools/ede-check.py when this page is built, so they cannot
disagree with it.
| Property | Value |
|---|---|
| File | ede-check.py |
| Size | 23,842 bytes |
| SHA-256 | fc082ef072ffbcf2b7f0a91954812603bf295b26aa37feefe9cdc55d2663aef7 |
| Licence | MIT — LICENSE.txt |
| Source | github.com/UsamaIqbal0304/ede-check |
To check it, on Linux sha256sum ede-check.py, on macOS
shasum -a 256 ede-check.py, on Windows
certutil -hashfile ede-check.py SHA256. A different digest means a
different file — not necessarily a hostile one, but not this one.
The repository holds the same file, byte for byte, together with everything needed to re-run the checks this page's claims rest on — so they can be run rather than read about. Issues and pull requests there are read.
bacnet-sweep
Broadcasts a BACnet/IP Who-Is, tables the devices that answer, and dumps a named device's object list — object name, present value and units — to a table or to CSV. It can encode two BACnet services and no others: Who-Is and ReadProperty.
- BACnet/IP
- Who-Is
- CSV out
mqtt-tap
Subscribes to a broker and prints what is actually on it: the topic tree with a count, a rate, a payload-type guess and the last value per topic, plus the retained topics that stopped updating. It sends five packet types and none of them is PUBLISH.
- MQTT
- Topic tree
- Retained
decoder-check
Runs a LoRaWAN device vendor's payload decoder against your frames in a sealed vm context and reports what a station would actually get back: crashes on a short frame, types that change between uplinks, units glued into values, keys a station has to escape. It reads frames and nothing else - no network, no broker, no network server.
- LoRaWAN
- Decoder
- Sandboxed
modbus-address-scan
Reads modbusCore-rt.jar out of a Niagara installation with javap and prints the register a point of each address format actually asks for — including the four band boundaries that all resolve to the same one.
- Modbus
- Shipped jars
- No station
module-sign-scan
Reads the verification code out of a Niagara installation and prints the four modes, the signature state each one accepts or refuses, and the exact log line a station writes — including the warning that only becomes a refusal when a certificate expires.
- Module signing
- Shipped jars
- No station
bacnet-priority-scan
Reads bacnet-rt.jar with javap and prints the object types Niagara writes through the priority array without asking, the ones it probes with a single ReadProperty, and what a failed probe does to the point for the life of that configuration.
- BACnet
- Shipped jars
- No station
alarm-route-scan
Reads alarm-rt.jar and baja.jar with javap and prints what happens to an alarm between the source and the recipient: one queue, one worker thread, the coalesce key that decides which duplicate is dropped, and why the invocation that lost that collision still reports success.
- Alarms
- Shipped jars
- No station
alarm-recipient-scan
Reads the recipient side of alarm-rt.jar with javap and prints why returning false from sendAlarm drops the alarm silently, what throwing does instead, how long the retry loop runs, and which four properties are the only evidence a site can send you.
- Alarms
- Retry
- No station
schedule-scan
Reads schedule-rt.jar with javap and prints the 90-day scanLimit horizon that turns a far-off change into no change at all, why nextCov steps over a boundary whose value matches, and the one serial uncapped queue every control schedule shares.
- Schedules
- Shipped jars
- No station
workbook-scan
Opens an .xlsx as the zip of XML it is and reports what is in the bytes: formulas saved holding an error, links into files that may be gone, saved queries to one person's mapped drive, approximate VLOOKUPs, hidden sheets, and rules nothing protects. It reads the old binary .xls too.
- Excel
- No install
- JSON out
poll-scheduler-scan
Reads the poll scheduler out of driver-rt.jar and prints the arithmetic: three rate defaults, one point polled per pass, and the bucket size at which the thread stops sleeping and the real cycle time stretches.
- Niagara
- javap
- Read-only
tuning-stale-scan
Reads the tuning policy and the stale branch out of the shipped jars: the default staleTime of zero, the clock it measures, and why an unsolicited device can sit dead with an ok status for as long as the station runs.
- Niagara
- javap
- Read-only
Next step
Send the EDE file and the point list it was meant to produce.
A file that imports clean and lands the wrong points is usually two or three columns, and the parser decides which. Saying which columns they are costs nothing either way.