Open Lighting Architecture  0.9.4
 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()
278  m_year(0),
279  m_offset(0) {}
280  void Visit(const ola::messaging::UInt16MessageField *message) {
281  m_year = message->Value();
282  }
283 
284  void Visit(const ola::messaging::UInt8MessageField *message) {
285  if (m_offset < CLOCK_FIELDS)
286  m_fields[m_offset] = message->Value();
287  m_offset++;
288  }
289 
290  void PostStringHook() {
291  if (m_offset != CLOCK_FIELDS) {
292  Stream() << "Malformed packet";
293  }
294  Stream() << std::setfill('0') << std::setw(2) <<
295  static_cast<int>(m_fields[1]) << "/" <<
296  static_cast<int>(m_fields[0]) << "/" <<
297  m_year << " " <<
298  static_cast<int>(m_fields[2]) << ":" <<
299  static_cast<int>(m_fields[3]) << ":" <<
300  static_cast<int>(m_fields[4]) << std::endl;
301  }
302 
303  private:
304  enum { CLOCK_FIELDS = 5};
305  uint16_t m_year;
306  uint8_t m_fields[CLOCK_FIELDS];
307  unsigned int m_offset;
308 };
309 
314  public:
315  void Visit(const ola::messaging::UInt8MessageField *field) {
316  if (m_slot_info.empty())
317  return;
318  m_slot_info.back().type = field->Value();
319  m_slot_info.back().type_defined = true;
320  }
321 
322  void Visit(const ola::messaging::UInt16MessageField *field) {
323  if (m_slot_info.empty())
324  return;
325  if (!m_slot_info.back().offset_defined) {
326  m_slot_info.back().offset = field->Value();
327  m_slot_info.back().offset_defined = true;
328  } else {
329  m_slot_info.back().label = field->Value();
330  m_slot_info.back().label_defined = true;
331  }
332  }
333 
334  void Visit(const ola::messaging::GroupMessageField*) {
335  slot_info slot;
336  m_slot_info.push_back(slot);
337  }
338 
339  protected:
340  void PostStringHook() {
341  std::vector<slot_info>::const_iterator iter = m_slot_info.begin();
342  for (; iter != m_slot_info.end(); ++iter) {
343  if (!iter->offset_defined ||
344  !iter->type_defined ||
345  !iter->label_defined) {
346  OLA_WARN << "Invalid slot info";
347  continue;
348  }
349 
350  const std::string slot = SlotInfoToString(iter->type, iter->label);
351 
352  if (slot.empty()) {
353  Stream() << " offset: " <<
354  iter->offset << ", type: " << iter->type <<
355  ", label: " << iter->label << std::endl;
356  } else {
357  Stream() << "Slot offset " << iter->offset << ": " << slot << std::endl;
358  }
359  }
360  }
361 
362  private:
363  struct slot_info {
364  public:
365  uint16_t offset;
366  bool offset_defined;
367  uint8_t type;
368  bool type_defined;
369  uint16_t label;
370  bool label_defined;
371 
372  slot_info() : offset(0), offset_defined(false), type(0),
373  type_defined(false), label(0), label_defined(false) {}
374  };
375  std::vector<slot_info> m_slot_info;
376 };
377 
378 
383  public:
384  void Visit(const ola::messaging::UInt8MessageField *message) {
385  const std::string name = message->GetDescriptor()->Name();
386  if (name == "type") {
387  Stream() << TransformLabel(name) << ": " <<
388  SensorTypeToString(message->Value()) << std::endl;
389  } else if (name == "unit") {
390  Stream() << TransformLabel(name) << ": ";
391  if (message->Value() == UNITS_NONE) {
392  Stream() << "None";
393  } else {
394  Stream() << UnitToString(message->Value());
395  }
396  Stream() << std::endl;
397  } else if (name == "prefix") {
398  Stream() << TransformLabel(name) << ": ";
399  if (message->Value() == PREFIX_NONE) {
400  Stream() << "None";
401  } else {
402  Stream() << PrefixToString(message->Value());
403  }
404  Stream() << std::endl;
405  } else if (name == "supports_recording") {
406  Stream() << TransformLabel(name) << ": ";
407  std::string supports_recording =
408  SensorSupportsRecordingToString(message->Value());
409  if (supports_recording.empty()) {
410  Stream() << "None";
411  } else {
412  Stream() << supports_recording;
413  }
414  Stream() << std::endl;
415  } else {
416  ola::messaging::GenericMessagePrinter::Visit(message);
417  }
418  }
419 
420  protected:
421  std::string TransformLabel(const std::string &label) {
422  std::string new_label = label;
423  ola::CustomCapitalizeLabel(&new_label);
424  return new_label;
425  }
426 };
427 } // namespace rdm
428 } // namespace ola
429 #endif // INCLUDE_OLA_RDM_RDMMESSAGEPRINTERS_H_