IOControl/include/IO/Request.h
Go to the documentation of this file.
1 
20 #pragma once
21 
22 #include "Error.h"
23 #include "DevNode.h"
24 #include "Event.h"
25 #include <debug_progmem.h>
26 
27 namespace IO
28 {
29 /*
30  * IO Commands
31  */
32 #define IOCOMMAND_MAP(XX) \
33  XX(undefined, "Undefined or invalid") \
34  XX(query, "Query node states") \
35  XX(off, "Turn node off or set to minimum") \
36  XX(on, "Turn node on or set to maximum") \
37  XX(toggle, "Toggle node(s) between on and off") \
38  XX(latch, "Relay nodes") \
39  XX(momentary, "Relay nodes") \
40  XX(delay, "Relay nodes") \
41  XX(set, "Set value") \
42  XX(adjust, "Adjust value") \
43  XX(update, "Perform update cycle (e.g. DMX512)")
44 
45 enum class Command {
46 #define XX(tag, comment) tag,
48 #undef XX
49 };
50 
51 } // namespace IO
52 
54 bool fromString(IO::Command& cmd, const char* str);
55 
56 namespace IO
57 {
58 class Device;
59 class Request;
60 
79 class Request : public LinkedObjectTemplate<Request>
80 {
81 public:
83 
97  using Callback = Delegate<void(const Request& request)>;
98 
100  {
101  debug_d("Request %p created", this);
102  }
103 
104  // Prevent copying; if required, add `virtual clone()`
105  Request(const Request&) = delete;
106 
107  virtual ~Request()
108  {
109  debug_d("Request %p (%s) destroyed", this, requestId.c_str());
110  }
111 
115  ErrorCode error() const
116  {
117  return errorCode;
118  }
119 
120  bool isPending() const
121  {
122  return errorCode == Error::pending;
123  }
124 
128  String caption() const;
129 
133  virtual ErrorCode parseJson(JsonObjectConst json);
134 
142  virtual void submit();
143 
144  /*
145  * Usually called by device or controller, but can also be used to
146  * pass a request to its callback first, for example on a configuration
147  * error.
148  */
149  void complete(ErrorCode err);
150 
154  virtual void getJson(JsonObject json) const;
155 
159  void setID(const String& value)
160  {
161  requestId = value;
162  }
163 
167  void setCommand(Command cmd)
168  {
169  debug_d("setCommand(0x%08x: %s)", cmd, toString(cmd).c_str());
170  command = cmd;
171  }
172 
176  void onComplete(Callback callback)
177  {
178  this->callback = callback;
179  }
180 
181  bool nodeQuery(DevNode node)
182  {
183  command = Command::query;
184  return setNode(node);
185  }
186 
187  bool nodeOff(DevNode node)
188  {
189  setCommand(Command::off);
190  return setNode(node);
191  }
192 
193  bool nodeOn(DevNode node)
194  {
195  setCommand(Command::on);
196  return setNode(node);
197  }
198 
199  bool nodeToggle(DevNode node)
200  {
201  setCommand(Command::toggle);
202  return setNode(node);
203  }
204 
209  bool nodeSet(DevNode node, int value)
210  {
211  setCommand(Command::set);
212  return setNode(node) && setValue(value);
213  }
214 
215  bool nodeAdjust(DevNode node, int value)
216  {
217  setCommand(Command::adjust);
218  return setNode(node) && setValue(value);
219  }
225  virtual bool setNode(DevNode node)
226  {
227  return false;
228  }
229 
233  virtual bool setValue(int value)
234  {
235  return false;
236  }
237 
242  {
244  }
245 
246  /*
247  * Generic set state command. 0 is off, otherwise on.
248  * Dimmable nodes use percentage level 0 - 100.
249  */
250  virtual bool setNodeState(DevNode node, DevNode::State state)
251  {
252  if(state == DevNode::State::on) {
253  setCommand(Command::on);
254  } else if(state == DevNode::State::off) {
255  setCommand(Command::off);
256  } else {
257  return false;
258  }
259  return setNode(node);
260  }
261 
265  const CString& id() const
266  {
267  return requestId;
268  }
269 
271  {
272  return command;
273  }
274 
278  virtual void handleEvent(Event event);
279 
281 
282 private:
283  Callback callback;
284  Command command{Command::undefined};
285  ErrorCode errorCode{Error::pending};
286  CString requestId;
287 };
288 
289 } // namespace IO
#define IOCOMMAND_MAP(XX)
Definition: IOControl/include/IO/Request.h:32
bool fromString(IO::Command &cmd, const char *str)
String toString(IO::Command cmd)
Manage a set of bit values using enumeration.
Definition: BitSet.h:45
Class to manage a NUL-terminated C-style string When storing persistent strings in RAM the regular St...
Definition: CString.h:27
const char * c_str() const
Definition: CString.h:100
Handles requests for a specific device; the requests are executed by the relevant controller.
Definition: Libraries/IOControl/include/IO/Device.h:36
Request represents a single user request/response over a bus.
Definition: IOControl/include/IO/Request.h:80
Device & device
Definition: IOControl/include/IO/Request.h:280
bool nodeOff(DevNode node)
Definition: IOControl/include/IO/Request.h:187
virtual bool setNodeState(DevNode node, DevNode::State state)
Definition: IOControl/include/IO/Request.h:250
ErrorCode error() const
Request error code defaults to 'pending' and is set on completion.
Definition: IOControl/include/IO/Request.h:115
bool nodeAdjust(DevNode node, int value)
Definition: IOControl/include/IO/Request.h:215
virtual bool setValue(int value)
If nodes support values, implement this method.
Definition: IOControl/include/IO/Request.h:233
Request(const Request &)=delete
void setCommand(Command cmd)
Set the command code.
Definition: IOControl/include/IO/Request.h:167
virtual void handleEvent(Event event)
Implementations may override this method as required.
virtual DevNode::States getNodeStates(DevNode node)
Query node status from response.
Definition: IOControl/include/IO/Request.h:241
void complete(ErrorCode err)
virtual void getJson(JsonObject json) const
Get result of a completed request in JSON format.
void setID(const String &value)
Request identifiers are optional, useful for tracking remote requests.
Definition: IOControl/include/IO/Request.h:159
Command getCommand() const
Definition: IOControl/include/IO/Request.h:270
virtual ~Request()
Definition: IOControl/include/IO/Request.h:107
bool nodeToggle(DevNode node)
Definition: IOControl/include/IO/Request.h:199
virtual ErrorCode parseJson(JsonObjectConst json)
Fill this request from a JSON description.
void onComplete(Callback callback)
Set the request completion callback.
Definition: IOControl/include/IO/Request.h:176
bool nodeQuery(DevNode node)
Definition: IOControl/include/IO/Request.h:181
String caption() const
Get a descriptive caption for this request.
virtual bool setNode(DevNode node)
If nodes are supported, implement this method.
Definition: IOControl/include/IO/Request.h:225
Request(Device &device)
Definition: IOControl/include/IO/Request.h:99
bool nodeOn(DevNode node)
Definition: IOControl/include/IO/Request.h:193
bool isPending() const
Definition: IOControl/include/IO/Request.h:120
const CString & id() const
Get the request ID, if there is one.
Definition: IOControl/include/IO/Request.h:265
bool nodeSet(DevNode node, int value)
For nodes supporting analogue state (e.g. brightness)
Definition: IOControl/include/IO/Request.h:209
virtual void submit()
Submit a request.
Base class template for linked items with type casting.
Definition: LinkedObject.h:62
The String class.
Definition: WString.h:137
#define debug_d
Definition: debug_progmem.h:100
Json json
@ pending
Definition: Libraries/IOControl/include/IO/Error.h:72
Definition: IOControl/include/IO/Controller.h:26
Command
Definition: IOControl/include/IO/Request.h:45
XX(tag, comment)
Event
Definition: Event.h:36
int16_t ErrorCode
Definition: Libraries/IOControl/include/IO/Error.h:27
Identifies a device node.
Definition: DevNode.h:30
State
Definition: DevNode.h:36
#define str(s)
Definition: testrunner.h:124