Logo Search packages:      
Sourcecode: hardware-monitor version File versions  Download package

monitor-impls.cpp

/* The various system statistics - adapters of the libgtop interface.
 *
 * Copyright (c) 2003, 04, 05 Ole Laursen.
 *
 * This program is free software; you can redistribute it and/or 
 * modify it under the terms of the GNU General Public License as 
 * published by the Free Software Foundation; either version 2 of the
 * License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
 * USA.
 */

#include <string>
#include <iomanip>
#if __GNUC__ < 3
#include <iostream>
#else
#include <ostream>
#endif
#include <sys/time.h>         // for high-precision timing for the network load
#include <vector>
#include <algorithm>
#include <cstdio>
#include <cassert>
#include <cstdlib>

#include <glibtop.h>
#include <glibtop/cpu.h>
#include <glibtop/mem.h>
#include <glibtop/swap.h>
#include <glibtop/loadavg.h>
#include <glibtop/fsusage.h>
#include <glibtop/netload.h>


#include "monitor-impls.hpp"
#include "ucompose.hpp"
#include "i18n.hpp"


// decay factor for maximum values (log_0.999(0.9) = 105 iterations before
// reduced 10%)
double const max_decay = 0.999; 


//
// functions from monitor.hpp
//

std::list<Monitor *>
load_monitors(const Glib::RefPtr<Gnome::Conf::Client> &client,
            const Glib::ustring &dir)
{
  std::list<Monitor *> monitors;
  
  Glib::SListHandle<Glib::ustring> gconf_list
    = client->all_dirs(dir + "/monitors");

  for (Glib::SListHandle<Glib::ustring>::const_iterator i = gconf_list.begin(),
       end = gconf_list.end(); i != end; ++i) {
    const Glib::ustring &mon_dir = *i;
    
    Glib::ustring type = client->get_string(mon_dir + "/type");
    
    if (type == "cpu_usage") {
      Gnome::Conf::Value v = client->get(mon_dir + "/cpu_no");
      int cpu_no;
      
      if (v.get_type() == Gnome::Conf::VALUE_INT)
      cpu_no = v.get_int();
      else
      cpu_no = -1;

      if (cpu_no == -1)
      monitors.push_back(new CpuUsageMonitor);
      else
      monitors.push_back(new CpuUsageMonitor(cpu_no));
    }
    else if (type == "memory_usage")
      monitors.push_back(new MemoryUsageMonitor);
    else if (type == "swap_usage")
      monitors.push_back(new SwapUsageMonitor);
    else if (type == "load_average")
      monitors.push_back(new LoadAverageMonitor);
    else if (type == "disk_usage") {
      Gnome::Conf::Value v = client->get(mon_dir + "/mount_dir");
      Glib::ustring mount_dir;
      
      if (v.get_type() == Gnome::Conf::VALUE_STRING)
      mount_dir = v.get_string();
      else
      mount_dir = "/";  // FIXME: use schema?

      v = client->get(mon_dir + "/show_free");
      bool show_free;

      if (v.get_type() == Gnome::Conf::VALUE_BOOL)
      show_free = v.get_bool();
      else
      show_free = false;      // FIXME: use schema?
      
      monitors.push_back(new DiskUsageMonitor(mount_dir, show_free));
    }
    else if (type == "network_load") {
      Glib::ustring inter;
      int inter_no, inter_direction;
      
      Gnome::Conf::Value v = client->get(mon_dir + "/interface");
      
      if (v.get_type() == Gnome::Conf::VALUE_STRING)
      inter = v.get_string();
      else
      inter = "eth";    // FIXME: use schema?

      
      v = client->get(mon_dir + "/interface_no");
      
      if (v.get_type() == Gnome::Conf::VALUE_INT)
      inter_no = v.get_int();
      else
      inter_no = 0;     // FIXME: use schema?

      
      v = client->get(mon_dir + "/interface_direction");
      
      if (v.get_type() == Gnome::Conf::VALUE_INT)
      inter_direction = v.get_int();
      else
      inter_direction = NetworkLoadMonitor::all_data; // FIXME: use schema?

      NetworkLoadMonitor::Direction dir;
      
      if (inter_direction == NetworkLoadMonitor::incoming_data)
      dir = NetworkLoadMonitor::incoming_data;
      else if (inter_direction == NetworkLoadMonitor::outgoing_data)
      dir = NetworkLoadMonitor::outgoing_data;
      else
      dir = NetworkLoadMonitor::all_data;

      monitors.push_back(new NetworkLoadMonitor(inter, inter_no, dir));
    }
    else if (type == "temperature") {
      Gnome::Conf::Value v = client->get(mon_dir + "/temperature_no");
      int temperature_no;
      
      if (v.get_type() == Gnome::Conf::VALUE_INT)
      temperature_no = v.get_int();
      else
      temperature_no = 0;     // FIXME: use schema?
      
      monitors.push_back(new TemperatureMonitor(temperature_no));
    }
    else if (type == "fan_speed") {
      Gnome::Conf::Value v = client->get(mon_dir + "/fan_no");
      int fan_no;
      
      if (v.get_type() == Gnome::Conf::VALUE_INT)
      fan_no = v.get_int();
      else
      fan_no = 0; // FIXME: use schema?
      
      monitors.push_back(new FanSpeedMonitor(fan_no));
    }

    monitors.back()->set_gconf_dir(mon_dir);
  }

  // always start with a CpuUsageMonitor - FIXME: use schema?
  if (monitors.empty())
    monitors.push_back(new CpuUsageMonitor);

  return monitors;
}


