Fawkes API  Fawkes Development Version
battery_monitor_treeview.cpp
1 
2 /***************************************************************************
3  * battery_monitor_treeview.cpp - TreeView class for displaying the battery
4  * status of the robots
5  *
6  * Created: Mon Apr 06 16:08:50 2009
7  * Copyright 2009 Daniel Beck
8  *
9  ****************************************************************************/
10 
11 /* This program is free software; you can redistribute it and/or modify
12  * it under the terms of the GNU General Public License as published by
13  * the Free Software Foundation; either version 2 of the License, or
14  * (at your option) any later version.
15  *
16  * This program is distributed in the hope that it will be useful,
17  * but WITHOUT ANY WARRANTY; without even the implied warranty of
18  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19  * GNU Library General Public License for more details.
20  *
21  * Read the full text in the LICENSE.GPL file in the doc directory.
22  */
23 
24 #include "battery_monitor_treeview.h"
25 
26 #include <blackboard/remote.h>
27 #include <gui_utils/interface_dispatcher.h>
28 #include <interfaces/BatteryInterface.h>
29 
30 #include <cstring>
31 
32 using namespace std;
33 using namespace fawkes;
34 
35 /** @class BatteryMonitorTreeView tools/battery_monitor/battery_monitor_treeview.h
36  * A treeview that retrieves battery data from the robots over remote
37  * blackboard connections and displays those.
38  * @author Daniel Beck
39  */
40 
41 /** @class BatteryMonitorTreeView::BatteryRecord tools/battery_monitor/battery_monitor_treeview.h
42  * Column record class for the battery monitor treeview.
43  * @author Daniel Beck
44  */
45 
46 /** @var BatteryMonitorTreeView::m_battery_record
47  * Column record object to acces the columns of the storage object.
48  */
49 
50 /** @var BatteryMonitorTreeView::m_battery_list
51  * Storage object.
52  */
53 
54 /** @var BatteryMonitorTreeView::m_remote_bbs
55  * Map with remote blackboards: hostname -> remote blackboard.
56  */
57 
58 /** @var BatteryMonitorTreeView::m_battery_interfaces
59  * Map containing the battery interfaces: hostname -> battery interface
60  */
61 
62 /** @var BatteryMonitorTreeView::m_interface_dispatcher
63  * Interface dispatcher for the battery interfaces.
64  */
65 
66 /** Constructor.
67  * @param cobject base object type
68  * @param builder builder to get widgets from
69  */
71  const Glib::RefPtr<Gtk::Builder> &builder)
72 : Gtk::TreeView(cobject)
73 {
74  m_battery_list = Gtk::ListStore::create(m_battery_record);
75  set_model(m_battery_list);
76 
77  append_column("Host", m_battery_record.short_name);
78  append_column_numeric("Abs. SOC [%]", m_battery_record.absolute_soc, "%.1f");
79  append_column_numeric("Rel. SOC [%]", m_battery_record.relative_soc, "%.1f");
80  append_column_numeric("Voltage [V]", m_battery_record.voltage, "%.3f");
81  append_column_numeric("Current [A]", m_battery_record.current, "%.3f");
82 
83  builder->get_widget("dlgWarning", m_dlg_warning);
84  m_dlg_warning->hide();
85 
86  m_trigger_update.connect(sigc::mem_fun(*this, &BatteryMonitorTreeView::update));
87 
88  m_relative_soc_threshold = 20.0;
89 }
90 
91 /** Destructor. */
93 {
94  std::map<string, BatteryInterface *>::iterator biit;
95  for (biit = m_battery_interfaces.begin(); biit != m_battery_interfaces.end(); ++biit) {
96  std::map<string, BlackBoard *>::iterator rbit;
97  rbit = m_remote_bbs.find(biit->first);
98 
99  std::map<string, InterfaceDispatcher *>::iterator idit;
100  idit = m_interface_dispatcher.find(biit->first);
101 
102  if (rbit != m_remote_bbs.end()) {
103  rbit->second->unregister_listener(idit->second);
104  rbit->second->close(biit->second);
105  delete rbit->second;
106  }
107  }
108 
109  // delete interface dispatcher
110  std::map<string, InterfaceDispatcher *>::iterator i;
111  for (i = m_interface_dispatcher.begin(); i != m_interface_dispatcher.end(); ++i) {
112  delete i->second;
113  }
114 
115  // delete remote blackboards
116  for (std::map<string, BlackBoard *>::iterator i = m_remote_bbs.begin(); i != m_remote_bbs.end();
117  ++i) {
118  delete i->second;
119  }
120 
121  delete m_dlg_warning;
122 }
123 
124 /** Add given host.
125  * @param h the host's hostname
126  */
127 void
129 {
130  string host(h);
131 
132  BlackBoard * rbb;
133  std::map<string, BlackBoard *>::iterator i = m_remote_bbs.find(host);
134 
135  if (i == m_remote_bbs.end())
136  // no remote blackboard opened, yet
137  {
138  try {
139  rbb = new RemoteBlackBoard(h, 1910);
140  m_remote_bbs[host] = rbb;
141  } catch (Exception &e) {
142  e.append("Could not open remote blackboard on host %s", h);
143  e.print_trace();
144  return;
145  }
146  } else {
147  rbb = i->second;
148  }
149 
150  if (m_battery_interfaces.find(host) == m_battery_interfaces.end())
151  // no battery interface opened, yet
152  {
153  try {
154  BatteryInterface *bi;
155  bi = rbb->open_for_reading<BatteryInterface>("Battery");
156  m_battery_interfaces[host] = bi;
157 
158  InterfaceDispatcher *id = new InterfaceDispatcher("BatteryMonitorTreeView", bi);
159 
160  id->signal_data_changed().connect(
161  sigc::mem_fun(*this, &BatteryMonitorTreeView::on_data_changed));
162  id->signal_writer_added().connect(
163  sigc::mem_fun(*this, &BatteryMonitorTreeView::on_writer_added));
164  id->signal_writer_removed().connect(
165  sigc::mem_fun(*this, &BatteryMonitorTreeView::on_writer_removed));
166  rbb->register_listener(id, BlackBoard::BBIL_FLAG_DATA | BlackBoard::BBIL_FLAG_WRITER);
167  } catch (Exception &e) {
168  e.append("Opening battery interface on host %s failed", h);
169  e.print_trace();
170  }
171 
172  // add below threshold counter
173  m_below_threshold_counter[host] = 0;
174  }
175 
176  m_trigger_update();
177 }
178 
179 /** Remove given host.
180  * @param h the host's hostname
181  */
182 void
184 {
185  string host(h);
186 
187  std::map<string, BlackBoard *>::iterator rbbit = m_remote_bbs.find(host);
188  if (m_remote_bbs.end() == rbbit)
189  // no blackboard opened---nothing to do
190  {
191  return;
192  }
193 
194  std::map<string, BatteryInterface *>::iterator biit = m_battery_interfaces.find(host);
195 
196  if (m_battery_interfaces.end() != biit)
197  // battery inteface opened. listener need to be unregistered and
198  // interface nees to be closed
199  {
200  try {
201  BlackBoard * rbb = rbbit->second;
202  InterfaceDispatcher *id = m_interface_dispatcher.find(host)->second;
203  rbb->unregister_listener(id);
204  rbb->close(biit->second);
205  m_battery_interfaces.erase(biit);
206  } catch (Exception &e) {
207  e.append("Closing battery interface for host %s could not be closed", h);
208  e.print_trace();
209  }
210  }
211 
212  // destroy blackboard
213  delete rbbit->second;
214  m_remote_bbs.erase(rbbit);
215 
216  // remove below threshold counter
217  m_below_threshold_counter.erase(host);
218 
219  m_trigger_update();
220 }
221 
222 void
223 BatteryMonitorTreeView::update()
224 {
225  // clear treeview
226  Gtk::TreeModel::Children::iterator rit = m_battery_list->children().begin();
227  while (rit != m_battery_list->children().end()) {
228  rit = m_battery_list->erase(rit);
229  }
230 
231  for (std::map<string, BatteryInterface *>::iterator biit = m_battery_interfaces.begin();
232  biit != m_battery_interfaces.end();
233  ++biit) {
234  // update data in interface
235  BatteryInterface *bi = biit->second;
236 
237  try {
238  bi->read();
239  } catch (Exception &e) {
240  e.append("read() failed");
241  e.print_trace();
242  continue;
243  }
244 
245  if (!bi->has_writer())
246  // only consider interfaces which have a writer
247  {
248  continue;
249  }
250 
251  Gtk::TreeModel::Row row;
252  row = *m_battery_list->append();
253  row[m_battery_record.fqdn] = Glib::ustring(biit->first);
254 
255  char *fqdn = strdup((biit->first).c_str());
256  char *sh;
257  char delim = '.';
258  sh = strtok(fqdn, &delim);
259  int i = atoi(sh);
260 
261  if (0 != i) {
262  row[m_battery_record.short_name] = Glib::ustring(biit->first);
263  } else {
264  row[m_battery_record.short_name] = Glib::ustring(sh);
265  }
266 
267  row[m_battery_record.absolute_soc] = bi->absolute_soc() * 100.0;
268  row[m_battery_record.relative_soc] = bi->relative_soc() * 100.0;
269  row[m_battery_record.current] = bi->current() / 1000.0;
270  row[m_battery_record.voltage] = bi->voltage() / 1000.0;
271 
272  string fqdn_str = string(fqdn);
273  if (row[m_battery_record.relative_soc] <= m_relative_soc_threshold) {
274  unsigned int cnt = m_below_threshold_counter[fqdn_str];
275  m_below_threshold_counter[fqdn_str] = ++cnt;
276  } else {
277  m_below_threshold_counter[fqdn_str] = 0;
278  }
279 
280  free(fqdn);
281  }
282 
283  Glib::ustring secondary = "The batteries on ";
284  bool below_threshold = false;
285 
286  for (std::map<string, unsigned int>::iterator i = m_below_threshold_counter.begin();
287  i != m_below_threshold_counter.end();
288  ++i) {
289  if (i->second > 2) {
290  secondary += "<b>" + Glib::ustring((i->first).c_str()) + "</b>" + " ";
291  i->second = 0;
292 
293  below_threshold = true;
294  }
295  }
296  secondary += "need to be replaced.";
297 
298  if (below_threshold) {
299  m_dlg_warning->set_secondary_text(secondary, true);
300  m_dlg_warning->set_urgency_hint();
301  m_dlg_warning->run();
302  m_dlg_warning->hide();
303  }
304 }
305 
306 void
307 BatteryMonitorTreeView::on_data_changed(fawkes::Interface *interface)
308 {
309  update();
310 }
311 
312 void
313 BatteryMonitorTreeView::on_writer_added(fawkes::Interface *interface)
314 {
315  update();
316 }
317 
318 void
319 BatteryMonitorTreeView::on_writer_removed(fawkes::Interface *interface)
320 {
321  update();
322 }
BatteryMonitorTreeView::BatteryMonitorTreeView
BatteryMonitorTreeView(BaseObjectType *cobject, const Glib::RefPtr< Gtk::Builder > &builder)
Constructor.
Definition: battery_monitor_treeview.cpp:70
fawkes::BatteryInterface::absolute_soc
float absolute_soc() const
Get absolute_soc value.
Definition: BatteryInterface.cpp:174
fawkes::BlackBoard::register_listener
virtual void register_listener(BlackBoardInterfaceListener *listener, ListenerRegisterFlag flag=BBIL_FLAG_ALL)
Register BB event listener.
Definition: blackboard.cpp:190
BatteryMonitorTreeView::m_battery_record
BatteryRecord m_battery_record
Definition: battery_monitor_treeview.h:69
fawkes::Interface::read
void read()
Read from BlackBoard into local copy.
Definition: interface.cpp:477
BatteryMonitorTreeView::m_battery_interfaces
std::map< std::string, fawkes::BatteryInterface * > m_battery_interfaces
Definition: battery_monitor_treeview.h:73
fawkes::BatteryInterface::relative_soc
float relative_soc() const
Get relative_soc value.
Definition: BatteryInterface.cpp:205
fawkes::BlackBoard::unregister_listener
virtual void unregister_listener(BlackBoardInterfaceListener *listener)
Unregister BB interface listener.
Definition: blackboard.cpp:217
fawkes::BlackBoard
Definition: blackboard.h:50
BatteryMonitorTreeView::BatteryRecord::absolute_soc
Gtk::TreeModelColumn< float > absolute_soc
The battery's absolute state of charge.
Definition: battery_monitor_treeview.h:63
fawkes::RemoteBlackBoard
Definition: remote.h:53
BatteryMonitorTreeView::add_host
void add_host(const char *host)
Add given host.
Definition: battery_monitor_treeview.cpp:128
BatteryMonitorTreeView::~BatteryMonitorTreeView
virtual ~BatteryMonitorTreeView()
Destructor.
Definition: battery_monitor_treeview.cpp:92
fawkes::Exception::append
void append(const char *format,...)
Append messages to the message list.
Definition: exception.cpp:333
BatteryMonitorTreeView::BatteryRecord::current
Gtk::TreeModelColumn< float > current
The battery's current.
Definition: battery_monitor_treeview.h:65
BatteryMonitorTreeView::m_interface_dispatcher
std::map< std::string, fawkes::InterfaceDispatcher * > m_interface_dispatcher
Definition: battery_monitor_treeview.h:74
fawkes::BlackBoard::close
virtual void close(Interface *interface)=0
BatteryMonitorTreeView::m_battery_list
Glib::RefPtr< Gtk::ListStore > m_battery_list
Definition: battery_monitor_treeview.h:70
BatteryMonitorTreeView::m_remote_bbs
std::map< std::string, fawkes::BlackBoard * > m_remote_bbs
Definition: battery_monitor_treeview.h:72
fawkes
BatteryMonitorTreeView::rem_host
void rem_host(const char *host)
Remove given host.
Definition: battery_monitor_treeview.cpp:183
fawkes::BatteryInterface::current
uint32_t current() const
Get current value.
Definition: BatteryInterface.cpp:81
fawkes::BatteryInterface
Definition: BatteryInterface.h:39
fawkes::Interface
Definition: interface.h:78
fawkes::Interface::has_writer
bool has_writer() const
Check if there is a writer for the interface.
Definition: interface.cpp:819
fawkes::Exception::print_trace
void print_trace()
Prints trace to stderr.
Definition: exception.cpp:601
fawkes::InterfaceDispatcher
Definition: interface_dispatcher.h:42
BatteryMonitorTreeView::BatteryRecord::voltage
Gtk::TreeModelColumn< float > voltage
The battery's voltage.
Definition: battery_monitor_treeview.h:66
fawkes::BatteryInterface::voltage
uint32_t voltage() const
Get voltage value.
Definition: BatteryInterface.cpp:112
fawkes::BlackBoard::open_for_reading
virtual Interface * open_for_reading(const char *interface_type, const char *identifier, const char *owner=NULL)=0
BatteryMonitorTreeView::BatteryRecord::relative_soc
Gtk::TreeModelColumn< float > relative_soc
The battery's relative state of charge.
Definition: battery_monitor_treeview.h:64
BatteryMonitorTreeView::BatteryRecord::short_name
Gtk::TreeModelColumn< Glib::ustring > short_name
A shorter hostname (w/o domain)
Definition: battery_monitor_treeview.h:62
BatteryMonitorTreeView::BatteryRecord::fqdn
Gtk::TreeModelColumn< Glib::ustring > fqdn
The FQDN.
Definition: battery_monitor_treeview.h:61
fawkes::Exception
Definition: exception.h:41