src/
Coverage:
low: ≥ 0%
medium: ≥ 75.0%
high: ≥ 90.0%
Lines:
2 / 2
100.0%
Branches:
-
-%
Functions:
2 / 2
100.0%

ShadeRequests.h
Line Branch Exec Source
1 #ifndef SHADE_REQUESTS_H
2 #define SHADE_REQUESTS_H
3 #include <stdint.h>
4 #include "SomfyFrame.h"
5 #include "ShadeTypes.h"
6
7 // Shade requests from the entry points (HTTP and MQTT) and the domain module
8 // that carries them out on loop(). Kept free of the shade model so it can be
9 // unit tested on the PC (pio test -e native).
10
11 enum class shade_request_type_t : uint8_t {
12 shade_command, // move the shade to target, or send command
13 group_command, // send command to the group
14 tilt_command, // move the tilt to target, or send command to the tilt
15 shade_repeat, // send command, or repeat it when it was the last one sent
16 group_repeat, // the same for a group
17 set_positions, // correct where the shade is thought to be; sends nothing
18 shade_sensor, // send a sensor frame as the shade
19 group_sensor, // send a sensor frame as the group
20 set_favorite, // set or clear the shade's favorite
21 unpair, // send Prog and clear paired
22 set_rolling_code // set the shade's rolling code; sends nothing
23 };
24
25 // Positions are as the client sees them: 0-100, counted from the other end on
26 // a shade with flipPosition, and -1 when not given.
27 struct shade_request_t {
28 shade_request_type_t type = shade_request_type_t::shade_command;
29 uint8_t id = 255; // shade id, or group id for group_*
30 int8_t target = -1; // shade/tilt_command: -1 sends command instead
31 somfy_commands command = somfy_commands::My;
32 int8_t repeat = -1; // -1 for the shade's or group's own repeats
33 uint8_t stepSize = 0;
34 int8_t position = -1; // set_positions, set_favorite
35 int8_t tiltPosition = -1; // set_positions, set_favorite
36 int8_t sunny = -1; // *_sensor: -1 leaves it as it is
37 int8_t windy = -1;
38 uint16_t rollingCode = 0; // set_rolling_code
39 };
40
41 // Whether the request sends anything on air.
42 bool shadeRequestUsesRadio(shade_request_type_t type);
43 // Whether the request's id is a group id rather than a shade id.
44 bool shadeRequestIsForGroup(shade_request_type_t type);
45 // A repeat count from a client: negative for the default, capped at what fits.
46 int8_t requestRepeat(int32_t repeat);
47 // A target from a client: -1 unless it is 0-100.
48 int8_t requestTarget(int32_t target);
49
50 // What ShadeRequests needs to know about a shade. Positions are stored ones.
51 struct shade_info_t {
52 bool flipPosition = false;
53 shade_types shadeType = shade_types::roller;
54 tilt_types tiltType = tilt_types::none;
55 uint8_t repeats = 1;
56 uint8_t bitLength = 56;
57 float currentPos = 0.0f;
58 float myPos = -1.0f;
59 float myTiltPos = -1.0f;
60 bool idle = true; // not moving, and at its target
61 };
62
63 // The seam between ShadeRequests and the shades and groups it acts on. On the
64 // device it is the shade model (SomfyShadeOps); the tests record the calls.
65 // Positions are stored ones, so already turned round for a flipped shade.
66 class ShadeOps {
67 public:
68 1 virtual ~ShadeOps() {}
69 virtual bool findShade(uint8_t shadeId, shade_info_t &info) = 0;
70 // repeats is the group's own repeat count.
71 virtual bool findGroup(uint8_t groupId, uint8_t &repeats) = 0;
72 // The bool ones return false when the radio refused a command they sent.
73 virtual bool moveToTarget(uint8_t shadeId, float pos) = 0;
74 virtual bool moveToTiltTarget(uint8_t shadeId, float tilt) = 0;
75 virtual bool sendCommand(uint8_t shadeId, somfy_commands cmd, uint8_t repeat, uint8_t stepSize) = 0;
76 virtual bool sendTiltCommand(uint8_t shadeId, somfy_commands cmd) = 0;
77 virtual bool isLastCommand(uint8_t shadeId, somfy_commands cmd) = 0;
78 virtual bool repeatFrame(uint8_t shadeId, uint8_t repeat) = 0;
79 virtual bool sendSensorCommand(uint8_t shadeId, int8_t windy, int8_t sunny, uint8_t repeat) = 0;
80 virtual bool setMyPosition(uint8_t shadeId, int8_t pos, int8_t tilt) = 0;
81 // A negative position leaves that one as it is.
82 virtual void setPositions(uint8_t shadeId, float pos, float tilt) = 0;
83 virtual void setUnpaired(uint8_t shadeId) = 0;
84 virtual void setRollingCode(uint8_t shadeId, uint16_t code) = 0;
85 virtual bool sendGroupCommand(uint8_t groupId, somfy_commands cmd, uint8_t repeat, uint8_t stepSize) = 0;
86 virtual bool isLastGroupCommand(uint8_t groupId, somfy_commands cmd) = 0;
87 virtual bool repeatGroupFrame(uint8_t groupId, uint8_t repeat) = 0;
88 virtual bool sendGroupSensorCommand(uint8_t groupId, int8_t windy, int8_t sunny, uint8_t repeat) = 0;
89 };
90
91 // How a request went. One with nothing in range to do is done.
92 enum class shade_request_result_t : uint8_t {
93 done,
94 not_found, // no shade or group with that id; nothing was done
95 radio_refused, // the radio didn't take a command it sent
96 shade_moving, // a favorite is only set on a shade at rest; nothing was done
97 no_tilt // only a tilt was given, for a shade without one; nothing was done
98 };
99
100 // Carries out shade requests, whichever entry point they came from: finds
101 // the shade or group, turns client positions into stored ones, checks
102 // ranges and fills in default repeats. Runs on loop() only.
103 class ShadeRequests {
104 public:
105 1 explicit ShadeRequests(ShadeOps &ops) : ops(ops) {}
106 shade_request_result_t run(const shade_request_t &req);
107 private:
108 ShadeOps &ops;
109 };
110 #endif
111