//
// helpers
//

// for setting precision
struct Precision
{
  int n;
};

template <typename T>
T &operator <<(T& os, const Precision &p)
{
#if __GNUC__ < 3
  os << std::setprecision(p.n) << std::setiosflags(std::ios::fixed);
#else
  os << std::setprecision(p.n) << std::setiosflags(std::ios_base::fixed);
#endif
  return os;
}

Precision precision(int n)
{
  Precision p;
  p.n = n;
  return p;
}

// for getting max no. of decimal digits
Precision decimal_digits(double val, int n)
{
  Precision p;

  if (val == 0)
    p.n = 1;
  else {
    while (val > 1 && n > 0) {
      val /= 10;
      --n;
    }

    p.n = n;
  }
  
  return p;
}


//
// class CpuUsageMonitor
//

int const CpuUsageMonitor::max_cpu_no = GLIBTOP_NCPU;

CpuUsageMonitor::CpuUsageMonitor()
  : cpu_no(all_cpus), user_time(0), nice_time(0), sys_time(0), idle_time(0)
{}

CpuUsageMonitor::CpuUsageMonitor(int cpu)
  : cpu_no(cpu), user_time(0), nice_time(0), sys_time(0), idle_time(0)
{
  assert(cpu_no >= 0 && cpu_no < GLIBTOP_NCPU);
}

double CpuUsageMonitor::do_measure()
{
  glibtop_cpu cpu;
      
  glibtop_get_cpu(&cpu);

  guint64 u, n, s, i;
      
  if (cpu_no == all_cpus) {
    u = cpu.user;
    n = cpu.nice;
    s = cpu.sys;
    i = cpu.idle;
  }
  else {
    u = cpu.xcpu_user[cpu_no];
    n = cpu.xcpu_nice[cpu_no];
    s = cpu.xcpu_sys[cpu_no];
    i = cpu.xcpu_idle[cpu_no];
  }
      
  // calculate ticks since last call
  guint64
    duser = u - user_time,
    dnice = n - nice_time,
    dsys = s - sys_time,
    didle = i - idle_time; 

  // and save the new values
  user_time = u;
  nice_time = n;
  sys_time = s;
  idle_time = i;
    
  guint64 total = duser + dnice + dsys + didle;

  if (total > 0)
    // don't count dnice to avoid always showing 100% with SETI@home and
    // similar applications running
    return double(duser + dsys) / total;
  else
    return 0;
}

double CpuUsageMonitor::max()
{
  return 1;
}

Glib::ustring CpuUsageMonitor::format_value(double val)
{
  return String::ucompose(_("%1%%"), precision(1), 100 * val);
}

Glib::ustring CpuUsageMonitor::get_name()
{
  if (cpu_no == all_cpus)
    return _("All processors");
  else
    return String::ucompose(_("Processor no. %1"), cpu_no + 1);
}

