Open Lighting Architecture 0.10.9
Loading...
Searching...
No Matches
RDMMessagePrinters.h
Go to the documentation of this file.
1/*
2 * This library is free software; you can redistribute it and/or
3 * modify it under the terms of the GNU Lesser General Public
4 * License as published by the Free Software Foundation; either
5 * version 2.1 of the License, or (at your option) any later version.
6 *
7 * This library is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
10 * Lesser General Public License for more details.
11 *
12 * You should have received a copy of the GNU Lesser General Public
13 * License along with this library; if not, write to the Free Software
14 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
15 *
16 * RDMMessagePrinters.h
17 * Write out RDM Messages in a human-readable format.
18 * Copyright (C) 2010 Simon Newton
19 */
20
29#ifndef INCLUDE_OLA_RDM_RDMMESSAGEPRINTERS_H_
30#define INCLUDE_OLA_RDM_RDMMESSAGEPRINTERS_H_
31
32#include <ola/Logging.h>
33#include <ola/StringUtils.h>
34#include <ola/messaging/MessagePrinter.h>
35#include <ola/rdm/PidStore.h>
36#include <ola/rdm/RDMHelper.h>
37#include <ola/rdm/UID.h>
38#include <ola/strings/Format.h>
39#include <iomanip>
40#include <set>
41#include <string>
42#include <vector>
43
44
45namespace ola {
46namespace rdm {
47
52 public:
53 explicit RDMMessagePrinter(unsigned int initial_ident = 0)
55 ola::messaging::GenericMessagePrinter::DEFAULT_INDENT,
56 initial_ident) {
57 }
58 protected:
59 std::string TransformLabel(const std::string &label) {
60 std::string new_label = label;
62 return new_label;
63 }
64};
65
66
71 public:
72 void Visit(const ola::messaging::UIDMessageField *field) {
73 Stream() << field->Value() << std::endl;
74 }
75};
76
77
82 public:
83 void Visit(const ola::messaging::UInt8MessageField *field) {
84 if (m_messages.empty()) {
85 return;
86 }
87 m_messages.back().status_type = field->Value();
88 m_messages.back().status_type_defined = true;
89 }
90
91 void Visit(const ola::messaging::Int16MessageField *field) {
92 if (m_messages.empty()) {
93 return;
94 }
95 status_message &message = m_messages.back();
96 if (message.int_offset < MAX_INT_FIELDS) {
97 message.int16_fields[message.int_offset++] = field->Value();
98 }
99 }
100
101 void Visit(const ola::messaging::UInt16MessageField *field) {
102 if (m_messages.empty()) {
103 return;
104 }
105 status_message &message = m_messages.back();
106 if (message.uint_offset < MAX_UINT_FIELDS) {
107 message.uint16_fields[message.uint_offset++] = field->Value();
108 }
109 }
110
111 void Visit(const ola::messaging::GroupMessageField*) {
112 status_message message;
113 m_messages.push_back(message);
114 }
115
116 protected:
117 void PostStringHook() {
118 std::vector<status_message>::const_iterator iter = m_messages.begin();
119 for (; iter != m_messages.end(); ++iter) {
120 if (!iter->status_type_defined ||
121 iter->uint_offset != MAX_UINT_FIELDS ||
122 iter->int_offset != MAX_INT_FIELDS) {
123 OLA_WARN << "Invalid status message";
124 continue;
125 }
126
127 const std::string message = StatusMessageIdToString(
128 iter->uint16_fields[1],
129 iter->int16_fields[0],
130 iter->int16_fields[1]);
131
132 Stream() << StatusTypeToString(iter->status_type) << ": ";
133 if (iter->uint16_fields[0]) {
134 Stream() << "Sub-device " << iter->uint16_fields[0] << ": ";
135 }
136
137 if (message.empty()) {
138 Stream() << " message-id: " << iter->uint16_fields[1] << ", data1: "
139 << iter->int16_fields[0] << ", data2: "
140 << iter->int16_fields[1] << std::endl;
141 } else {
142 Stream() << message << std::endl;
143 }
144 }
145 }
146
147 private:
148 enum { MAX_INT_FIELDS = 2 };
149 enum { MAX_UINT_FIELDS = 2 };
150 struct status_message {
151 public:
152 uint16_t uint16_fields[MAX_UINT_FIELDS];
153 int16_t int16_fields[MAX_INT_FIELDS];
154 uint8_t uint_offset;
155 uint8_t int_offset;
156 uint8_t status_type;
157 bool status_type_defined;
158
159 status_message() : uint_offset(0), int_offset(0), status_type(0),
160 status_type_defined(false) {}
161 };
162 std::vector<status_message> m_messages;
163};
164
165
170 public:
171 SupportedParamsPrinter(uint16_t manufacturer_id,
172 const RootPidStore *root_store)
173 : m_manufacturer_id(manufacturer_id),
174 m_root_store(root_store) {}
175
176 void Visit(const ola::messaging::UInt16MessageField *message) {
177 m_pids.insert(message->Value());
178 }
179
180 protected:
181 void PostStringHook() {
182 std::set<uint16_t>::const_iterator iter = m_pids.begin();
183 for (; iter != m_pids.end(); ++iter) {
184 Stream() << " " << ola::strings::ToHex(*iter);
185 const PidDescriptor *descriptor = m_root_store->GetDescriptor(
186 *iter, m_manufacturer_id);
187 if (descriptor) {
188 std::string name = descriptor->Name();
189 ola::ToLower(&name);
190 Stream() << " (" << name << ")";
191 }
192 Stream() << std::endl;
193 }
194 }
195
196 private:
197 std::set<uint16_t> m_pids;
198 uint16_t m_manufacturer_id;
199 const RootPidStore *m_root_store;
200};
201
202
207 public:
208 void Visit(const ola::messaging::UInt16MessageField *message) {
209 const std::string name = message->GetDescriptor()->Name();
210 if (name == "product_category") {
211 Stream() << TransformLabel(name) << ": "
212 << ProductCategoryToString(message->Value()) << std::endl;
213 } else {
214 ola::messaging::GenericMessagePrinter::Visit(message);
215 }
216 }
217
218 protected:
219 std::string TransformLabel(const std::string &label) {
220 std::string new_label = label;
221 ola::CustomCapitalizeLabel(&new_label);
222 return new_label;
223 }
224};
225
226
231 public:
232 void Visit(const ola::messaging::StringMessageField *message) {
233 Stream() << EncodeString(message->Value()) << std::endl;
234 }
235};
236
237
242 public:
243 void Visit(const ola::messaging::UInt16MessageField *message) {
244 m_product_ids.insert(message->Value());
245 }
246
247 void PostStringHook() {
248 std::set<uint16_t>::const_iterator iter = m_product_ids.begin();
249 for (; iter != m_product_ids.end(); ++iter) {
250 Stream() << ProductDetailToString(*iter) << std::endl;
251 }
252 }
253
254 private:
255 std::set<uint16_t> m_product_ids;
256};
257
258
263 public:
264 void Visit(const ola::messaging::StringMessageField *message) {
265 m_languages.insert(message->Value());
266 }
267
268 void PostStringHook() {
269 std::set<std::string>::const_iterator iter = m_languages.begin();
270 for (; iter != m_languages.end(); ++iter) {
271 Stream() << EncodeString(*iter) << std::endl;
272 }
273 }
274 private:
275 std::set<std::string> m_languages;
276};
277
278
283 public:
286 m_year(0),
287 m_offset(0) {}
288 void Visit(const ola::messaging::UInt16MessageField *message) {
289 m_year = message->Value();
290 }
291
292 void Visit(const ola::messaging::UInt8MessageField *message) {
293 if (m_offset < CLOCK_FIELDS) {
294 m_fields[m_offset] = message->Value();
295 }
296 m_offset++;
297 }
298
299 void PostStringHook() {
300 if (m_offset != CLOCK_FIELDS) {
301 Stream() << "Malformed packet";
302 }
303 Stream() << std::setfill('0') << std::setw(2)
304 << static_cast<int>(m_fields[1]) << "/"
305 << static_cast<int>(m_fields[0]) << "/"
306 << m_year << " "
307 << static_cast<int>(m_fields[2]) << ":"
308 << static_cast<int>(m_fields[3]) << ":"
309 << static_cast<int>(m_fields[4]) << std::endl;
310 }
311
312 private:
313 enum { CLOCK_FIELDS = 5};
314 uint16_t m_year;
315 uint8_t m_fields[CLOCK_FIELDS];
316 unsigned int m_offset;
317};
318
323 public:
324 void Visit(const ola::messaging::UInt8MessageField *field) {
325 if (m_slot_info.empty()) {
326 return;
327 }
328 m_slot_info.back().type = field->Value();
329 m_slot_info.back().type_defined = true;
330 }
331
332 void Visit(const ola::messaging::UInt16MessageField *field) {
333 if (m_slot_info.empty()) {
334 return;
335 }
336 if (!m_slot_info.back().offset_defined) {
337 m_slot_info.back().offset = field->Value();
338 m_slot_info.back().offset_defined = true;
339 } else {
340 m_slot_info.back().label = field->Value();
341 m_slot_info.back().label_defined = true;
342 }
343 }
344
345 void Visit(const ola::messaging::GroupMessageField*) {
346 slot_info slot;
347 m_slot_info.push_back(slot);
348 }
349
350 protected:
351 void PostStringHook() {
352 std::vector<slot_info>::const_iterator iter = m_slot_info.begin();
353 for (; iter != m_slot_info.end(); ++iter) {
354 if (!iter->offset_defined ||
355 !iter->type_defined ||
356 !iter->label_defined) {
357 OLA_WARN << "Invalid slot info";
358 continue;
359 }
360
361 const std::string slot = SlotInfoToString(iter->type, iter->label);
362
363 if (slot.empty()) {
364 Stream() << " offset: " << iter->offset << ", type: " << iter->type
365 << ", label: " << iter->label << std::endl;
366 } else {
367 Stream() << "Slot offset " << iter->offset << ": " << slot << std::endl;
368 }
369 }
370 }
371
372 private:
373 struct slot_info {
374 public:
375 uint16_t offset;
376 bool offset_defined;
377 uint8_t type;
378 bool type_defined;
379 uint16_t label;
380 bool label_defined;
381
382 slot_info() : offset(0), offset_defined(false), type(0),
383 type_defined(false), label(0), label_defined(false) {}
384 };
385 std::vector<slot_info> m_slot_info;
386};
387
388
393 public:
394 void Visit(const ola::messaging::UInt8MessageField *message) {
395 const std::string name = message->GetDescriptor()->Name();
396 if (name == "type") {
397 Stream() << TransformLabel(name) << ": "
398 << SensorTypeToString(message->Value()) << std::endl;
399 } else if (name == "unit") {
400 Stream() << TransformLabel(name) << ": ";
401 if (message->Value() == UNITS_NONE) {
402 Stream() << "None";
403 } else {
404 Stream() << UnitToString(message->Value());
405 }
406 Stream() << std::endl;
407 } else if (name == "prefix") {
408 Stream() << TransformLabel(name) << ": ";
409 if (message->Value() == PREFIX_NONE) {
410 Stream() << "None";
411 } else {
412 Stream() << PrefixToString(message->Value());
413 }
414 Stream() << std::endl;
415 } else if (name == "supports_recording") {
416 Stream() << TransformLabel(name) << ": ";
417 std::string supports_recording =
418 SensorSupportsRecordingToString(message->Value());
419 if (supports_recording.empty()) {
420 Stream() << "None";
421 } else {
422 Stream() << supports_recording;
423 }
424 Stream() << std::endl;
425 } else {
426 ola::messaging::GenericMessagePrinter::Visit(message);
427 }
428 }
429
430 protected:
431 std::string TransformLabel(const std::string &label) {
432 std::string new_label = label;
433 ola::CustomCapitalizeLabel(&new_label);
434 return new_label;
435 }
436};
437} // namespace rdm
438} // namespace ola
439#endif // INCLUDE_OLA_RDM_RDMMESSAGEPRINTERS_H_
Formatting functions for basic types.
Header file for OLA Logging.
Holds information about RDM PIDs.
Various misc RDM functions.
Various string utility functions.
A RDM unique identifier (UID).
Definition MessageVisitor.h:38
Definition MessagePrinter.h:70
Definition Message.h:242
Definition MessagePrinter.h:35
Definition Message.h:183
Definition Message.h:157
Definition RDMMessagePrinters.h:282
Definition RDMMessagePrinters.h:206
Definition RDMMessagePrinters.h:230
Definition RDMMessagePrinters.h:262
Definition PidStore.h:248
Definition RDMMessagePrinters.h:241
Definition RDMMessagePrinters.h:70
Definition RDMMessagePrinters.h:51
The root of the RDM parameter descriptor store.
Definition PidStore.h:68
const PidDescriptor * GetDescriptor(const std::string &pid_name) const
Lookup a PLASA-defined parameter by name.
Definition PidStore.cpp:48
Definition RDMMessagePrinters.h:392
Definition RDMMessagePrinters.h:322
Definition RDMMessagePrinters.h:81
Definition RDMMessagePrinters.h:169
#define OLA_WARN
Definition Logging.h:73
string UnitToString(uint8_t unit)
Definition RDMHelper.cpp:1083
string StatusMessageIdToString(uint16_t message_id, int16_t data1, int16_t data2)
Definition RDMHelper.cpp:910
string StatusTypeToString(uint8_t status_type)
Definition RDMHelper.cpp:1052
string ProductDetailToString(uint16_t detail)
Definition RDMHelper.cpp:464
string SensorSupportsRecordingToString(uint8_t supports_recording)
Definition RDMHelper.cpp:756
string ProductCategoryToString(uint16_t category)
Definition RDMHelper.cpp:328
string SensorTypeToString(uint8_t type)
Definition RDMHelper.cpp:673
string SlotInfoToString(uint8_t slot_type, uint16_t slot_label)
Definition RDMHelper.cpp:773
string PrefixToString(uint8_t prefix)
Definition RDMHelper.cpp:271
The namespace containing all OLA symbols.
Definition Credentials.cpp:44
string EncodeString(const string &original)
Encode any unprintable characters in a string as hex, returning a copy.
Definition StringUtils.cpp:302
void ToLower(string *s)
Convert a string to lower case.
Definition StringUtils.cpp:404
void CustomCapitalizeLabel(string *s)
Similar to CapitalizeLabel() but this also capitalized known acronyms.
Definition StringUtils.cpp:437