HAN-FUN API  1.5.3
This project provides the common implementation of ULE Alliance's HAN-FUN application protocol.
example_08.cpp
Go to the documentation of this file.
1 // =============================================================================
16 // =============================================================================
17 
18 #include "hanfun.h"
19 #include "hanfun/debug.h"
20 
21 #include "localloop.h"
22 
23 // =============================================================================
24 // Implementation
25 // =============================================================================
26 
27 namespace
28 {
29  // =============================================================================
30  // Alarms
31  // =============================================================================
32 
33  /*
34  * Unit implementing the Simple %Detector profile.
35  */
36  struct SimpleDetector: public HF::Units::Unit<HF::Profiles::SimpleDetector>
37  {
38  SimpleDetector(uint8_t id, HF::IDevice &device):
39  HF::Units::Unit<HF::Profiles::SimpleDetector>(id, device)
40  {}
41  };
42 
43  /*
44  * Example alarm node.
45  */
46  struct Alarm: public HF::Devices::Node::Node
47  {
48  // Simple detector unit.
49  SimpleDetector detector;
50 
51  Alarm(): detector(1, *this) // Place unit at id 1.
52  {}
53  };
54 
55  // =============================================================================
56  // Light
57  // =============================================================================
58 
59  /*
60  * Unit implementing the Simple OnOff Switchable profile.
61  */
62  struct SimpleLight: public HF::Units::Unit<HF::Profiles::SimpleLight>
63  {
65 
66  SimpleLight(uint8_t id, HF::IDevice &device): _Parent(id, device)
67  {}
68 
69  void on(HF::Protocol::Address &source)
70  {
71  _Parent::on(source);
72  LOG(INFO) << device().address() << " : Command ON received ..." << NL;
73  }
74 
75  void off(HF::Protocol::Address &source)
76  {
77  _Parent::off(source);
78  LOG(INFO) << device().address() << " : Command OFF received ..." << NL;
79  }
80 
81  void toggle(HF::Protocol::Address &source)
82  {
83  _Parent::toggle(source);
84  LOG(INFO) << device().address() << " : Command TOGGLE received ..." << NL;
85  }
86  };
87 
88  /*
89  * Example light node.
90  */
91  struct Light: public HF::Devices::Node::Node
92  {
93  // Simple detector unit.
94  SimpleLight simple_light;
95 
96  Light(): simple_light(1, *this) // Place unit at id 1.
97  {}
98  };
99 
100  // =============================================================================
101  // Base
102  // =============================================================================
103 
104  /*
105  * Custom alert receiver.
106  */
107  struct AlertSink: public HF::Interfaces::Alert::Client
108  {
110  {
111  LOG(INFO) << "Alert received from " << source.device << "/" << (int) source.unit << " : "
112  << message.state << NL;
113 
114  auto _unit =
116 
117  HF::Protocol::Address addr = source;
118  addr.device += 3;
119  _unit->toggle(addr);
120  }
121 
122  virtual HF::Units::IUnit &unit() const = 0;
123  };
124 
125  /*
126  * Unit implementing the Simple On-Off Switch profile and %Alert client interface.
127  */
128  struct Alarm2Switch: public HF::Units::Unit<HF::Profiles::SimpleOnOffSwitch, AlertSink>
129  {
130  Alarm2Switch(uint8_t id, HF::IDevice &device):
131  HF::Units::Unit<HF::Profiles::SimpleOnOffSwitch, AlertSink>(id, device)
132  {}
133  };
134 
135  /*
136  * Example concentrator.
137  */
139  {
140  Alarm2Switch alarm2switch;
141 
142  Base(): alarm2switch(1, *this)
143  {}
144  };
145 
146 } // namespace
147 
148 // =============================================================================
149 // MAIN
150 // =============================================================================
151 
152 int main(int argc, char **argv)
153 {
154  UNUSED(argc);
155  UNUSED(argv);
156 
157  LOG(INFO) << "Use case : Catch all binding rules." << NL;
158 
159  /*
160  * Each node variable is a remote device, i.e.,
161  * the Node variables are declared on the remote device
162  * code and are not used on the base code.
163  */
164  LOG(INFO) << "Create the node instances ..." << NL;
165 
166  Alarm alarm_1;
167  Alarm alarm_2;
168  Alarm alarm_3;
169 
170  Light light_4;
171  Light light_5;
172  Light light_6;
173 
174  /*
175  * This instance represents the base application.
176  */
177  LOG(INFO) << "Create the base instance ..." << NL;
178  Base base;
179 
180  LOG(INFO) << "Create transport instance" << NL;
181  Localloop loop;
182 
183  /*
184  * Setup the network.
185  *
186  * This simulates the devices connecting to the base using for
187  * example a TCP/IP connection or a DECT ULE PVC.
188  */
189  LOG(INFO) << "Network setup ..." << NL;
190 
191  loop.set_base(&base);
192 
193  loop.add_node(&alarm_1, "alarm_1");
194  loop.add_node(&alarm_2, "alarm_2");
195  loop.add_node(&alarm_3, "alarm_3");
196 
197  loop.add_node(&light_4, "light_4");
198  loop.add_node(&light_5, "light_5");
199  loop.add_node(&light_6, "light_6");
200 
201  // Register devices.
202 
203  LOG(INFO) << "Registering alarm_1 ... " << NL;
204  alarm_1.unit0()->device_management()->register_device();
205  LOG(INFO) << "Alarm1 address ... " << alarm_1.address() << NL;
206  assert(alarm_1.address() == 1);
207 
208  LOG(INFO) << "Registering alarm_2 ... " << NL;
209  alarm_2.unit0()->device_management()->register_device();
210  LOG(INFO) << "Alarm2 address ... " << alarm_2.address() << NL;
211  assert(alarm_2.address() == 2);
212 
213  LOG(INFO) << "Registering alarm_3 ... " << NL;
214  alarm_3.unit0()->device_management()->register_device();
215  LOG(INFO) << "Alarm3 address ... " << alarm_3.address() << NL;
216  assert(alarm_3.address() == 3);
217 
218  LOG(INFO) << "Registering light_4 ... " << NL;
219  light_4.unit0()->device_management()->register_device();
220  LOG(INFO) << "Node4 address ... " << light_4.address() << NL;
221  assert(light_4.address() == 4);
222 
223  LOG(INFO) << "Registering light_5 ... " << NL;
224  light_5.unit0()->device_management()->register_device();
225  LOG(INFO) << "Node5 address ... " << light_5.address() << NL;
226  assert(light_5.address() == 5);
227 
228  LOG(INFO) << "Registering light_6 ... " << NL;
229  light_6.unit0()->device_management()->register_device();
230  LOG(INFO) << "Node6 address ... " << light_6.address() << NL;
231  assert(light_6.address() == 6);
232 
233  LOG(INFO) << "There should be 6 registered devices ... "
234  << base.unit0()->device_management()->entries().size() << NL;
235  assert(base.unit0()->device_management()->entries().size() == 6);
236 
237  LOG(INFO) << "=== Setup catch all binding for alert interface ===" << NL;
238  LOG(INFO) << "Alert commands will be sent to unit 1 on the base." << NL;
239 
240  HF::Protocol::Address source;
241  HF::Protocol::Address destination(0, 1);
243 
244  base.unit0()->bind_management()->add(source, destination, itf);
245  LOG(INFO) << "There should be one bind entry ... "
246  << base.unit0()->bind_management()->entries().size() << NL;
247  assert(base.unit0()->bind_management()->entries().size() == 1);
248 
249  LOG(INFO) << "=== Sending alarms should toggle the corresponding lights ===" << NL;
250  LOG(INFO) << "1 -> 4 | 2 -> 5 | 3 -> 6" << NL;
251 
252  LOG(INFO) << "Alarm 1 ON ..." << NL;
253  alarm_1.detector.alert(true);
254 
255  LOG(INFO) << "Alarm 2 ON ..." << NL;
256  alarm_2.detector.alert(true);
257 
258  LOG(INFO) << "Alarm 3 ON ..." << NL;
259  alarm_3.detector.alert(true);
260 
261  LOG(INFO) << "Alarm 2 OFF ..." << NL;
262  alarm_2.detector.alert(false);
263 
264  LOG(INFO) << "Alarm 3 OFF ..." << NL;
265  alarm_3.detector.alert(false);
266 
267  LOG(INFO) << "Alarm 1 OFF ..." << NL;
268  alarm_1.detector.alert(false);
269 
270  return 0;
271 }
uint8_t unit
Source Unit.
Definition: protocol.h:206
This class represents a HAN-FUN Concentrator.
Definition: base.h:302
void toggle(HF::Protocol::Address &source)
Callback that is called when a TOGGLE_CMD message is received.
Definition: node.cpp:72
This is the top level include file for the HAN-FUN library.
This file contains the prototypes of the debug functionality in HAN-FUN.
virtual void status(Protocol::Address &source, Message &message)
Callback function called when a status update message is received from an Alert server.
Definition: alert.h:382
void on(HF::Protocol::Address &source)
Callback that is called when a ON_CMD message is received.
Definition: node.cpp:60
Payload for the Status command.
Definition: alert.h:86
uint32_t state
Current state of the server.
Definition: alert.h:93
Alert Interface : Client side implementation.
Definition: alert.h:367
Alert interface UID.
Definition: interface.h:78
Helper template class to implement units.
Definition: units.h:196
This class represents the interface common to all HAN-FUN devices.
Definition: device.h:99
virtual uint16_t address() const =0
Return the device address on the HAN-FUN network, when the device is registered, or HF_BROADCAST_ADDR...
Template for HAN-FUN concentrator devices.
Definition: devices.h:906
#define NL
Helper define for new-line and stream clear.
Definition: debug.h:34
CoreServices * unit0() const
Get the unit 0 used by this concentrator device.
Definition: devices.h:910
Network Address.
Definition: protocol.h:201
IDevice & device() const
Reference to the device this unit belongs to.
Definition: units.h:107
This file contains an implementation of a HAN-FUN transport layer to be used in the example applicati...
This class represents the interface implemented by all HAN-FUN units.
Definition: units.h:48
void off(HF::Protocol::Address &source)
Callback that is called when a OFF_CMD message is received.
Definition: node.cpp:66
uint16_t device
Device Address.
Definition: protocol.h:204
#define UNUSED(x)
Helper macro to remove warning about unused function/method argument.
#define LOG(X)
Log messages with the level given by X.
Definition: debug.h:81
SimpleLight(uint8_t index, HF::IDevice &device)
Constructor.
Definition: node.h:52
Template for declaring HAN-FUN node devices.
Definition: devices.h:425
Top-level namespace for the HAN-FUN library.
Definition: attributes.h:22