Glib::ustring CpuUsageMonitor::get_short_name()
{
  if (cpu_no == all_cpus)
    // must be short
    return _("CPU");
  else
    // note to translators: %1 is the cpu no, e.g. "CPU 1"
    return String::ucompose(_("CPU %1"), cpu_no + 1);
}

int CpuUsageMonitor::update_interval()
{
  return 1000;
}

void CpuUsageMonitor::save(const Glib::RefPtr<Gnome::Conf::Client> &client)
{
  Glib::ustring dir = get_gconf_dir();
  client->set(dir + "/type", Glib::ustring("cpu_usage"));
  client->set(dir + "/cpu_no", cpu_no);
}


//
// class SwapUsageMonitor
//

SwapUsageMonitor::SwapUsageMonitor()
  : max_value(0)
{
}

double SwapUsageMonitor::do_measure()
{
  glibtop_swap swp;
      
  glibtop_get_swap(&swp);
      
  max_value = swp.total;

  if (swp.total > 0)
    return swp.used;
  else
    return 0;
}

double SwapUsageMonitor::max()
{
  return max_value;
}

Glib::ustring SwapUsageMonitor::format_value(double val)
{
  val /= 1000000;
  
  return String::ucompose(_("%1 Mb"), decimal_digits(val, 3), val);
}

Glib::ustring SwapUsageMonitor::get_name()
{
  return _("Disk-based memory");
}

Glib::ustring SwapUsageMonitor::get_short_name()
{
  // must be short
  return _("Swap");
}

int SwapUsageMonitor::update_interval()
{
  return 10 * 1000;
}

void SwapUsageMonitor::save(const Glib::RefPtr<Gnome::Conf::Client> &client)
{
  Glib::ustring dir = get_gconf_dir();
  client->set(dir + "/type", Glib::ustring("swap_usage"));
}


//
// class LoadAverageMonitor
//

LoadAverageMonitor::LoadAverageMonitor()
  : max_value(1.0)
{
}

double LoadAverageMonitor::do_measure()
{
  glibtop_loadavg loadavg;
      
  glibtop_get_loadavg (&loadavg);

  double val = loadavg.loadavg[0];
  
  max_value *= max_decay;     // reduce gradually
  
  if (max_value < 1)          // make sure we don't get below 1
    max_value = 1;
  
  if (val > max_value)
    max_value = val * 1.05;

  if (max_value > 0)
    return val;
  else
    return 0;
}

double LoadAverageMonitor::max()
{
  return max_value;
}

Glib::ustring LoadAverageMonitor::format_value(double val)
{
  return String::ucompose("%1", precision(1), val);
}

Glib::ustring LoadAverageMonitor::get_name()
{
  return _("Load average");
}

Glib::ustring LoadAverageMonitor::get_short_name()
{
  // note to translators: short for "load average" - it has nothing to do with
  // loading data
  return _("Load");
}

int LoadAverageMonitor::update_interval()
{
  return 30 * 1000;
}

void LoadAverageMonitor::save(const Glib::RefPtr<Gnome::Conf::Client> &client)
{
  Glib::ustring dir = get_gconf_dir();
  client->set(dir + "/type", Glib::ustring("load_average"));
  client->set(dir + "/max", max_value);
}

void LoadAverageMonitor::load(const Glib::RefPtr<Gnome::Conf::Client> &client)
{
  Glib::ustring dir = get_gconf_dir();
  if (client->get_string(dir + "/type") == "load_average") {
    Gnome::Conf::Value v = client->get(dir + "/max");
    if (v.get_type() == Gnome::Conf::VALUE_FLOAT)
      max_value = v.get_float();
  }
}


//
// class MemoryUsageMonitor
//

MemoryUsageMonitor::MemoryUsageMonitor()
  : max_value(0)
{
}

double MemoryUsageMonitor::do_measure()
{
  glibtop_mem mem;
      
  glibtop_get_mem (&mem);

  max_value = mem.total;

  if (mem.total > 0)
    return mem.used - (mem.buffer + mem.cached);
  else
    return 0;
}

double MemoryUsageMonitor::max()
{
  return max_value;
}
      
