feat!: remove the old API, ports 8081 and 8080 (step 4a)

Step 4a of docs/SECURITY_PLAN.md. Port 80 keeps the eleven HTTP routes of
ADR 0006 and the socket at /ws; everything else moved to protocol 2.

- Port 8081 (ApiRoutes) and the socket on 8080 (SocketEmitter) are gone.
  Protocol 2 owns its frame buffer and loop-task check.
- Port 80 drops every route the old web UI called: reads, edits,
  settings, scans, reboot, /shades.cfg, /discovery. HttpRoutes.cpp holds
  what stays.
- ModelSnapshot, SnapshotSlots and the read documents are gone. The item
  snapshot types stay, as ItemSnapshot, for events, MQTT and the command
  replies.
- Model edits reply only to their protocol 2 op: requestResult goes.
- The settings' toJSON writers, used only by the settings routes, go.
- The _espsomfy_rts._tcp mDNS record moves to port 80, with path=/ws.
- The memory event reports the loop-rate window it closes.
- A deleted room no longer re-publishes its retained MQTT topics.
- e2e: the heap check reads the sync's status; the sync is checked on
  its own instead of against /controller.
- README gets an API and ports section.

BREAKING CHANGE: ports 8081 and 8080 and the old HTTP routes are gone.
Home Assistant needs integration 3.0.0 or newer.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
cjkas 2026-10-27 21:49:38 +01:00
parent c91c20d444
commit 2a954aa158
53 changed files with 613 additions and 3549 deletions

View file

@ -57,16 +57,16 @@ struct rebootDelay_t {
else if(str[0] == 'f' || str[0] == 'F' || str[0] == '0') return false;
return def;
}
// Whether a wifiStrength broadcast is worth sending: always on a channel change,
// Whether a wifi broadcast is worth sending: always on a channel change,
// otherwise only for an RSSI change of at least minDelta dBm.
bool rssiNeedsEmit(int rssi, int lastRssi, int channel, int lastChannel, int minDelta);
// What the last wifiStrength broadcast told every client. Only broadcasts
// move it: an emit to one new client tells the others nothing.
// What the last wifi broadcast told every client. A client that connects gets
// the signal in its sync, which tells the others nothing, so it isn't moved.
struct RssiBroadcast {
int rssi = 0;
int channel = 0;
bool due(int rssi, int channel, int minDelta) const;
void sent(bool broadcast, int rssi, int channel);
void sent(int rssi, int channel);
};
// Whether an AP a scan found for our SSID is worth connecting to. While
// connected it has to be at least minGain dBm stronger than the current AP so
@ -74,7 +74,7 @@ struct RssiBroadcast {
bool worthRoaming(bool connected, int currentRssi, int apRssi, int minGain);
// Whether the calling task may send socket events. They are all formatted
// into one shared buffer, so only loop()'s task may. owner is that task, or
// null before SocketEmitter::begin() has recorded it (setup() runs there too).
// null before ProtoSocket::begin() has recorded it (setup() runs there too).
bool emitAllowed(const void *current, const void *owner);
// A short name for a wifi_auth_mode_t value, for the logs. The values up to
// WAPI are the same in ESP-IDF 4.4 and 5.x.
@ -91,10 +91,9 @@ void releaseAssetName(char *buf, size_t size, const char *kind, const char *chip
// depth is how many the dump claims are valid.
void formatBacktrace(char *buf, size_t size, const uint32_t *bt, size_t maxFrames, uint32_t depth);
// How well loop() keeps up: the passes it made per second and its longest
// pass, over the window since the last memStatus broadcast. Only the loop
// pass, over the window since the last memory broadcast. Only the loop
// task calls record(), rate(), maxUs() and publish(). publish() closes the
// window and keeps its figures where another task (the /discovery response)
// can read them without seeing a half reset window.
// window and keeps its figures for the memory event and a client's sync.
class LoopStats {
uint32_t _passes = 0;
uint32_t _maxUs = 0;