refactor: carry out shade requests from one module behind a LoopQueue

HTTP routes and MQTT commands now both build a shade request and submit it
to the LoopQueue, which loop() drains into ShadeRequests. ShadeRequests
finds the shade or group, turns client positions into stored ones, checks
ranges and fills in default repeats, and reaches the shades through the
ShadeOps seam: SomfyShadeOps on the device, a recording fake in the native
tests. MqttCommands turns a .../set topic into a shade request.

Behaviour that changes:
- MQTT tiltTarget, mypos, myTiltPos and tiltPosition, and /setPositions,
  now honour flipPosition like the other routes.
- MQTT mypos keeps the favorite tilt (was set to 0) and myTiltPos keeps
  the favorite lift.
- repeat 0 on /shadeCommand means no repeats, as it did for groups; a
  JSON repeat over 127 is capped instead of wrapping to the default.
- Position corrections go through the setters, so MQTT publishes them.
- MQTT commands wait while the radio is full instead of being refused.
- The queue is drained every loop() pass and no longer from inside a
  GitHub firmware download.

WebCommand.h is replaced by LoopQueue.h and ShadeRequests.h. 45 new native
tests, 271 in all. Flash: esp32devdbg +976 bytes, esp32dev +1,380 bytes.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
cjkas 2026-10-16 09:36:46 +02:00
parent 5fd5feda28
commit 395cb2d1c7
20 changed files with 1354 additions and 569 deletions

27
src/SomfyShadeOps.h Normal file
View file

@ -0,0 +1,27 @@
#ifndef SOMFY_SHADE_OPS_H
#define SOMFY_SHADE_OPS_H
#include "ShadeRequests.h"
// ShadeOps on the device: forwards to the shades and groups of the shade
// model. Runs on loop() only.
class SomfyShadeOps : public ShadeOps {
public:
bool findShade(uint8_t shadeId, shade_info_t &info) override;
bool findGroup(uint8_t groupId, uint8_t &repeats) override;
bool moveToTarget(uint8_t shadeId, float pos) override;
bool moveToTiltTarget(uint8_t shadeId, float tilt) override;
bool sendCommand(uint8_t shadeId, somfy_commands cmd, uint8_t repeat, uint8_t stepSize) override;
bool sendTiltCommand(uint8_t shadeId, somfy_commands cmd) override;
bool isLastCommand(uint8_t shadeId, somfy_commands cmd) override;
bool repeatFrame(uint8_t shadeId, uint8_t repeat) override;
bool sendSensorCommand(uint8_t shadeId, int8_t windy, int8_t sunny, uint8_t repeat) override;
bool setMyPosition(uint8_t shadeId, int8_t pos, int8_t tilt) override;
void setPositions(uint8_t shadeId, float pos, float tilt) override;
void setUnpaired(uint8_t shadeId) override;
void setRollingCode(uint8_t shadeId, uint16_t code) override;
bool sendGroupCommand(uint8_t groupId, somfy_commands cmd, uint8_t repeat, uint8_t stepSize) override;
bool isLastGroupCommand(uint8_t groupId, somfy_commands cmd) override;
bool repeatGroupFrame(uint8_t groupId, uint8_t repeat) override;
bool sendGroupSensorCommand(uint8_t groupId, int8_t windy, int8_t sunny, uint8_t repeat) override;
};
#endif