Glib::ustring MemoryUsageMonitor::format_value(double val)
{
  val /= 1000000;
  
  return String::ucompose(_("%1 Mb"), decimal_digits(val, 3), val);
}

Glib::ustring MemoryUsageMonitor::get_name()
{
  return _("Memory");
}

Glib::ustring MemoryUsageMonitor::get_short_name()
{
  // short for memory
  return _("Mem.");
}

int MemoryUsageMonitor::update_interval()
{
  return 10 * 1000;
}

void MemoryUsageMonitor::save(const Glib::RefPtr<Gnome::Conf::Client> &client)
{
  Glib::ustring dir = get_gconf_dir();
  client->set(dir + "/type", Glib::ustring("memory_usage"));
}


//
// class DiskUsageMonitor
//

DiskUsageMonitor::DiskUsageMonitor(const std::string &dir, bool free)
  : max_value(0), mount_dir(dir), show_free(free)
{
}

double DiskUsageMonitor::do_measure()
{
  glibtop_fsusage fsusage;

  glibtop_get_fsusage(&fsusage, mount_dir.c_str());

  max_value = fsusage.blocks * fsusage.block_size;

  double v = 0;
  
  if (show_free) {
    if (fsusage.bavail > 0)
      v = fsusage.bavail * fsusage.block_size;
  }
  else {
    if (fsusage.blocks > 0)
      v = (fsusage.blocks - fsusage.bfree) * fsusage.block_size;
  }
  
  return v;
}

double DiskUsageMonitor::max()
{
  return max_value;
}

Glib::ustring DiskUsageMonitor::format_value(double val)
{
  if (val >= 1000 * 1000 * 1000) {
    val /= 1000 * 1000 * 1000;
    return String::ucompose(_("%1 Gb"), decimal_digits(val, 3), val);
  }
  else if (val >= 1000 * 1000) {
    val /= 1000 * 1000;
    return String::ucompose(_("%1 Mb"), decimal_digits(val, 3), val);
  }
  else if (val >= 1000) {
    val /= 1000;
    return String::ucompose(_("%1 kb"), decimal_digits(val, 3), val);
  }
  else
    return String::ucompose(_("%1 b"), decimal_digits(val, 3), val);
}

Glib::ustring DiskUsageMonitor::get_name()
{
  return String::ucompose(_("Disk (%1)"), mount_dir);
}


Glib::ustring DiskUsageMonitor::get_short_name()
{
  return String::ucompose("%1", mount_dir);
}

int DiskUsageMonitor::update_interval()
{
  return 60 * 1000;
}

void DiskUsageMonitor::save(const Glib::RefPtr<Gnome::Conf::Client> &client)
{
  Glib::ustring dir = get_gconf_dir();
  client->set(dir + "/type", Glib::ustring("disk_usage"));
  client->set(dir + "/mount_dir", mount_dir);
  client->set(dir + "/show_free", show_free);
}


//
// class NetworkLoadMonitor
//

NetworkLoadMonitor::NetworkLoadMonitor(const Glib::ustring &inter, int inter_no,
                               Direction dir)
  : max_value(1), byte_count(0), time_stamp_secs(0), time_stamp_usecs(0),
    interface(inter), interface_no(inter_no), direction(dir)
{
}

double NetworkLoadMonitor::do_measure()
{
  glibtop_netload netload;

  glibtop_get_netload(&netload,
                  String::ucompose("%1%2", interface, interface_no).c_str());
  guint64 val, bytes;
    
  if (direction == all_data)
    bytes = netload.bytes_total;
  else if (direction == incoming_data)
    bytes = netload.bytes_in;
  else
    bytes = netload.bytes_out;
  
  if (byte_count == 0)
    val = 0;   // avoid calculating an enormous throughput initially
  else
    val = bytes - byte_count;

  byte_count = bytes;

  if (val != 0)               // reduce gradually
    max_value = guint64(max_value * max_decay);
  
  if (val > max_value)
    max_value = guint64(val * 1.05);

  for (nlm_seq::iterator i = sync_monitors.begin(), end = sync_monitors.end();
       i != end; ++i) {
    NetworkLoadMonitor &other = **i;
    if (other.max_value > max_value)
      max_value = other.max_value;
    else if (max_value > other.max_value)
      other.max_value = max_value;
  }
  
  // calculate difference in msecs
  struct timeval tv;
  if (gettimeofday(&tv, 0) == 0) {
    time_difference =
      (tv.tv_sec - time_stamp_secs) * 1000 +
      (tv.tv_usec - time_stamp_usecs) / 1000;
    time_stamp_secs = tv.tv_sec;
    time_stamp_usecs = tv.tv_usec;
  }

  return val;
}

