Open Lighting Architecture  0.9.1
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
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  *
17  * A command line based RDM controller
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 <iomanip>
39 #include <set>
40 #include <string>
41 #include <vector>
42 
43 
44 namespace ola {
45 namespace rdm {
46 
51  public:
52  explicit RDMMessagePrinter(unsigned int initial_ident = 0)
54  ola::messaging::GenericMessagePrinter::DEFAULT_INDENT,
55  initial_ident) {
56  }
57  protected:
58  std::string TransformLabel(const std::string &label) {
59  std::string new_label = label;
60  ola::CustomCapitalizeLabel(&new_label);
61  return new_label;
62  }
63 };
64 
65 
70  public:
71  void Visit(const ola::messaging::UIDMessageField *field) {
72  Stream() << field->Value() << std::endl;
73  }
74 };
75 
76 
81  public:
82  void Visit(const ola::messaging::UInt8MessageField *field) {
83  if (m_messages.empty())
84  return;
85  m_messages.back().status_type = field->Value();
86  m_messages.back().status_type_defined = true;
87  }
88 
89  void Visit(const ola::messaging::Int16MessageField *field) {
90  if (m_messages.empty())
91  return;
92  status_message &message = m_messages.back();
93  if (message.int_offset < MAX_INT_FIELDS)
94  message.int16_fields[message.int_offset++] = field->Value();
95  }
96 
97  void Visit(const ola::messaging::UInt16MessageField *field) {
98  if (m_messages.empty())
99  return;
100  status_message &message = m_messages.back();
101  if (message.uint_offset < MAX_UINT_FIELDS)
102  message.uint16_fields[message.uint_offset++] = field->Value();
103  }
104 
105  void Visit(const ola::messaging::GroupMessageField*) {
106  status_message message;
107  m_messages.push_back(message);
108  }
109 
110  protected:
111  void PostStringHook() {
112  std::vector<status_message>::const_iterator iter = m_messages.begin();
113  for (; iter != m_messages.end(); ++iter) {
114  if (!iter->status_type_defined ||
115  iter->uint_offset != MAX_UINT_FIELDS ||
116  iter->int_offset != MAX_INT_FIELDS) {
117  OLA_WARN << "Invalid status message";
118  continue;
119  }
120 
121  const std::string message = StatusMessageIdToString(
122  iter->uint16_fields[1],
123  iter->int16_fields[0],
124  iter->int16_fields[1]);
125 
126  Stream() << StatusTypeToString(iter->status_type) << ": ";
127  if (iter->uint16_fields[0])
128  Stream() << "Sub-device " << iter->uint16_fields[0] << ": ";
129 
130  if (message.empty()) {
131  Stream() << " message-id: " <<
132  iter->uint16_fields[1] << ", data1: " << iter->int16_fields[0] <<
133  ", data2: " << iter->int16_fields[1] << std::endl;
134  } else {
135  Stream() << message << std::endl;
136  }
137  }
138  }
139 
140  private:
141  enum { MAX_INT_FIELDS = 2 };
142  enum { MAX_UINT_FIELDS = 2 };
143  struct status_message {
144  public:
145  uint16_t uint16_fields[MAX_UINT_FIELDS];
146  int16_t int16_fields[MAX_INT_FIELDS];
147  uint8_t uint_offset;
148  uint8_t int_offset;
149  uint8_t status_type;
150  bool status_type_defined;
151 
152  status_message() : uint_offset(0), int_offset(0), status_type(0),
153  status_type_defined(false) {}
154  };
155  std::vector<status_message> m_messages;
156 };
157 
158 
163  public:
164  SupportedParamsPrinter(uint16_t manufacturer_id,
165  const RootPidStore *root_store)
166  : m_manufacturer_id(manufacturer_id),
167  m_root_store(root_store) {}
168 
169  void Visit(const ola::messaging::UInt16MessageField *message) {
170  m_pids.insert(message->Value());
171  }
172 
173  protected:
174  void PostStringHook() {
175  std::set<uint16_t>::const_iterator iter = m_pids.begin();
176  for (; iter != m_pids.end(); ++iter) {
177  Stream() << " 0x" << std::hex << *iter;
178  const PidDescriptor *descriptor = m_root_store->GetDescriptor(
179  *iter, m_manufacturer_id);
180  if (descriptor) {
181  std::string name = descriptor->Name();
182  ola::ToLower(&name);
183  Stream() << " (" << name << ")";
184  }
185  Stream() << std::endl;
186  }
187  }
188 
189  private:
190  std::set<uint16_t> m_pids;
191  uint16_t m_manufacturer_id;
192  const RootPidStore *m_root_store;
193 };
194 
195 
200  public:
201  void Visit(const ola::messaging::UInt16MessageField *message) {
202  const std::string name = message->GetDescriptor()->Name();
203  if (name == "product_category")
204  Stream() << TransformLabel(name) << ": " <<
205  ProductCategoryToString(message->Value()) << std::endl;
206  else
207  ola::messaging::GenericMessagePrinter::Visit(message);
208  }
209 
210  protected:
211  std::string TransformLabel(const std::string &label) {
212  std::string new_label = label;
213  ola::CustomCapitalizeLabel(&new_label);
214  return new_label;
215  }
216 };
217 
218 
223  public:
224  void Visit(const ola::messaging::StringMessageField *message) {
225  Stream() << EncodeString(message->Value()) << std::endl;
226  }
227 };
228 
229 
234  public:
235  void Visit(const ola::messaging::UInt16MessageField *message) {
236  m_product_ids.insert(message->Value());
237  }
238 
239  void PostStringHook() {
240  std::set<uint16_t>::const_iterator iter = m_product_ids.begin();
241  for (; iter != m_product_ids.end(); ++iter) {
242  Stream() << ProductDetailToString(*iter) << std::endl;
243  }
244  }
245 
246  private:
247  std::set<uint16_t> m_product_ids;
248 };
249 
250 
255  public:
256  void Visit(const ola::messaging::StringMessageField *message) {
257  m_languages.insert(message->Value());
258  }
259 
260  void PostStringHook() {
261  std::set<std::string>::const_iterator iter = m_languages.begin();
262  for (; iter != m_languages.end(); ++iter) {
263  Stream() << EncodeString(*iter) << std::endl;
264  }
265  }
266  private:
267  std::set<std::string> m_languages;
268 };
269 
270 
275  public:
276  ClockPrinter() : ola::messaging::MessagePrinter(), m_offset(0) {}
277  void Visit(const ola::messaging::UInt16MessageField *message) {
278  m_year = message->Value();
279  }
280 
281  void Visit(const ola::messaging::UInt8MessageField *message) {
282  if (m_offset < CLOCK_FIELDS)
283  m_fields[m_offset] = message->Value();
284  m_offset++;
285  }
286 
287  void PostStringHook() {
288  if (m_offset != CLOCK_FIELDS) {
289  Stream() << "Malformed packet";
290  }
291  Stream() << std::setfill('0') << std::setw(2) <<
292  static_cast<int>(m_fields[1]) << "/" <<
293  static_cast<int>(m_fields[0]) << "/" <<
294  m_year << " " <<
295  static_cast<int>(m_fields[2]) << ":" <<
296  static_cast<int>(m_fields[3]) << ":" <<
297  static_cast<int>(m_fields[4]) << std::endl;
298  }
299 
300  private:
301  enum { CLOCK_FIELDS = 5};
302  uint16_t m_year;
303  uint8_t m_fields[CLOCK_FIELDS];
304  unsigned int m_offset;
305 };
306 
311  public:
312  void Visit(const ola::messaging::UInt8MessageField *field) {
313  if (m_slot_info.empty())
314  return;
315  m_slot_info.back().type = field->Value();
316  m_slot_info.back().type_defined = true;
317  }
318 
319  void Visit(const ola::messaging::UInt16MessageField *field) {
320  if (m_slot_info.empty())
321  return;
322  if (!m_slot_info.back().offset_defined) {
323  m_slot_info.back().offset = field->Value();
324  m_slot_info.back().offset_defined = true;
325  } else {
326  m_slot_info.back().label = field->Value();
327  m_slot_info.back().label_defined = true;
328  }
329  }
330 
331  void Visit(const ola::messaging::GroupMessageField*) {
332  slot_info slot;
333  m_slot_info.push_back(slot);
334  }
335 
336  protected:
337  void PostStringHook() {
338  std::vector<slot_info>::const_iterator iter = m_slot_info.begin();
339  for (; iter != m_slot_info.end(); ++iter) {
340  if (!iter->offset_defined ||
341  !iter->type_defined ||
342  !iter->label_defined) {
343  OLA_WARN << "Invalid slot info";
344  continue;
345  }
346 
347  const std::string slot = SlotInfoToString(iter->type, iter->label);
348 
349  if (slot.empty()) {
350  Stream() << " offset: " <<
351  iter->offset << ", type: " << iter->type <<
352  ", label: " << iter->label << std::endl;
353  } else {
354  Stream() << "Slot offset " << iter->offset << ": " << slot << std::endl;
355  }
356  }
357  }
358 
359  private:
360  struct slot_info {
361  public:
362  uint16_t offset;
363  bool offset_defined;
364  uint8_t type;
365  bool type_defined;
366  uint16_t label;
367  bool label_defined;
368 
369  slot_info() : offset(0), offset_defined(false), type(0),
370  type_defined(false), label(0), label_defined(false) {}
371  };
372  std::vector<slot_info> m_slot_info;
373 };
374 
375 
380  public:
381  void Visit(const ola::messaging::UInt8MessageField *message) {
382  const std::string name = message->GetDescriptor()->Name();
383  if (name == "type") {
384  Stream() << TransformLabel(name) << ": " <<
385  SensorTypeToString(message->Value()) << std::endl;
386  } else if (name == "unit") {
387  Stream() << TransformLabel(name) << ": ";
388  if (message->Value() == UNITS_NONE) {
389  Stream() << "None";
390  } else {
391  Stream() << UnitToString(message->Value());
392  }
393  Stream() << std::endl;
394  } else if (name == "prefix") {
395  Stream() << TransformLabel(name) << ": ";
396  if (message->Value() == PREFIX_NONE) {
397  Stream() << "None";
398  } else {
399  Stream() << PrefixToString(message->Value());
400  }
401  Stream() << std::endl;
402  } else if (name == "supports_recording") {
403  Stream() << TransformLabel(name) << ": ";
404  std::string supports_recording =
405  SensorSupportsRecordingToString(message->Value());
406  if (supports_recording.empty()) {
407  Stream() << "None";
408  } else {
409  Stream() << supports_recording;
410  }
411  Stream() << std::endl;
412  } else {
413  ola::messaging::GenericMessagePrinter::Visit(message);
414  }
415  }
416 
417  protected:
418  std::string TransformLabel(const std::string &label) {
419  std::string new_label = label;
420  ola::CustomCapitalizeLabel(&new_label);
421  return new_label;
422  }
423 };
424 } // namespace rdm
425 } // namespace ola
426 #endif // INCLUDE_OLA_RDM_RDMMESSAGEPRINTERS_H_