matterbridge-plugin-nolongerevil-thermostat
v1.0.0
Published
Matterbridge plugin that bridges No Longer Evil self-hosted Nest thermostats to Matter, with live SSE-driven updates.
Maintainers
Readme
Matterbridge No Longer Evil Thermostat Plugin
Bridges No Longer Evil self-hosted Nest thermostats into Matterbridge, exposing each thermostat to Matter controllers (Apple Home, Google Home, SmartThings, Home Assistant, …) with sub-second live updates.
What it does
For every thermostat reported by your No Longer Evil control server the plugin exposes:
- A Thermostat device with
LocalTemperature,OccupiedHeatingSetpoint,OccupiedCoolingSetpoint,SystemMode(Off/Heat/Cool/Auto), andControlSequenceOfOperationderived from each device'scan_heat/can_coolcapabilities. - A separate on/off Away switch —
onputs the thermostat in away mode,offreturns to home.
State syncs both ways:
- Writes from a Matter controller (changing mode, setpoint, away) are translated into
POST /commandcalls on the No Longer Evil control server. - The No Longer Evil
GET /api/eventsSSE stream drives near-instant updates back to Matter (the plugin re-fetches/status?serial=…on each event and pushes attribute updates). - A defensive periodic poll (configurable, default 5 minutes) re-syncs every device to recover from any missed events or dropped streams.
Requirements
- A running No Longer Evil self-hosted control server (typically port
8082). - Matterbridge
>= 3.4.0. - Node.js
>= 20.19.0(>= 22.13.0for the 22.x line,>= 24.0.0for the 24.x line).
The plugin currently targets the self-hosted No Longer Evil control server. The hosted API at
nolongerevil.com/api/v1is not yet supported because it does not expose the SSE event stream the plugin relies on for live updates.
Install
npm install -g matterbridge-plugin-nolongerevil-thermostat
matterbridge -add matterbridge-plugin-nolongerevil-thermostatThen open the Matterbridge frontend and configure the plugin (see below).
Configuration
The plugin reads its config from Matterbridge's plugin settings UI (or matterbridge-plugin-nolongerevil-thermostat.config.json):
| Field | Type | Default | Description |
| ---------------------- | -------- | ----------------------- | ---------------------------------------------------------------------------------------------------------------- |
| apiUrl | string | http://localhost:8082 | Base URL of the No Longer Evil self-hosted control server. No trailing slash needed. |
| pollIntervalSeconds | integer | 300 | Defensive periodic re-sync. Live updates use SSE; this poll catches anything the stream missed. 0 disables it. |
| whiteList | string[] | [] | Only thermostats whose name or serial appears here will be exposed. Empty = all. |
| blackList | string[] | [] | Thermostats whose name or serial appears here are excluded. |
| debug | boolean | false | Verbose plugin logging. |
| unregisterOnShutdown | boolean | false | Unregister all devices on shutdown — useful during development. |
Security note
The No Longer Evil self-hosted control server has no authentication by default. If you expose it outside your trusted LAN, put it behind a reverse proxy with proper auth before pointing this plugin at it.
Mode mapping
| No Longer Evil mode | Matter SystemMode |
| ------------------- | ------------------- |
| off | Off (0) |
| heat | Heat (4) |
| cool | Cool (3) |
| range | Auto (1) |
| emergency | EmergencyHeat (5) |
In range/Auto mode the plugin uses the target_temperature_low / target_temperature_high fields and writes both bounds when either setpoint is changed from a Matter controller.
Out of scope (for now)
The first release deliberately keeps the surface small. The following are not exposed yet but the codebase has clean seams for adding them:
- Fan control (
set_fan/ MatterFanControlcluster) - Humidity reporting
- Schedule editing
- Setting
EmergencyHeatfrom a Matter controller (it's read-back only)
Troubleshooting
"SSE event stream reconnecting after: terminated" every 30–60 s
This is expected behavior with some servers and reverse proxies — the SSE connection gets closed when idle, the plugin reconnects automatically, and no events are lost outside a sub-second gap. The info-level log entry is intentionally visible so you can confirm the loop is healthy.
Plugin shows the away switch but no thermostat
Make sure you're running v1.0.0 or later — earlier dev builds had a unit-encoding bug that caused thermostat registration to fail silently.
Two devices with the same name
You may have stale registrations from a prior run. Either:
- Set
unregisterOnShutdown: true, restart matterbridge, then turn it back off; or matterbridge -remove .thenmatterbridge -add ..
Development
npm install
npm run build
npm run test # Jest, must hit 100% coverage on lines + functions
npm run test:vitest # Vitest mirror
npm run lint
npm run format:checkTo run against a local Matterbridge:
npm run dev:link # links the global matterbridge package
npm run matterbridge:add
matterbridgeLicense
This plugin is built on the excellent matterbridge-plugin-template by Luca Liguori.