double NetworkLoadMonitor::max()
{
  return max_value;
}

Glib::ustring NetworkLoadMonitor::format_value(double val)
{
  // 1000 ms = 1 s
  val = val / time_difference * 1000;

  if (val <= 0)               // fix weird problem with negative values
    val = 0;
  
  if (val >= 1000 * 1000 * 1000) {
    val /= 1000 * 1000 * 1000;
    return String::ucompose(_("%1 Gb/s"), decimal_digits(val, 3), val);
  }
  else if (val >= 1000 * 1000) {
    val /= 1000 * 1000;
    return String::ucompose(_("%1 Mb/s"), decimal_digits(val, 3), val);
  }
  else if (val >= 1000) {
    val /= 1000;
    return String::ucompose(_("%1 kb/s"), decimal_digits(val, 3), val);
  }
  else 
    return String::ucompose(_("%1 b/s"), decimal_digits(val, 3), val);
}

Glib::ustring NetworkLoadMonitor::get_name()
{
  Glib::ustring str;
  
  if (interface == "eth" && interface_no == 0)
    str = _("Ethernet (first)");
  else if (interface == "eth" && interface_no == 1)
    str = _("Ethernet (second)");
  else if (interface == "eth" && interface_no == 2)
    str = _("Ethernet (third)");
  else if (interface == "ppp" && interface_no == 0)
    str = _("Modem");
  else if (interface == "slip" && interface_no == 0)
    str = _("Serial link");
  else if (interface == "wlan" && interface_no == 0)
    str = _("Wireless");
  else
    // unknown, someone must have been fiddling with GConf
    str = String::ucompose("%1%2", interface, interface_no);

  if (direction == incoming_data)
    // %1 is the network connection, e.g. "Ethernet (first)", in signifies
    // that this is incoming data
    str = String::ucompose(_("%1, in"), str);
  else if (direction == outgoing_data)
    // %1 is the network connection, e.g. "Ethernet (first)", out signifies
    // that this is outgoing data
    str = String::ucompose(_("%1, out"), str);
  
  return str;
}

Glib::ustring NetworkLoadMonitor::get_short_name()
{
  Glib::ustring str;
  
  if (interface == "eth")
    // short for an ethernet card
    str = String::ucompose(_("Eth. %1"), interface_no + 1);
  else if (interface == "ppp" && interface_no == 0)
    // short for modem
    str = _("Mod.");
  else if (interface == "slip" && interface_no == 0)
    // short for serial link
    str = _("Ser.");
  else if (interface == "wlan" && interface_no == 0)
    // short for wireless
    str = _("W.less.");
  else
    // unknown, someone must have been fiddling with GConf
    str = String::ucompose("%1%2", interface, interface_no);

  if (direction == incoming_data)
    str = String::ucompose(_("%1, in"), str);
  else if (direction == outgoing_data)
    str = String::ucompose(_("%1, out"), str);

  return str;
}

int NetworkLoadMonitor::update_interval()
{
  return 1000;
}

void NetworkLoadMonitor::save(const Glib::RefPtr<Gnome::Conf::Client> &client)
{
  Glib::ustring dir = get_gconf_dir();
  client->set(dir + "/type", Glib::ustring("network_load"));
  client->set(dir + "/interface", interface);
  client->set(dir + "/interface_no", interface_no);
  client->set(dir + "/interface_direction", int(direction));
  client->set(dir + "/max", int(max_value)); // hopefully 32 bits is enough
}

