Releases: suburbazine/Unifi-Notification-Matrix
Release list
v0.5.6
What changed
Added
-
The Web settings offer the Windows Firewall rule for the ports they
choose. On a real site the acknowledgement address was right and the
router forwarded the port, and every Acknowledge button still timed out:
Windows Firewall dropped the connection before this program saw it. It took
a rule typed by hand into Defender.Under Settings → Web, a Windows Firewall card now says, for the
ack-only listener and the peer link listener, whether a rule lets them in:
allowed, blocked, out of date (wrong port, switched off, or for
another copy of the program), or not needed (not set,autountil its
first start, or on this machine only). Allow through Windows Firewall
creates or corrects the rules, and the Activity log records which ports it
opened. Beside it is the exact PowerShell the button runs, to paste into an
administrator terminal instead. That is the way when this program is
running from an ordinary terminal without the rights, or when you would
rather do it yourself.It works from the saved addresses, so a port changed and saved on this page
gets its rule before the restart that opens it. It never opens Listen on,
which is this page and its sign-in. Each rule allows one TCP port for this
program only, and belongs to theNotifyMatrixgroup so it is easy to
find.notifymatrix uninstallremoves them. The router still needs its own
forward for anything reached from outside the building. -
A paired product's refused events are now impossible to miss. When a
peer sends a kind of event its approved list does not include, which is
usually its next release reporting something new, every one is refused
until somebody approves it. All that said so was a card well down Settings
→ Peer link and a line in its receipts. At a real site, a new Rewards
release's events were refused for as long as it took somebody to look
there.Now a banner on every tab, the wall board included, says how many kinds of
event are waiting and how many have been refused, and links to the
decision. The Settings tab carries the count. In Peer link the decision
comes first, as a warning, and every refusal in the receipts has a
Decide now button that goes to it. The banner shows counts only; which
product and which conditions stay behind the sign-in. Nothing changes for
the paired product: refused events are answered exactly as before, and it
keeps retrying until the decision is made.
Changed
- The Ack-only listener's help now says the link needs the same port.
http://your.name:50001goes with0.0.0.0:50001, unless the router
deliberately forwards a different outside port to it. It used to say only
"never your public hostname", which read as if the two should differ.
Fixed
- An install fed only by paired products is no longer called "not set
up". With Rewards, LSProtect or Sentry paired and no UniFi console, the
header said not set up, Setup showed a red count, and a large box across
the incident board said Nothing is being watched yet … nothing can raise
one, while the paired products were raising incidents. A paired product
now counts as something being watched. The board shows its usual Nothing
open state, and the console and sources steps are marked optional ("not
needed: 1 paired product raises incidents here") rather than to-do. A
console that is configured but broken is still a to-do.
Verifying this release
Every binary is signed. Verification instructions, including how to
rebuild from source and compare hashes, are in
docs/RELEASING.md.
Linux / macOS — cosign (keyless, no key to trust in advance):
cosign verify-blob notifymatrix-linux-amd64 \
--bundle notifymatrix-linux-amd64.sigstore.json \
--certificate-identity-regexp '^https://github\.com/suburbazine/Unifi-Notification-Matrix/' \
--certificate-oidc-issuer https://token.actions.githubusercontent.com
Download the .sigstore.json next to the binary; it carries the
signature, the certificate and the transparency-log proof. Keep
--certificate-identity-regexp — without it cosign verifies a
signature from anyone.
Build provenance (any platform):
gh attestation verify notifymatrix-linux-amd64 --repo suburbazine/Unifi-Notification-Matrix
Windows: the .exe is Authenticode-signed and timestamped.
Right-click → Properties → Digital Signatures, or:
Get-AuthenticodeSignature .\notifymatrix-windows-amd64.exe
This is source-available software under the
PolyForm Noncommercial License 1.0.0. Commercial use
requires a licence: licensing@xtremission.com
Full Changelog: v0.5.5...v0.5.6
v0.5.5
What changed
Fixed
-
An acknowledgement address with no port is now called out, with the
fix. Withweb.ack_base_urlset tohttp://plus a name and no port,
every Acknowledge button and link goes to port 80. If acknowledgements are
answered somewhere else, such as an ack-only listener on port 50001, not
one of them works. Nothing said so: each setting looked right on its own,
and Setup marked the step as close to done. Found on a real site by the new
channel test, as a phone that could not connect.Setup now marks the step as to-do and gives the address to set, port
included. The same sentence is printed at every start, and pressing Send
a test on a channel shows it at once, instead of fifteen minutes of a
button that times out.https://addresses with no port are left alone,
because that is port 443 with a TLS proxy in front, which is the
recommended setup. So is an address with a port typed on purpose.
Verifying this release
Every binary is signed. Verification instructions, including how to
rebuild from source and compare hashes, are in
docs/RELEASING.md.
Linux / macOS — cosign (keyless, no key to trust in advance):
cosign verify-blob notifymatrix-linux-amd64 \
--bundle notifymatrix-linux-amd64.sigstore.json \
--certificate-identity-regexp '^https://github\.com/suburbazine/Unifi-Notification-Matrix/' \
--certificate-oidc-issuer https://token.actions.githubusercontent.com
Download the .sigstore.json next to the binary; it carries the
signature, the certificate and the transparency-log proof. Keep
--certificate-identity-regexp — without it cosign verifies a
signature from anyone.
Build provenance (any platform):
gh attestation verify notifymatrix-linux-amd64 --repo suburbazine/Unifi-Notification-Matrix
Windows: the .exe is Authenticode-signed and timestamped.
Right-click → Properties → Digital Signatures, or:
Get-AuthenticodeSignature .\notifymatrix-windows-amd64.exe
This is source-available software under the
PolyForm Noncommercial License 1.0.0. Commercial use
requires a licence: licensing@xtremission.com
Full Changelog: v0.5.4...v0.5.5
v0.5.4
What changed
Changed
-
Testing ntfy, Pushover or email now tests the Acknowledge button too.
The test used to send each channel's own hand-written message with nothing
to press on it. It proved the message arrived and nothing about
acknowledging it, which is how ntfy's Acknowledge button could do nothing
(fixed in 0.5.2) while every test passed.The test now sends a real alert about a real test incident. It is built by
the same code as every other alert and carries the same button or link.
Press Acknowledge on it, on the device, and the settings page says
Acknowledged via ntfy — acknowledgement works from ntfy. If it was
acknowledged from the web page instead, or closed without being
acknowledged, the page says that instead. Ifweb.ack_base_urlis not set,
the alert has no button on it, and the page says so and why.A test never escalates and never counts as alerting on the board. If nobody
acknowledges it, it is closed after fifteen minutes. Pressing test again
replaces the one still waiting, and a restart closes any test it
interrupted. Voice and webhooks test the way they did before: nobody
acknowledges from either.
Fixed
- A fresh install opened straight onto Settings now offers the first
password. It usually showed a plain Password box instead, with nowhere to
put the setup token. Anything typed there was refused with "no password is
set yet". The page drew the card before it knew setup was still needed, and
did not redraw it once it did. Going to another tab and back got past it. - A listener bound to this machine's LAN address is no longer called
unreachable. Withweb.listenset to an address like
192.168.1.50:8322, every start warned that nothing was listening where a
phone could reach it, and advised0.0.0.0. A phone on that LAN reaches it
perfectly well. The warning now fires only when the listeners are on
loopback, which is the case it was written for.
Verifying this release
Every binary is signed. Verification instructions, including how to
rebuild from source and compare hashes, are in
docs/RELEASING.md.
Linux / macOS — cosign (keyless, no key to trust in advance):
cosign verify-blob notifymatrix-linux-amd64 \
--bundle notifymatrix-linux-amd64.sigstore.json \
--certificate-identity-regexp '^https://github\.com/suburbazine/Unifi-Notification-Matrix/' \
--certificate-oidc-issuer https://token.actions.githubusercontent.com
Download the .sigstore.json next to the binary; it carries the
signature, the certificate and the transparency-log proof. Keep
--certificate-identity-regexp — without it cosign verifies a
signature from anyone.
Build provenance (any platform):
gh attestation verify notifymatrix-linux-amd64 --repo suburbazine/Unifi-Notification-Matrix
Windows: the .exe is Authenticode-signed and timestamped.
Right-click → Properties → Digital Signatures, or:
Get-AuthenticodeSignature .\notifymatrix-windows-amd64.exe
This is source-available software under the
PolyForm Noncommercial License 1.0.0. Commercial use
requires a licence: licensing@xtremission.com
Full Changelog: v0.5.3...v0.5.4
v0.5.3
What changed
Take this one if you run Sentry. Stopping Sentry now hands the doors back
to this product at once, at every site, with nothing to re-pair.
Changed
-
A stopped Sentry hands the doors back at every site, with nothing to
re-pair or edit. Sentry 1.6.16 reports when it is running but watching
nothing, and that is meant to put this product's own Access ingest straight
back in charge. At a site paired on an earlier Sentry, though, that report
was refused until somebody approved it — and approving it from the Peer link
page deliberately does not let it take anything back, so a stopped Sentry
kept the doors, watched by nothing, until its silence window ran out.This release accepts Sentry's monitoring-stopped report on its own, at start
and at pairing, and makes it hand Access back. It is safe to accept
unreviewed for one reason: all it can ever do is make this product watch the
doors itself. It cannot silence anything.The reply to a paired product's event now says whether raising it hands the
capability back, so Sentry's log can say what will happen when it is stopped
instead of guessing from how old its pairing is.
Verifying this release
Every binary is signed. Verification instructions, including how to
rebuild from source and compare hashes, are in
docs/RELEASING.md.
Linux / macOS — cosign (keyless, no key to trust in advance):
cosign verify-blob notifymatrix-linux-amd64 \
--bundle notifymatrix-linux-amd64.sigstore.json \
--certificate-identity-regexp '^https://github\.com/suburbazine/Unifi-Notification-Matrix/' \
--certificate-oidc-issuer https://token.actions.githubusercontent.com
Download the .sigstore.json next to the binary; it carries the
signature, the certificate and the transparency-log proof. Keep
--certificate-identity-regexp — without it cosign verifies a
signature from anyone.
Build provenance (any platform):
gh attestation verify notifymatrix-linux-amd64 --repo suburbazine/Unifi-Notification-Matrix
Windows: the .exe is Authenticode-signed and timestamped.
Right-click → Properties → Digital Signatures, or:
Get-AuthenticodeSignature .\notifymatrix-windows-amd64.exe
This is source-available software under the
PolyForm Noncommercial License 1.0.0. Commercial use
requires a licence: licensing@xtremission.com
Full Changelog: v0.5.2...v0.5.3
v0.5.2
What changed
Take this one if you acknowledge alerts from ntfy. The Acknowledge button
did not acknowledge anything — and made it look as though it had.
Fixed
-
ntfy's Acknowledge button acknowledged nothing, then cleared the
notification. The button is a background request: ntfy sends it and shows
nobody the answer. It sent a GET, and the acknowledgement link answers a GET
with an "are you sure?" page — on purpose, because mail scanners open links,
and a link that acknowledged on a GET would let one acknowledge an alarm
nobody saw. So the page was rendered to nobody, nothing was acknowledged,
and the notification then disappeared from the phone. The operator believed
the alarm was dealt with while it went on escalating.The button now POSTs, which acknowledges in one tap — a tapped button is a
person, not a prefetcher. The acknowledgement is recorded as coming through
ntfy. If the phone cannot reach the acknowledgement address, ntfy keeps the
notification and shows the error, rather than clearing it.Alerts sent before you upgrade still carry the old button. Acknowledge those
from the incident board, or by opening the link and confirming.
Added
-
Each paired product has its own silence window. It was sixteen minutes
for every peer. When a Sentry update left a site's Sentry dead, those were
sixteen minutes in which nothing watched the doors: while Sentry holds
Access, this product's own Access ingest stands down, and it only took the
doors back when the window ran out.Set
silent_afterunder a product inconfig.yaml—2mfor Sentry, say —
and it applies within seconds, no restart. After that long without contact
the product is reported silent and, if it holds a capability, loses it at
the same moment, so this product's own source takes over in two minutes
instead of sixteen. Blank keeps sixteen minutes; the window is kept between
a minute and a day, and a value outside that is used at the nearest limit
with a warning rather than refusing to start.The product is told how often to heartbeat to meet its window — a third of
it — in every reply, so a change reaches it at its next contact. Sentry
1.6.15, Lightspeed Rewards and LSProtect follow it; an older release keeps
heartbeating every five minutes, and the Peer link page now warns when a
product is going longer between contacts than its window, before its
silence alarm fires for a product that is fine.Shortening a window never pages anybody about a healthy product: it learns
its new rate at its next contact, and until then it is held to the window it
was last told. After this product restarts, a product not yet heard from is
given at least six minutes — the slowest rate it might still be on, and a
minute — before it can be reported silent.
Verifying this release
Every binary is signed. Verification instructions, including how to
rebuild from source and compare hashes, are in
docs/RELEASING.md.
Linux / macOS — cosign (keyless, no key to trust in advance):
cosign verify-blob notifymatrix-linux-amd64 \
--bundle notifymatrix-linux-amd64.sigstore.json \
--certificate-identity-regexp '^https://github\.com/suburbazine/Unifi-Notification-Matrix/' \
--certificate-oidc-issuer https://token.actions.githubusercontent.com
Download the .sigstore.json next to the binary; it carries the
signature, the certificate and the transparency-log proof. Keep
--certificate-identity-regexp — without it cosign verifies a
signature from anyone.
Build provenance (any platform):
gh attestation verify notifymatrix-linux-amd64 --repo suburbazine/Unifi-Notification-Matrix
Windows: the .exe is Authenticode-signed and timestamped.
Right-click → Properties → Digital Signatures, or:
Get-AuthenticodeSignature .\notifymatrix-windows-amd64.exe
This is source-available software under the
PolyForm Noncommercial License 1.0.0. Commercial use
requires a licence: licensing@xtremission.com
Full Changelog: v0.5.1...v0.5.2
v0.5.1
What changed
Take this one if you pair other products with this. When a paired product
keeps using a credential it no longer holds — as a Sentry watch did after a
re-pair — the Peer link page now says which product and what to do, instead
of reporting a stranger.
Changed
- A product still sending with a credential this installation retired is
named on the Peer link page, instead of being reported as "a credential
this installation has no record of". Re-pairing a product, or unpairing it
here, retires its previous credential, and part of the product may not
notice: a Sentry watch kept signing its heartbeats and its door events with
the credential a re-pair had replaced, and every one was refused as if a
stranger were knocking. The receipt now says whose credential it was, when
and why it was retired, and what to do — restart the product rather than
pair it again, which would only retire another.
Verifying this release
Every binary is signed. Verification instructions, including how to
rebuild from source and compare hashes, are in
docs/RELEASING.md.
Linux / macOS — cosign (keyless, no key to trust in advance):
cosign verify-blob notifymatrix-linux-amd64 \
--bundle notifymatrix-linux-amd64.sigstore.json \
--certificate-identity-regexp '^https://github\.com/suburbazine/Unifi-Notification-Matrix/' \
--certificate-oidc-issuer https://token.actions.githubusercontent.com
Download the .sigstore.json next to the binary; it carries the
signature, the certificate and the transparency-log proof. Keep
--certificate-identity-regexp — without it cosign verifies a
signature from anyone.
Build provenance (any platform):
gh attestation verify notifymatrix-linux-amd64 --repo suburbazine/Unifi-Notification-Matrix
Windows: the .exe is Authenticode-signed and timestamped.
Right-click → Properties → Digital Signatures, or:
Get-AuthenticodeSignature .\notifymatrix-windows-amd64.exe
This is source-available software under the
PolyForm Noncommercial License 1.0.0. Commercial use
requires a licence: licensing@xtremission.com
Full Changelog: v0.5.0...v0.5.1
v0.5.0
What changed
Take this one if you pair other Xtremission products with this, or intend
to. Two new ones — Lightspeed Rewards and LSProtect — can pair for the first
time, every paired product now has a deadman, and events that are a new fact
each time they arrive are kept one by one instead of folded away.
A minor rather than a patch because incidents can now carry something they
never carried before, and the store gains a table to hold it.
Added
-
Every occurrence of a per-occurrence event is kept, and one after review
alerts again. Some events are a new fact every time they arrive — a sale
voided at a register, a free item handed out with no loyalty reward behind
it. Folding a repeat into the open incident used to keep the first arrival
and discard the rest, so a second void was recorded nowhere, and a void
arriving after a manager had acknowledged the incident was delivered to
nobody at all.An incident now counts how many times the thing it is about has happened
and keeps each arrival in full — its own title, detail and severity — with
the most recent hundred kept and the total never capped. The alert carries
the newest arrival and says which occurrence it is and since when. The
incident board shows the count and the list.An acknowledgement is a review of what had arrived when it was given. An
arrival after it closes the reviewed incident and opens a fresh one linked
to it, which escalates from the first rung. The acknowledgement stays on the
record exactly as it was given.This applies to a paired product's momentary conditions only. Nothing about
this product's own sources changes: motion arrives in bursts, and a new
incident for every burst after an acknowledgement would page somebody all
afternoon.A condition can opt out, so that an acknowledgement also covers what
follows: the peer declaresper_occurrence: falsefor it, or the operator
sets it under the peer'soverridesinconfig.yaml. Sentry's access
denials are the first such condition — a single denial after somebody has
already looked at the cascade is not news, while a credential sweep after
review still is. Sentry declares it itself from 1.6.12; at a site paired on
an earlier Sentry, this release writes the override intoconfig.yamlon
its own at start, where it can be seen and changed. Set
per_occurrence: trueexplicitly to keep denials re-alerting instead. -
A paired product that stands in for none of this product's sources can
pair. A peer used to have to claim a capability — Sentry claims Access, and
our own Access ingest stands down while it is healthy. A loyalty system or a
point-of-sale bridge claims nothing, and could not pair at all. The claim is
now optional; one that is made must name protect, access or network. -
Every paired product has a deadman. A peer that claimed nothing had its
heartbeats recorded nowhere, so if the machine it runs on died, nothing
noticed. Any authenticated request from a peer now counts as contact —
nothing unauthenticated does, or anybody on the network could keep a dead
peer looking alive — and sixteen minutes of silence raises "Peer link: … has
gone silent", cleared the moment it is heard from again.
Fixed
-
An occurrence is stamped with when it happened, not when it reached this
product — a peer replaying events queued during an outage would otherwise
list every one at the minute the queue drained. (Found in the live pairing
tests, before release.) -
A peer's momentary events that cleared quickly were never delivered. Whether
a cleared incident is still owed an alert was decided from this product's
own catalogue only, so a peer's own declaration — and the operator's override
of it — were read by nothing. An event raised and cleared before the first
scheduler pass reached nobody. That included Sentry's link test. -
The pairing request no longer has a field for the pairing code. It was
never read — the proof is what is checked — but a client following the
structure would send the code itself, handing it to anything that
terminated TLS on the way. A client that still sends it is not refused. -
After a notification channel was saved, a paired peer was told the health
of channels that had been closed. The reply's delivery status read the
channel set as it was at start; since 0.4.2 a save replaces that set. It now
reads the one in use.
Verifying this release
Every binary is signed. Verification instructions, including how to
rebuild from source and compare hashes, are in
docs/RELEASING.md.
Linux / macOS — cosign (keyless, no key to trust in advance):
cosign verify-blob notifymatrix-linux-amd64 \
--bundle notifymatrix-linux-amd64.sigstore.json \
--certificate-identity-regexp '^https://github\.com/suburbazine/Unifi-Notification-Matrix/' \
--certificate-oidc-issuer https://token.actions.githubusercontent.com
Download the .sigstore.json next to the binary; it carries the
signature, the certificate and the transparency-log proof. Keep
--certificate-identity-regexp — without it cosign verifies a
signature from anyone.
Build provenance (any platform):
gh attestation verify notifymatrix-linux-amd64 --repo suburbazine/Unifi-Notification-Matrix
Windows: the .exe is Authenticode-signed and timestamped.
Right-click → Properties → Digital Signatures, or:
Get-AuthenticodeSignature .\notifymatrix-windows-amd64.exe
This is source-available software under the
PolyForm Noncommercial License 1.0.0. Commercial use
requires a licence: licensing@xtremission.com
Full Changelog: v0.4.2...v0.5.0
v0.4.2
What changed
Take this one if you have ever waited for a restart to make a setting
count. Saved settings now apply to the running daemon — channels, escalation,
rules, quiet hours, hooks and consoles — and so does a config.yaml you edit
by hand. Only the listen addresses still need the daemon stopped.
Also fixes two things reported from a live site: time zones could not be set at
all on Windows, and every Network offline incident claimed the device had been
down for three minutes.
Added
-
Silence an alarm from the alarm. A card for something you have decided
you do not want to hear about — a camera on a failing PoE port, a door sensor
being worked on — now carries Silence…, which writes the ignore rule for
you and closes the incident.The rule is built from the incident, not from anything the page sends, and it
matches exactly that alarm: that condition, from that device, on that source.
Nothing wider. It is an ordinary rule: it appears in Settings › Rules and is
removed there, and the audit record names it, so "why was I not told about
that camera" has an answer months later.A critical alarm cannot be silenced this way, and the refusal is in the
API rather than only in the page. Quiet hours never apply to critical either.
If a critical alarm really should be silenced, the rule can be written in
Settings, deliberately, with the whole rule list in front of you.
Changed
-
Saved settings take effect immediately. Channels, escalation ladders,
rules, quiet hours and inbound hooks were all built once when the daemon
started and never rebuilt, so every save updated the file, updated the
screen, and left the running process deciding by the old configuration —
with nothing anywhere saying the two had parted company. A restart was the
only way to close the gap, and a restart is not a neutral act: it drops every
console connection and re-polls everything.The worst of it was invisible. A channel enabled and saved was a channel this
daemon had never heard of: "ntfy is not enabled" when you pressed Test,
contradicting the screen you were looking at — and the same stale set
delivered the real alarms, so it would have been told nothing at 3am. A new
inbound hook's URL returned the same 404 as a mistyped token until you
restarted.A change that cannot be applied is refused rather than half-applied, and says
which subsystem kept its old configuration and that a restart will close the
gap.Consoles too, and a console nobody touched keeps its connection. Protect
holds a WebSocket, a backoff ladder and the table that turns an update frame
into a clear; saving an unrelated setting no longer costs any of them. Which
sources are unchanged is decided by what each was built from — host,
application, that application's key, the pinned fingerprint — rather than by
its name, because every source of an application shares one name and a
corrected API key would otherwise be taken for the broken source it replaces.A
config.yamledited by hand is applied too, a few seconds after you
finish editing it — the setup guide tells you to edit that file, so the
documented path was the one that silently did nothing. The log says when a
change was applied, and says why if the file will not load.The listen addresses still need a restart — a socket already bound cannot
be moved under the connections using it. That is now the only thing that
does, and the Web section offers the restart itself, only when one of those
addresses actually changed. Everywhere else, a save says it is in effect.
Fixed
-
Every Network offline incident claimed the device had been down for three
minutes. Three minutes is the threshold — how long a device must be seen
down before it counts as an outage at all — and the incident quoted that
constant instead of measuring anything. Access points that had been off for
weeks were reported as three-minute outages.It now says how long the device has actually been down. And when the device
was already down at the first poll — which is every pre-existing outage,
every time the daemon restarts — it says that instead, because the age of
that outage is genuinely unknown: this API carries no events and no timestamp
on a device, so the only clock available is our own, which started at the
restart. An incident that quotes it reads as something that has just broken. -
On Windows, every time zone name was refused. Setting quiet hours to
America/New_York— the example printed beside the field — failed, while
UTCworked, which reads as the slash in the name breaking the field. It was
not the slash: those two are simply the only names that resolve without a
time zone database, and Windows has none. The binary fell back to a copy
inside a Go installation, which no machine running a release has.Worse than a rejected field: quiet hours are checked when the configuration
loads, so a zone written intoconfig.yamlby hand refused the daemon's
start outright, and the site was then watched by nothing.The database now travels inside the binary, which also covers a Linux install
whose image carries notzdatapackage. It costs 402KB.The site's time zone is not only about quiet hours — it is the clock every
alert is announced in, so anyone running on Windows who left it blank has
been getting times in the server's zone.
Verifying this release
Every binary is signed. Verification instructions, including how to
rebuild from source and compare hashes, are in
docs/RELEASING.md.
Linux / macOS — cosign (keyless, no key to trust in advance):
cosign verify-blob notifymatrix-linux-amd64 \
--bundle notifymatrix-linux-amd64.sigstore.json \
--certificate-identity-regexp '^https://github\.com/suburbazine/Unifi-Notification-Matrix/' \
--certificate-oidc-issuer https://token.actions.githubusercontent.com
Download the .sigstore.json next to the binary; it carries the
signature, the certificate and the transparency-log proof. Keep
--certificate-identity-regexp — without it cosign verifies a
signature from anyone.
Build provenance (any platform):
gh attestation verify notifymatrix-linux-amd64 --repo suburbazine/Unifi-Notification-Matrix
Windows: the .exe is Authenticode-signed and timestamped.
Right-click → Properties → Digital Signatures, or:
Get-AuthenticodeSignature .\notifymatrix-windows-amd64.exe
This is source-available software under the
PolyForm Noncommercial License 1.0.0. Commercial use
requires a licence: licensing@xtremission.com
Full Changelog: v0.4.1...v0.4.2
v0.4.1
What changed
Take this one if you have ever edited config.yaml by hand. A file without
an ack_key brought up a daemon with no interface on any port and said nothing
about why. Everything else here is the interface being less tiring to use.
Changed
-
The tabs stay with you down a long page. Settings runs past eight
thousand pixels and Help is longer; changing tab meant scrolling all the way
back to the top first. The tab bar is now stuck beneath the header, and on a
phone — where three stacked bars would eat a quarter of the screen — the
header scrolls away instead and the tabs take the top.The Settings section rail, the chip strip a phone shows in its place, and
every anchored heading were all offset by the height of the header alone;
they now key off the height of everything stuck above them, so a section you
jump to lands below the chrome rather than behind it. That last part was
already slightly wrong at phone width before this change.
Fixed
-
A configuration without an acknowledgement key started a daemon with no
interface, and said nothing about it.The key is normally generated the first time notifymatrix writes its own
configuration file, so an installation that went through setup has always had
one. Aconfig.yamlwritten by hand — or restored from a backup taken before
the key existed — did not, and the entire web surface was conditional on it:
no settings page, no status board, no acknowledgement endpoint, no peer link.The daemon started anyway. It reported itself running, watched the site, and
sent alerts carrying acknowledgement links that pointed at a port nothing was
listening on. The only symptom was a browser that could not connect to a
service the service manager said was up.The key is now generated when the configuration is opened rather than only
when it is written, and it is kept, so links already sent keep working across
a restart. If one still cannot be generated — a data directory that is not
writable — the daemon now refuses to start and says so, instead of running
headless and looking healthy.
Verifying this release
Every binary is signed. Verification instructions, including how to
rebuild from source and compare hashes, are in
docs/RELEASING.md.
Linux / macOS — cosign (keyless, no key to trust in advance):
cosign verify-blob notifymatrix-linux-amd64 \
--bundle notifymatrix-linux-amd64.sigstore.json \
--certificate-identity-regexp '^https://github\.com/suburbazine/Unifi-Notification-Matrix/' \
--certificate-oidc-issuer https://token.actions.githubusercontent.com
Download the .sigstore.json next to the binary; it carries the
signature, the certificate and the transparency-log proof. Keep
--certificate-identity-regexp — without it cosign verifies a
signature from anyone.
Build provenance (any platform):
gh attestation verify notifymatrix-linux-amd64 --repo suburbazine/Unifi-Notification-Matrix
Windows: the .exe is Authenticode-signed and timestamped.
Right-click → Properties → Digital Signatures, or:
Get-AuthenticodeSignature .\notifymatrix-windows-amd64.exe
This is source-available software under the
PolyForm Noncommercial License 1.0.0. Commercial use
requires a licence: licensing@xtremission.com
Full Changelog: v0.4.0...v0.4.1
v0.4.0
What changed
Take this one if you run UniFi Access. Its notifications socket moved, and
earlier builds cannot find it — which means no live door events, silently.
A minor rather than a patch because alerts can now carry a sentence they never
carried before, and there is a new panel on the Health tab to go with it.
Added
-
Alerts can say whether they arrived alone or in a crowd, and the Health
tab shows what the crowd is.The motivating case is a wireless jammer before a break-in: several devices
going quiet at once, none of them decisive on its own. Not caught as
unusual silence — a site that is normally silent at 3am has no signal to
lose — but as the disconnect burst the jamming causes, which is many devices
at once and is what the measurement watches for.Spread carries the verdict and volume never does alone. Fifty events
from one flapping camera is not a surge and must never read as one; nine
devices producing one each is the shape that matters. Events that rules
silenced are counted, because a site whose motion is suppressed is still a
site with motion in it, and those are exactly the events a jammer removes.Decoration only. It cannot move a severity or a ladder: a statistical
signal nudging a real alarm up a tier is how a firmware rollout becomes a
phone call at 3am.The baseline is learned per hour, weekday and weekend apart, over eight
weeks, and is not quoted until it has been earned — fourteen days, and
twenty-four comparable stretches for the hour in question. Until then the
panel states the count and says what it is waiting for.It stays quiet in two states where a sentence would be worse than none:
under ten minutes of uptime, and while any source is not reporting. The
panel says which, because "nothing unusual" and "we are not watching all of
it" look identical on a screen and are opposite facts.At 144 stretches a day for 56 days the history is 8,064 rows for any site,
busy or quiet, pruned as it is written.
Fixed
-
The Access notifications socket moved, and this build now finds it. On
an ENVR running current Access,/proxy/access/api/v1/developer/devices/notifications
answers 404 to a key whoseintegrationREST paths return 28 doors — and
the same path under the REST base connects and delivers. Captured by the
probe on real hardware, which is why this is a fact rather than a guess.Both paths are tried, current firmware first, and the one that connects is
remembered so a reconnect never pays the 404 twice. The older path is kept
because the only two door-state message shapes this build knows were
captured there, and a site on that firmware must not lose its socket to a
fix for another. -
A keepalive is no longer evidence that the stream is unintelligible.
That console sends a bare string six times a minute, plus an informational
event about its own log depth. Counted as frames nobody could read, fifty of
them raise a high incident saying door-forced detection is degraded — on
a console whose socket is working perfectly, because nobody has opened a
door yet. Which is most sites at 3am.Protocol noise is now counted apart from failures to understand. The alarm
still fires for what it was built for: door state arriving in a shape this
build cannot read.
Changed
-
A Network device going offline now raises
low, nothigh. On the
default laddershighwakes somebody — for an access point rebooting, a PoE
port cycling, or a switch that was unplugged on purpose. Most of what
polling a controller produces is operational noise, and an operator woken by
it either stops trusting the product or turns the source off.What makes one of these serious is the company it keeps: the same outage
taking a camera or a door controller with it. The Network source polls one
API and knows nothing about Protect or Access, so deciding that there would
be a guess dressed as a severity. A site that knows which switch carries the
door hardware raises that one with a rule.
Fixed
-
"The only way Network events exist at all" was wrong, and read as
"Network needs webhooks". A console with an API key andnetworkin its
sources already reports switches and access points going offline, derived
from polling, with no rule involved. Alarm Manager rules are for the alarms
no API carries — WAN outages, threat detections, PoE faults, and Protect's
own hardware alarms.Corrected in the README, in the setup guide, in the checklist's own
reasoning, and on the Webhooks screen, which now says plainly that none of
it is needed to watch a console.
Verifying this release
Every binary is signed. Verification instructions, including how to
rebuild from source and compare hashes, are in
docs/RELEASING.md.
Linux / macOS — cosign (keyless, no key to trust in advance):
cosign verify-blob notifymatrix-linux-amd64 \
--bundle notifymatrix-linux-amd64.sigstore.json \
--certificate-identity-regexp '^https://github\.com/suburbazine/Unifi-Notification-Matrix/' \
--certificate-oidc-issuer https://token.actions.githubusercontent.com
Download the .sigstore.json next to the binary; it carries the
signature, the certificate and the transparency-log proof. Keep
--certificate-identity-regexp — without it cosign verifies a
signature from anyone.
Build provenance (any platform):
gh attestation verify notifymatrix-linux-amd64 --repo suburbazine/Unifi-Notification-Matrix
Windows: the .exe is Authenticode-signed and timestamped.
Right-click → Properties → Digital Signatures, or:
Get-AuthenticodeSignature .\notifymatrix-windows-amd64.exe
This is source-available software under the
PolyForm Noncommercial License 1.0.0. Commercial use
requires a licence: licensing@xtremission.com
Full Changelog: v0.3.9...v0.4.0