battery_monitor_treeview.cpp
00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #include "battery_monitor_treeview.h"
00025
00026 #include <blackboard/remote.h>
00027 #include <gui_utils/interface_dispatcher.h>
00028 #include <gui_utils/utils.h>
00029 #include <interfaces/BatteryInterface.h>
00030
00031 #include <cstring>
00032
00033 using namespace std;
00034 using namespace fawkes;
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071 BatteryMonitorTreeView::BatteryMonitorTreeView( BaseObjectType* cobject,
00072 const Glib::RefPtr< Gnome::Glade::Xml >& ref_xml )
00073 : Gtk::TreeView( cobject )
00074 {
00075 m_battery_list = Gtk::ListStore::create( m_battery_record );
00076 set_model( m_battery_list );
00077
00078 append_column( "Host", m_battery_record.short_name );
00079 append_column_numeric( "Abs. SOC [%]", m_battery_record.absolute_soc, "%.1f" );
00080 append_column_numeric( "Rel. SOC [%]", m_battery_record.relative_soc, "%.1f" );
00081 append_column_numeric( "Voltage [V]", m_battery_record.voltage, "%.3f" );
00082 append_column_numeric( "Current [A]", m_battery_record.current, "%.3f" );
00083
00084 m_dlg_warning = dynamic_cast< Gtk::MessageDialog* >( get_widget( ref_xml, "dlgWarning" ) );
00085 m_dlg_warning->hide();
00086
00087 m_trigger_update.connect( sigc::mem_fun( *this, &BatteryMonitorTreeView::update ) );
00088
00089 m_relative_soc_threshold = 20.0;
00090 }
00091
00092
00093 BatteryMonitorTreeView::~BatteryMonitorTreeView()
00094 {
00095 for ( std::map< string, BatteryInterface* >::iterator biit = m_battery_interfaces.begin();
00096 biit != m_battery_interfaces.end();
00097 ++biit )
00098 {
00099 std::map< string, BlackBoard* >::iterator rbit;
00100 rbit = m_remote_bbs.find( biit->first );
00101
00102 std::map< string, InterfaceDispatcher* >::iterator idit;
00103 idit = m_interface_dispatcher.find( biit->first );
00104
00105 if ( rbit != m_remote_bbs.end() )
00106 {
00107 rbit->second->unregister_listener( idit->second );
00108 rbit->second->close( biit->second );
00109 delete rbit->second;
00110 }
00111 }
00112
00113
00114 for ( std::map< string, InterfaceDispatcher* >::iterator i = m_interface_dispatcher.begin();
00115 i != m_interface_dispatcher.end();
00116 ++i )
00117 {
00118 delete i->second;
00119 }
00120
00121
00122 for ( std::map< string, BlackBoard* >::iterator i = m_remote_bbs.begin();
00123 i != m_remote_bbs.end();
00124 ++i )
00125 {
00126 delete i->second;
00127 }
00128
00129 delete m_dlg_warning;
00130 }
00131
00132
00133
00134
00135 void
00136 BatteryMonitorTreeView::add_host( const char* h )
00137 {
00138 string host(h);
00139
00140 BlackBoard* rbb;
00141 std::map< string, BlackBoard* >::iterator i = m_remote_bbs.find( host );
00142
00143 if ( i == m_remote_bbs.end() )
00144
00145 {
00146 try
00147 {
00148 rbb = new RemoteBlackBoard( h, 1910 );
00149 m_remote_bbs[ host ] = rbb;
00150 }
00151 catch ( Exception& e )
00152 {
00153 e.append( "Could not open remote blackboard on host %s", h );
00154 e.print_trace();
00155 return;
00156 }
00157 }
00158 else
00159 { rbb = i->second; }
00160
00161 if ( m_battery_interfaces.find( host ) == m_battery_interfaces.end() )
00162
00163 {
00164 try
00165 {
00166 BatteryInterface* bi;
00167 bi = rbb->open_for_reading< BatteryInterface >( "Battery" );
00168 m_battery_interfaces[ host ] = bi;
00169
00170 InterfaceDispatcher* id = new InterfaceDispatcher( "BatteryMonitorTreeView", bi );
00171
00172 id->signal_data_changed().connect( sigc::mem_fun( *this,
00173 &BatteryMonitorTreeView::on_data_changed ) );
00174 id->signal_writer_added().connect( sigc::mem_fun( *this,
00175 &BatteryMonitorTreeView::on_writer_added ) );
00176 id->signal_writer_removed().connect( sigc::mem_fun( *this,
00177 &BatteryMonitorTreeView::on_writer_removed ) );
00178 rbb->register_listener( id, BlackBoard::BBIL_FLAG_DATA || BlackBoard::BBIL_FLAG_WRITER );
00179 }
00180 catch ( Exception& e )
00181 {
00182 e.append( "Opening battery interface on host %s failed", h );
00183 e.print_trace();
00184 }
00185
00186
00187 m_below_threshold_counter[ host ] = 0;
00188 }
00189
00190 m_trigger_update();
00191 }
00192
00193
00194
00195
00196 void
00197 BatteryMonitorTreeView::rem_host( const char* h )
00198 {
00199 string host( h );
00200
00201 std::map< string, BlackBoard* >::iterator rbbit = m_remote_bbs.find( host );
00202 if ( m_remote_bbs.end() == rbbit )
00203
00204 { return; }
00205
00206 std::map< string, BatteryInterface* >::iterator biit = m_battery_interfaces.find( host );
00207
00208 if ( m_battery_interfaces.end() != biit )
00209
00210
00211 {
00212 try
00213 {
00214 BlackBoard* rbb = rbbit->second;
00215 InterfaceDispatcher* id = m_interface_dispatcher.find( host )->second;
00216 rbb->unregister_listener( id );
00217 rbb->close( biit->second );
00218 m_battery_interfaces.erase( biit );
00219 }
00220 catch ( Exception& e )
00221 {
00222 e.append( "Closing battery interface for host %s could not be closed", h );
00223 e.print_trace();
00224 }
00225 }
00226
00227
00228 delete rbbit->second;
00229 m_remote_bbs.erase( rbbit );
00230
00231
00232 m_below_threshold_counter.erase( host );
00233
00234 m_trigger_update();
00235 }
00236
00237 void
00238 BatteryMonitorTreeView::update()
00239 {
00240
00241 Gtk::TreeModel::Children::iterator rit = m_battery_list->children().begin();
00242 while ( rit != m_battery_list->children().end() )
00243 {
00244 rit = m_battery_list->erase( rit );
00245 }
00246
00247 for ( std::map< string, BatteryInterface* >::iterator biit = m_battery_interfaces.begin();
00248 biit != m_battery_interfaces.end();
00249 ++biit )
00250 {
00251
00252 BatteryInterface* bi = biit->second;
00253
00254 try
00255 {
00256 bi->read();
00257 }
00258 catch ( Exception& e )
00259 {
00260 e.append( "read() failed" );
00261 e.print_trace();
00262 continue;
00263 }
00264
00265 if ( !bi->has_writer() )
00266
00267 { continue; }
00268
00269 Gtk::TreeModel::Row row;
00270 row = *m_battery_list->append();
00271 row[ m_battery_record.fqdn ] = Glib::ustring( biit->first );
00272
00273 char* fqdn = strdup( (biit->first).c_str() );
00274 char* sh;
00275 char delim = '.';
00276 sh = strtok( fqdn, &delim );
00277 int i = atoi( sh );
00278
00279 if ( 0 != i )
00280 { row[ m_battery_record.short_name ] = Glib::ustring( biit->first ); }
00281 else
00282 { row[ m_battery_record.short_name ] = Glib::ustring( sh ); }
00283
00284 row[ m_battery_record.absolute_soc ] = bi->absolute_soc() * 100.0;
00285 row[ m_battery_record.relative_soc ] = bi->relative_soc() * 100.0;
00286 row[ m_battery_record.current ] = bi->current() / 1000.0;
00287 row[ m_battery_record.voltage ] = bi->voltage() / 1000.0;
00288
00289 string fqdn_str = string( fqdn );
00290 if ( row[ m_battery_record.relative_soc ] <= m_relative_soc_threshold )
00291 {
00292 unsigned int cnt = m_below_threshold_counter[ fqdn_str ];
00293 m_below_threshold_counter[ fqdn_str ] = ++cnt;
00294 }
00295 else
00296 { m_below_threshold_counter[ fqdn_str ] = 0; }
00297
00298 free(fqdn);
00299 }
00300
00301 Glib::ustring secondary = "The batteries on ";
00302 bool below_threshold = false;
00303
00304 for ( std::map< string, unsigned int >::iterator i = m_below_threshold_counter.begin();
00305 i != m_below_threshold_counter.end();
00306 ++i )
00307 {
00308 if ( i->second > 2 )
00309 {
00310 secondary += "<b>" + Glib::ustring( (i->first).c_str() ) + "</b>" + " ";
00311 i->second = 0;
00312
00313 below_threshold = true;
00314 }
00315 }
00316 secondary += "need to be replaced.";
00317
00318 if ( below_threshold )
00319 {
00320 m_dlg_warning->set_secondary_text( secondary, true );
00321 m_dlg_warning->set_urgency_hint();
00322 m_dlg_warning->run();
00323 m_dlg_warning->hide();
00324 }
00325 }
00326
00327 void
00328 BatteryMonitorTreeView::on_data_changed( fawkes::Interface* interface )
00329 {
00330 update();
00331 }
00332
00333 void
00334 BatteryMonitorTreeView::on_writer_added( fawkes::Interface* interface )
00335 {
00336 update();
00337 }
00338
00339 void
00340 BatteryMonitorTreeView::on_writer_removed( fawkes::Interface* interface )
00341 {
00342 update();
00343 }