mirror of
https://github.com/rstrouse/ESPSomfy-RTS.git
synced 2026-10-31 22:02:17 +01:00
The 19 routes that changed rooms, shades, groups and repeaters on the web
server task (add, save, delete, link and unlink, setPaired, the sort
orders) now copy their request into a model_edit_t, queue it on the
LoopQueue and reply {status:accepted,requestId:N}. loop() applies it
(SomfyJson.cpp, next to fromJSON) and broadcasts requestResult {requestId,
ok, id, code, desc}. One edit at a time; a second gets 503, a body over
4 KB gets 413.
ModelEditor.h/.cpp holds the rules, tested natively: the lowest free id,
the next sort order, a free remote address, adding to and removing from
the group-member and repeater lists, and the GPIO pin-conflict check. They
replace the getNext*Id/getMax*Order copies, the remote-address search,
the list code and the inline pin checks. The pin check now uses the
protocol being saved and checks every pin against Ethernet, not only up.
/getNextRoom, /getNextShade, /getNextGroup, /groupOptions and a new
/repeaters (the UI already called it) are ModelSnapshot reads.
The web UI's editJSON() sends an edit, waits for its requestResult, then
reads the item back from /shade, /group, /room or /repeaters, so the
callbacks that used the old reply bodies are unchanged. No result within
5 s offers a reload; reads and edits told Busy are retried. It now also
refreshes its lists on shadeAdded/shadeRemoved/groupAdded/groupRemoved
from other clients, and procRoomRemoved keeps the right rooms.
Also fixed: a shade that fails validation is no longer added; linked
repeaters and sort orders are saved; linking reports a full list.
27 new native tests, 319 in all. Flash: esp32devdbg -11,484 bytes,
esp32dev -7,180 bytes.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
112 lines
4.4 KiB
C++
112 lines
4.4 KiB
C++
#include <esp_task_wdt.h>
|
|
#include "Somfy.h"
|
|
#include "SomfyEditor.h"
|
|
#include "Sockets.h"
|
|
#include "entryPoints/MQTT.h"
|
|
|
|
extern SomfyShadeController somfy;
|
|
extern SocketEmitter sockEmit;
|
|
extern MQTTClass mqtt;
|
|
|
|
void SomfyShade::emitState(const char *evt) { this->emitState(255, evt); }
|
|
void SomfyShade::emitState(uint8_t num, const char *evt) {
|
|
JsonSockEvent *json = sockEmit.beginEmit(evt);
|
|
json->beginObject();
|
|
json->addElem("shadeId", this->shadeId);
|
|
json->addElem("type", static_cast<uint8_t>(this->shadeType));
|
|
json->addElem("remoteAddress", (uint32_t)this->getRemoteAddress());
|
|
json->addElem("name", this->name);
|
|
json->addElem("direction", this->direction);
|
|
json->addElem("position", this->transformPosition(this->currentPos));
|
|
json->addElem("target", this->transformPosition(this->target));
|
|
json->addElem("myPos", this->transformPosition(this->myPos));
|
|
json->addElem("tiltType", static_cast<uint8_t>(this->tiltType));
|
|
json->addElem("flipCommands", this->flipCommands);
|
|
json->addElem("flipPosition", this->flipPosition);
|
|
json->addElem("flags", this->flags);
|
|
json->addElem("sunSensor", this->hasSunSensor());
|
|
json->addElem("light", this->hasLight());
|
|
json->addElem("sortOrder", this->sortOrder);
|
|
if(this->tiltType != tilt_types::none) {
|
|
json->addElem("tiltDirection", this->tiltDirection);
|
|
json->addElem("tiltTarget", this->transformPosition(this->tiltTarget));
|
|
json->addElem("tiltPosition", this->transformPosition(this->currentTiltPos));
|
|
json->addElem("myTiltPos", this->transformPosition(this->myTiltPos));
|
|
}
|
|
json->endObject();
|
|
sockEmit.endEmit(num);
|
|
}
|
|
void SomfyShade::emitCommand(somfy_commands cmd, const char *source, uint32_t sourceAddress, const char *evt) { this->emitCommand(255, cmd, source, sourceAddress, evt); }
|
|
void SomfyShade::emitCommand(uint8_t num, somfy_commands cmd, const char *source, uint32_t sourceAddress, const char *evt) {
|
|
JsonSockEvent *json = sockEmit.beginEmit(evt);
|
|
json->beginObject();
|
|
json->addElem("shadeId", this->shadeId);
|
|
json->addElem("remoteAddress", (uint32_t)this->getRemoteAddress());
|
|
json->addElem("cmd", translateSomfyCommand(cmd).c_str());
|
|
json->addElem("source", source);
|
|
json->addElem("rcode", (uint32_t)this->lastRollingCode);
|
|
json->addElem("sourceAddress", (uint32_t)sourceAddress);
|
|
json->endObject();
|
|
sockEmit.endEmit(num);
|
|
if(mqtt.connected()) {
|
|
this->publish("cmdSource", source);
|
|
this->publish("cmdAddress", sourceAddress);
|
|
this->publish("cmd", translateSomfyCommand(cmd).c_str());
|
|
}
|
|
}
|
|
void SomfyRoom::emitState(const char *evt) { this->emitState(255, evt); }
|
|
void SomfyRoom::emitState(uint8_t num, const char *evt) {
|
|
JsonSockEvent *json = sockEmit.beginEmit(evt);
|
|
json->beginObject();
|
|
json->addElem("roomId", this->roomId);
|
|
json->addElem("name", this->name);
|
|
json->addElem("sortOrder", this->sortOrder);
|
|
json->endObject();
|
|
sockEmit.endEmit(num);
|
|
this->publish();
|
|
}
|
|
void SomfyGroup::emitState(const char *evt) { this->emitState(255, evt); }
|
|
void SomfyGroup::emitState(uint8_t num, const char *evt) {
|
|
uint8_t flags = 0;
|
|
JsonSockEvent *json = sockEmit.beginEmit(evt);
|
|
json->beginObject();
|
|
json->addElem("groupId", this->groupId);
|
|
json->addElem("remoteAddress", (uint32_t)this->getRemoteAddress());
|
|
json->addElem("name", this->name);
|
|
json->addElem("sunSensor", this->hasSunSensor());
|
|
json->beginArray("shades");
|
|
for(uint8_t i = 0; i < SOMFY_MAX_GROUPED_SHADES; i++) {
|
|
if(this->linkedShades[i] != 255 && this->linkedShades[i] != 0) {
|
|
SomfyShade *shade = somfy.getShadeById(this->linkedShades[i]);
|
|
if(shade) {
|
|
json->addElem(this->linkedShades[i]);
|
|
flags |= shade->flags;
|
|
}
|
|
}
|
|
}
|
|
json->endArray();
|
|
json->addElem("flags", flags);
|
|
json->endObject();
|
|
sockEmit.endEmit(num);
|
|
this->publish();
|
|
}
|
|
// To every client: the sender picks out its own by requestId.
|
|
void emitRequestResult(uint32_t requestId, const edit_result_t &result) {
|
|
JsonSockEvent *json = sockEmit.beginEmit("requestResult");
|
|
json->beginObject();
|
|
json->addElem("requestId", requestId);
|
|
json->addElem("ok", result.ok);
|
|
json->addElem("id", result.id);
|
|
json->addElem("code", result.code);
|
|
json->addElem("desc", result.desc);
|
|
json->endObject();
|
|
sockEmit.endEmit();
|
|
}
|
|
void SomfyShadeController::emitState(uint8_t num) {
|
|
for(uint8_t i = 0; i < SOMFY_MAX_SHADES; i++) {
|
|
SomfyShade *shade = &this->shades[i];
|
|
if(shade->getShadeId() == 255) continue;
|
|
esp_task_wdt_reset();
|
|
shade->emitState(num);
|
|
}
|
|
}
|