void NetworkLoadMonitor::load(const Glib::RefPtr<Gnome::Conf::Client> &client)
{
  Glib::ustring dir = get_gconf_dir();
  if (client->get_string(dir + "/type") == "network_load"
      && client->get_string(dir + "/interface") == interface
      && client->get_int(dir + "/interface_no") == interface_no
      && client->get_int(dir + "/interface_direction") == int(direction)) {
    Gnome::Conf::Value v = client->get(dir + "/max");
    if (v.get_type() == Gnome::Conf::VALUE_INT)
      max_value = v.get_int();
  }
}

void NetworkLoadMonitor::possibly_add_sync_with(Monitor *other)
{
  if (NetworkLoadMonitor *o = dynamic_cast<NetworkLoadMonitor *>(other))
    if (interface == o->interface && interface_no == o->interface_no
      && direction != o->direction)
      sync_monitors.push_back(o);
}

void NetworkLoadMonitor::remove_sync_with(Monitor *other)
{
  nlm_seq::iterator i
    = std::find(sync_monitors.begin(), sync_monitors.end(), other);

  if (i != sync_monitors.end())
    sync_monitors.erase(i);
}


//
// implementation of sensors wrapper
//

Sensors::Sensors()
{
#if HAVE_LIBSENSORS
  std::FILE *conf_file = std::fopen(SENSORS_CONF_FILE, "r");

  if (!conf_file)
    return;

  if (sensors_init(conf_file) != 0)
    return;

  int i = 0;
  const sensors_chip_name *c;
  
  while ((c = sensors_get_detected_chips(&i)))
    chips.push_back(*c);
#endif
}

Sensors::~Sensors()
{
#if HAVE_LIBSENSORS
  chips.clear();
  
  sensors_cleanup();
#endif
}

Sensors &Sensors::instance()
{
  static Sensors s;

  return s;
}


Sensors::FeatureInfoSequence Sensors::get_features(std::string base)
{
  FeatureInfoSequence vec;
  
#if HAVE_LIBSENSORS
  const sensors_feature_data *data;

  for (unsigned int i = 0; i < chips.size(); ++i) {
    sensors_chip_name &chip = chips[i];
    int i1 = 0, i2 = 0;

    std::string last_feature;
    while ((data = sensors_get_all_features(chip, &i1, &i2))) {
      std::string name = data->name;

      // check whether this is a main feature
      if (name.find(base) != std::string::npos
        && data->mapping == SENSORS_NO_MAPPING
        && sensors_get_ignored(chip, data->number) != 0) {
      FeatureInfo info;
      info.chip_no = i;
      info.feature_no = data->number;
      info.max = invalid_max;

      char *desc;
      if (sensors_get_label(chip, info.feature_no, &desc) == 0) {
        info.description = desc;
        std::free(desc);
      }
        
      vec.push_back(info);
      last_feature = name;
      }
      // check whether this is a max value for the last feature
      else if (data->mapping != SENSORS_NO_MAPPING
             && !last_feature.empty()
             && name.find(last_feature) != std::string::npos
             && name.find("_over") != std::string::npos) {
      double max;
      if (sensors_get_feature(chip, data->number, &max) == 0)
        vec.back().max = max;
      else
        vec.back().max = invalid_max;
      }
    }
  }
#endif
  
  return vec;
}

Sensors::FeatureInfoSequence Sensors::get_temperature_features()
{
  return get_features("temp");
}

Sensors::FeatureInfoSequence Sensors::get_fan_features()
{
  return get_features("fan");
}
  
double Sensors::get_value(int chip_no, int feature_no)
{
#if HAVE_LIBSENSORS
  if (chip_no < 0 || chip_no >= int(chips.size()))
    return 0;

  double res;

  if (sensors_get_feature(chips[chip_no], feature_no, &res) == 0)
    return res;
  else
    return 0;
#else
  return 0;
#endif
}



//
// class TemperatureMonitor
//

double const Sensors::invalid_max = -1000000;

TemperatureMonitor::TemperatureMonitor(int no)
  : sensors_no(no)
{
  Sensors::FeatureInfo info
    = Sensors::instance().get_temperature_features()[sensors_no];
  
  chip_no = info.chip_no;
  feature_no = info.feature_no;
  description = info.description;
  if (info.max != Sensors::invalid_max)
    max_value = info.max;
  else
    max_value = 40;            // set a reasonable default (40 Celcius degrees)
}

double TemperatureMonitor::do_measure()
{
  double val = Sensors::instance().get_value(chip_no, feature_no);
  
  if (val > max_value)
    max_value = val;

  return val;
}

double TemperatureMonitor::max()
{
  return max_value;
}

Glib::ustring TemperatureMonitor::format_value(double val)
{
  // %2 contains the degree sign (the following 'C' stands for Celsius)
  return String::ucompose(_("%1%2C"), decimal_digits(val, 3), val, "\xc2\xb0");
}

Glib::ustring TemperatureMonitor::get_name()
{
  if (!description.empty())
    // %2 is a descriptive string from sensors.conf
    return String::ucompose(_("Temperature %1: \"%2\""),
                      sensors_no + 1, description);
  else
    return String::ucompose(_("Temperature %1"), sensors_no + 1);
}

Glib::ustring TemperatureMonitor::get_short_name()
{
  // short for "temperature", %1 is sensor no.
  return String::ucompose(_("Temp. %1"), sensors_no + 1);
}

int TemperatureMonitor::update_interval()
{
  return 20 * 1000;
}

void TemperatureMonitor::save(const Glib::RefPtr<Gnome::Conf::Client> &client)
{
  Glib::ustring dir = get_gconf_dir();
  client->set(dir + "/type", Glib::ustring("temperature"));
  client->set(dir + "/temperature_no", sensors_no);
  client->set(dir + "/max", max_value);
}

void TemperatureMonitor::load(const Glib::RefPtr<Gnome::Conf::Client> &client)
{
  Glib::ustring dir = get_gconf_dir();
  if (client->get_string(dir + "/type") == "temperature"
      && client->get_int(dir + "/temperature_no") == sensors_no) {
    Gnome::Conf::Value v = client->get(dir + "/max");
    if (v.get_type() == Gnome::Conf::VALUE_FLOAT)
      max_value = v.get_float();
  }
}



//
// class FanSpeedMonitor
//

FanSpeedMonitor::FanSpeedMonitor(int no)
  : sensors_no(no)
{
  Sensors::FeatureInfo info
    = Sensors::instance().get_fan_features()[sensors_no];
  
  chip_no = info.chip_no;
  feature_no = info.feature_no;
  description = info.description;
  if (info.max != Sensors::invalid_max)
    max_value = info.max;
  else
    max_value = 1;            // 1 rpm isn't realistic, but whatever
}

double FanSpeedMonitor::do_measure()
{
  double val = Sensors::instance().get_value(chip_no, feature_no);
  
  if (val > max_value)
    max_value = val;

  return val;
}

double FanSpeedMonitor::max()
{
  return max_value;
}

Glib::ustring FanSpeedMonitor::format_value(double val)
{
  // rpm is rotations per minute
  return String::ucompose(_("%1 rpm"), val, val);
}

Glib::ustring FanSpeedMonitor::get_name()
{
  if (!description.empty())
    // %2 is a descriptive string from sensors.conf
    return String::ucompose(_("Fan %1 speed: \"%2\""),
                      sensors_no + 1, description);
  else
    return String::ucompose(_("Fan %1 speed"), sensors_no + 1);
}

Glib::ustring FanSpeedMonitor::get_short_name()
{
  return String::ucompose(_("Fan %1"), sensors_no + 1);
}

int FanSpeedMonitor::update_interval()
{
  return 20 * 1000;
}

void FanSpeedMonitor::save(const Glib::RefPtr<Gnome::Conf::Client> &client)
{
  Glib::ustring dir = get_gconf_dir();
  client->set(dir + "/type", Glib::ustring("fan_speed"));
  client->set(dir + "/fan_no", sensors_no);
  client->set(dir + "/max", max_value);
}

void FanSpeedMonitor::load(const Glib::RefPtr<Gnome::Conf::Client> &client)
{
  Glib::ustring dir = get_gconf_dir();
  if (client->get_string(dir + "/type") == "fan_speed"
      && client->get_int(dir + "/fan_no") == sensors_no) {
    Gnome::Conf::Value v = client->get(dir + "/max");
    if (v.get_type() == Gnome::Conf::VALUE_FLOAT)
      max_value = v.get_float();
  }
}

Generated by  Doxygen 1.6.0   Back to index