]> git.ipfire.org Git - thirdparty/libatasmart.git/commitdiff
lots of updates
authorLennart Poettering <lennart@poettering.net>
Tue, 1 Jul 2008 16:57:23 +0000 (18:57 +0200)
committerLennart Poettering <lennart@poettering.net>
Tue, 1 Jul 2008 16:57:23 +0000 (18:57 +0200)
gnome-disk-health.glade
gnome-disk-health.vala
smartkitd.vala

index c345ababfee51898b5dbaee5ce9d14471eb33be7..a1a122f2ab6d2f4980792dd58a9d065126e00915 100644 (file)
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="UTF-8" standalone="no"?>
 <!DOCTYPE glade-interface SYSTEM "glade-2.0.dtd">
-<!--Generated with glade3 3.4.4 on Mon Jun 30 23:57:51 2008 -->
+<!--Generated with glade3 3.4.4 on Tue Jul  1 17:44:40 2008 -->
 <glade-interface>
   <widget class="GtkDialog" id="DiskHealthDialog">
     <property name="border_width">5</property>
                         <property name="column_spacing">6</property>
                         <property name="row_spacing">6</property>
                         <child>
-                          <widget class="GtkLabel" id="label5">
+                          <widget class="GtkLabel" id="firmwareLabel">
                             <property name="visible">True</property>
-                            <property name="xalign">1</property>
-                            <property name="label" translatable="yes">&lt;b&gt;Path:&lt;/b&gt;</property>
-                            <property name="use_markup">True</property>
+                            <property name="xalign">0</property>
+                            <property name="label" translatable="yes">label</property>
                           </widget>
                           <packing>
-                            <property name="x_options">GTK_FILL</property>
-                            <property name="y_options">GTK_FILL</property>
+                            <property name="left_attach">1</property>
+                            <property name="right_attach">2</property>
+                            <property name="top_attach">4</property>
+                            <property name="bottom_attach">5</property>
                           </packing>
                         </child>
                         <child>
-                          <widget class="GtkLabel" id="label6">
+                          <widget class="GtkLabel" id="serialLabel">
                             <property name="visible">True</property>
-                            <property name="xalign">1</property>
-                            <property name="label" translatable="yes">&lt;b&gt;Size:&lt;/b&gt;</property>
-                            <property name="use_markup">True</property>
+                            <property name="xalign">0</property>
+                            <property name="label" translatable="yes">label</property>
                           </widget>
                           <packing>
-                            <property name="top_attach">1</property>
-                            <property name="bottom_attach">2</property>
-                            <property name="x_options">GTK_FILL</property>
+                            <property name="left_attach">1</property>
+                            <property name="right_attach">2</property>
+                            <property name="top_attach">3</property>
+                            <property name="bottom_attach">4</property>
                           </packing>
                         </child>
                         <child>
-                          <widget class="GtkLabel" id="label7">
+                          <widget class="GtkLabel" id="modelLabel">
                             <property name="visible">True</property>
-                            <property name="xalign">1</property>
-                            <property name="label" translatable="yes">&lt;b&gt;Model:&lt;/b&gt;</property>
-                            <property name="use_markup">True</property>
+                            <property name="xalign">0</property>
+                            <property name="label" translatable="yes">label</property>
                           </widget>
                           <packing>
+                            <property name="left_attach">1</property>
+                            <property name="right_attach">2</property>
                             <property name="top_attach">2</property>
                             <property name="bottom_attach">3</property>
-                            <property name="x_options">GTK_FILL</property>
                           </packing>
                         </child>
                         <child>
-                          <widget class="GtkLabel" id="label8">
+                          <widget class="GtkLabel" id="sizeLabel">
                             <property name="visible">True</property>
-                            <property name="xalign">1</property>
-                            <property name="label" translatable="yes">&lt;b&gt;Serial Number:&lt;/b&gt;</property>
-                            <property name="use_markup">True</property>
+                            <property name="xalign">0</property>
+                            <property name="label" translatable="yes">label</property>
                           </widget>
                           <packing>
-                            <property name="top_attach">3</property>
-                            <property name="bottom_attach">4</property>
-                            <property name="x_options">GTK_FILL</property>
+                            <property name="left_attach">1</property>
+                            <property name="right_attach">2</property>
+                            <property name="top_attach">1</property>
+                            <property name="bottom_attach">2</property>
+                          </packing>
+                        </child>
+                        <child>
+                          <widget class="GtkLabel" id="pathLabel">
+                            <property name="visible">True</property>
+                            <property name="xalign">0</property>
+                            <property name="label" translatable="yes">label</property>
+                          </widget>
+                          <packing>
+                            <property name="left_attach">1</property>
+                            <property name="right_attach">2</property>
                           </packing>
                         </child>
                         <child>
                           </packing>
                         </child>
                         <child>
-                          <widget class="GtkLabel" id="pathLabel">
-                            <property name="visible">True</property>
-                            <property name="xalign">0</property>
-                            <property name="label" translatable="yes">label</property>
-                          </widget>
-                          <packing>
-                            <property name="left_attach">1</property>
-                            <property name="right_attach">2</property>
-                          </packing>
-                        </child>
-                        <child>
-                          <widget class="GtkLabel" id="sizeLabel">
+                          <widget class="GtkLabel" id="label8">
                             <property name="visible">True</property>
-                            <property name="xalign">0</property>
-                            <property name="label" translatable="yes">label</property>
+                            <property name="xalign">1</property>
+                            <property name="label" translatable="yes">&lt;b&gt;Serial Number:&lt;/b&gt;</property>
+                            <property name="use_markup">True</property>
                           </widget>
                           <packing>
-                            <property name="left_attach">1</property>
-                            <property name="right_attach">2</property>
-                            <property name="top_attach">1</property>
-                            <property name="bottom_attach">2</property>
+                            <property name="top_attach">3</property>
+                            <property name="bottom_attach">4</property>
+                            <property name="x_options">GTK_FILL</property>
                           </packing>
                         </child>
                         <child>
-                          <widget class="GtkLabel" id="modelLabel">
+                          <widget class="GtkLabel" id="label7">
                             <property name="visible">True</property>
-                            <property name="xalign">0</property>
-                            <property name="label" translatable="yes">label</property>
+                            <property name="xalign">1</property>
+                            <property name="label" translatable="yes">&lt;b&gt;Model:&lt;/b&gt;</property>
+                            <property name="use_markup">True</property>
                           </widget>
                           <packing>
-                            <property name="left_attach">1</property>
-                            <property name="right_attach">2</property>
                             <property name="top_attach">2</property>
                             <property name="bottom_attach">3</property>
+                            <property name="x_options">GTK_FILL</property>
                           </packing>
                         </child>
                         <child>
-                          <widget class="GtkLabel" id="serialLabel">
+                          <widget class="GtkLabel" id="label6">
                             <property name="visible">True</property>
-                            <property name="xalign">0</property>
-                            <property name="label" translatable="yes">label</property>
+                            <property name="xalign">1</property>
+                            <property name="label" translatable="yes">&lt;b&gt;Size:&lt;/b&gt;</property>
+                            <property name="use_markup">True</property>
                           </widget>
                           <packing>
-                            <property name="left_attach">1</property>
-                            <property name="right_attach">2</property>
-                            <property name="top_attach">3</property>
-                            <property name="bottom_attach">4</property>
+                            <property name="top_attach">1</property>
+                            <property name="bottom_attach">2</property>
+                            <property name="x_options">GTK_FILL</property>
                           </packing>
                         </child>
                         <child>
-                          <widget class="GtkLabel" id="firmwareLabel">
+                          <widget class="GtkLabel" id="label5">
                             <property name="visible">True</property>
-                            <property name="xalign">0</property>
-                            <property name="label" translatable="yes">label</property>
+                            <property name="xalign">1</property>
+                            <property name="label" translatable="yes">&lt;b&gt;Path:&lt;/b&gt;</property>
+                            <property name="use_markup">True</property>
                           </widget>
                           <packing>
-                            <property name="left_attach">1</property>
-                            <property name="right_attach">2</property>
-                            <property name="top_attach">4</property>
-                            <property name="bottom_attach">5</property>
+                            <property name="x_options">GTK_FILL</property>
+                            <property name="y_options">GTK_FILL</property>
                           </packing>
                         </child>
                       </widget>
                         <property name="position">3</property>
                       </packing>
                     </child>
+                    <child>
+                      <widget class="GtkLabel" id="powerOnLabel">
+                        <property name="visible">True</property>
+                        <property name="label" translatable="yes">The disk has been powered on for 3.1 months.</property>
+                      </widget>
+                      <packing>
+                        <property name="expand">False</property>
+                        <property name="position">4</property>
+                      </packing>
+                    </child>
                   </widget>
                   <packing>
                     <property name="padding">16</property>
                         <property name="column_spacing">6</property>
                         <property name="row_spacing">6</property>
                         <child>
-                          <widget class="GtkLabel" id="label21">
-                            <property name="visible">True</property>
-                            <property name="xalign">1</property>
-                            <property name="label" translatable="yes">&lt;b&gt;Name:&lt;/b&gt;</property>
-                            <property name="use_markup">True</property>
-                          </widget>
-                          <packing>
-                            <property name="x_options">GTK_FILL</property>
-                            <property name="y_options">GTK_FILL</property>
-                          </packing>
-                        </child>
-                        <child>
-                          <widget class="GtkLabel" id="label22">
+                          <widget class="GtkLabel" id="verdictLabel">
                             <property name="visible">True</property>
-                            <property name="xalign">1</property>
-                            <property name="label" translatable="yes">&lt;b&gt;ID:&lt;/b&gt;</property>
-                            <property name="use_markup">True</property>
+                            <property name="xalign">0</property>
+                            <property name="label" translatable="yes">n/a</property>
                           </widget>
                           <packing>
-                            <property name="top_attach">1</property>
-                            <property name="bottom_attach">2</property>
+                            <property name="left_attach">1</property>
+                            <property name="right_attach">2</property>
+                            <property name="top_attach">6</property>
+                            <property name="bottom_attach">7</property>
                             <property name="x_options">GTK_FILL</property>
                             <property name="y_options">GTK_FILL</property>
                           </packing>
                         </child>
                         <child>
-                          <widget class="GtkLabel" id="label23">
+                          <widget class="GtkLabel" id="label33">
                             <property name="visible">True</property>
                             <property name="xalign">1</property>
-                            <property name="label" translatable="yes">&lt;b&gt;Current Value:&lt;/b&gt;</property>
+                            <property name="label" translatable="yes">&lt;b&gt;Verdict:&lt;/b&gt;</property>
                             <property name="use_markup">True</property>
                           </widget>
                           <packing>
-                            <property name="top_attach">2</property>
-                            <property name="bottom_attach">3</property>
+                            <property name="top_attach">6</property>
+                            <property name="bottom_attach">7</property>
                             <property name="x_options">GTK_FILL</property>
                             <property name="y_options">GTK_FILL</property>
                           </packing>
                         </child>
                         <child>
-                          <widget class="GtkLabel" id="label24">
+                          <widget class="GtkLabel" id="typeLabel">
                             <property name="visible">True</property>
-                            <property name="xalign">1</property>
-                            <property name="label" translatable="yes">&lt;b&gt;Worst Value:&lt;/b&gt;</property>
-                            <property name="use_markup">True</property>
+                            <property name="xalign">0</property>
+                            <property name="label" translatable="yes">n/a</property>
                           </widget>
                           <packing>
-                            <property name="top_attach">3</property>
-                            <property name="bottom_attach">4</property>
+                            <property name="left_attach">1</property>
+                            <property name="right_attach">2</property>
+                            <property name="top_attach">5</property>
+                            <property name="bottom_attach">6</property>
                             <property name="x_options">GTK_FILL</property>
                             <property name="y_options">GTK_FILL</property>
                           </packing>
                         </child>
                         <child>
-                          <widget class="GtkLabel" id="label25">
+                          <widget class="GtkLabel" id="thresholdLabel">
                             <property name="visible">True</property>
-                            <property name="xalign">1</property>
-                            <property name="label" translatable="yes">&lt;b&gt;Threshold:&lt;/b&gt;</property>
-                            <property name="use_markup">True</property>
+                            <property name="xalign">0</property>
+                            <property name="label" translatable="yes">n/a</property>
                           </widget>
                           <packing>
+                            <property name="left_attach">1</property>
+                            <property name="right_attach">2</property>
                             <property name="top_attach">4</property>
                             <property name="bottom_attach">5</property>
                             <property name="x_options">GTK_FILL</property>
                           </packing>
                         </child>
                         <child>
-                          <widget class="GtkLabel" id="label26">
+                          <widget class="GtkLabel" id="worstLabel">
                             <property name="visible">True</property>
-                            <property name="xalign">1</property>
-                            <property name="label" translatable="yes">&lt;b&gt;Type:&lt;/b&gt;</property>
-                            <property name="use_markup">True</property>
+                            <property name="xalign">0</property>
+                            <property name="label" translatable="yes">n/a</property>
                           </widget>
                           <packing>
-                            <property name="top_attach">5</property>
-                            <property name="bottom_attach">6</property>
+                            <property name="left_attach">1</property>
+                            <property name="right_attach">2</property>
+                            <property name="top_attach">3</property>
+                            <property name="bottom_attach">4</property>
                             <property name="x_options">GTK_FILL</property>
                             <property name="y_options">GTK_FILL</property>
                           </packing>
                         </child>
                         <child>
-                          <widget class="GtkLabel" id="nameLabel">
+                          <widget class="GtkLabel" id="currentLabel">
                             <property name="visible">True</property>
                             <property name="xalign">0</property>
-                            <property name="label" translatable="yes">label</property>
+                            <property name="label" translatable="yes">n/a</property>
                           </widget>
                           <packing>
                             <property name="left_attach">1</property>
                             <property name="right_attach">2</property>
+                            <property name="top_attach">2</property>
+                            <property name="bottom_attach">3</property>
                             <property name="x_options">GTK_FILL</property>
                             <property name="y_options">GTK_FILL</property>
                           </packing>
                           <widget class="GtkLabel" id="idLabel">
                             <property name="visible">True</property>
                             <property name="xalign">0</property>
-                            <property name="label" translatable="yes">label</property>
+                            <property name="label" translatable="yes">n/a</property>
                           </widget>
                           <packing>
                             <property name="left_attach">1</property>
                           </packing>
                         </child>
                         <child>
-                          <widget class="GtkLabel" id="currentLabel">
+                          <widget class="GtkLabel" id="nameLabel">
                             <property name="visible">True</property>
                             <property name="xalign">0</property>
-                            <property name="label" translatable="yes">label</property>
+                            <property name="label" translatable="yes">n/a</property>
                           </widget>
                           <packing>
                             <property name="left_attach">1</property>
                             <property name="right_attach">2</property>
-                            <property name="top_attach">2</property>
-                            <property name="bottom_attach">3</property>
                             <property name="x_options">GTK_FILL</property>
                             <property name="y_options">GTK_FILL</property>
                           </packing>
                         </child>
                         <child>
-                          <widget class="GtkLabel" id="worstLabel">
+                          <widget class="GtkLabel" id="label26">
                             <property name="visible">True</property>
-                            <property name="xalign">0</property>
-                            <property name="label" translatable="yes">label</property>
+                            <property name="xalign">1</property>
+                            <property name="label" translatable="yes">&lt;b&gt;Type:&lt;/b&gt;</property>
+                            <property name="use_markup">True</property>
                           </widget>
                           <packing>
-                            <property name="left_attach">1</property>
-                            <property name="right_attach">2</property>
-                            <property name="top_attach">3</property>
-                            <property name="bottom_attach">4</property>
+                            <property name="top_attach">5</property>
+                            <property name="bottom_attach">6</property>
                             <property name="x_options">GTK_FILL</property>
                             <property name="y_options">GTK_FILL</property>
                           </packing>
                         </child>
                         <child>
-                          <widget class="GtkLabel" id="thresholdLabel">
+                          <widget class="GtkLabel" id="label25">
                             <property name="visible">True</property>
-                            <property name="xalign">0</property>
-                            <property name="label" translatable="yes">label</property>
+                            <property name="xalign">1</property>
+                            <property name="label" translatable="yes">&lt;b&gt;Threshold:&lt;/b&gt;</property>
+                            <property name="use_markup">True</property>
                           </widget>
                           <packing>
-                            <property name="left_attach">1</property>
-                            <property name="right_attach">2</property>
                             <property name="top_attach">4</property>
                             <property name="bottom_attach">5</property>
                             <property name="x_options">GTK_FILL</property>
                           </packing>
                         </child>
                         <child>
-                          <widget class="GtkLabel" id="typeLabel">
+                          <widget class="GtkLabel" id="label24">
                             <property name="visible">True</property>
-                            <property name="xalign">0</property>
-                            <property name="label" translatable="yes">label</property>
+                            <property name="xalign">1</property>
+                            <property name="label" translatable="yes">&lt;b&gt;Worst Value:&lt;/b&gt;</property>
+                            <property name="use_markup">True</property>
                           </widget>
                           <packing>
-                            <property name="left_attach">1</property>
-                            <property name="right_attach">2</property>
-                            <property name="top_attach">5</property>
-                            <property name="bottom_attach">6</property>
+                            <property name="top_attach">3</property>
+                            <property name="bottom_attach">4</property>
                             <property name="x_options">GTK_FILL</property>
                             <property name="y_options">GTK_FILL</property>
                           </packing>
                         </child>
                         <child>
-                          <widget class="GtkLabel" id="label33">
+                          <widget class="GtkLabel" id="label23">
                             <property name="visible">True</property>
                             <property name="xalign">1</property>
-                            <property name="label" translatable="yes">&lt;b&gt;Verdict:&lt;/b&gt;</property>
+                            <property name="label" translatable="yes">&lt;b&gt;Current Value:&lt;/b&gt;</property>
                             <property name="use_markup">True</property>
                           </widget>
                           <packing>
-                            <property name="top_attach">6</property>
-                            <property name="bottom_attach">7</property>
+                            <property name="top_attach">2</property>
+                            <property name="bottom_attach">3</property>
                             <property name="x_options">GTK_FILL</property>
                             <property name="y_options">GTK_FILL</property>
                           </packing>
                         </child>
                         <child>
-                          <widget class="GtkLabel" id="verdictLabel">
+                          <widget class="GtkLabel" id="label22">
                             <property name="visible">True</property>
-                            <property name="xalign">0</property>
-                            <property name="label" translatable="yes">label</property>
+                            <property name="xalign">1</property>
+                            <property name="label" translatable="yes">&lt;b&gt;ID:&lt;/b&gt;</property>
+                            <property name="use_markup">True</property>
+                          </widget>
+                          <packing>
+                            <property name="top_attach">1</property>
+                            <property name="bottom_attach">2</property>
+                            <property name="x_options">GTK_FILL</property>
+                            <property name="y_options">GTK_FILL</property>
+                          </packing>
+                        </child>
+                        <child>
+                          <widget class="GtkLabel" id="label21">
+                            <property name="visible">True</property>
+                            <property name="xalign">1</property>
+                            <property name="label" translatable="yes">&lt;b&gt;Name:&lt;/b&gt;</property>
+                            <property name="use_markup">True</property>
                           </widget>
                           <packing>
-                            <property name="left_attach">1</property>
-                            <property name="right_attach">2</property>
-                            <property name="top_attach">6</property>
-                            <property name="bottom_attach">7</property>
                             <property name="x_options">GTK_FILL</property>
                             <property name="y_options">GTK_FILL</property>
                           </packing>
         <child internal-child="action_area">
           <widget class="GtkHButtonBox" id="dialog-action_area1">
             <property name="visible">True</property>
-            <property name="layout_style">GTK_BUTTONBOX_END</property>
+            <property name="layout_style">GTK_BUTTONBOX_EDGE</property>
+            <child>
+              <widget class="GtkButton" id="refreshButton">
+                <property name="visible">True</property>
+                <property name="can_focus">True</property>
+                <property name="receives_default">True</property>
+                <property name="label" translatable="yes">gtk-refresh</property>
+                <property name="use_stock">True</property>
+                <property name="response_id">0</property>
+              </widget>
+            </child>
             <child>
               <widget class="GtkButton" id="closeButton">
                 <property name="visible">True</property>
                 <property name="use_stock">True</property>
                 <property name="response_id">0</property>
               </widget>
+              <packing>
+                <property name="position">1</property>
+              </packing>
             </child>
           </widget>
           <packing>
index 2632289855bf6a2b48728db2dfce5776c6ce5d78..a3fcd4d057ca5fc7c2936d41ff26d831686a8b06 100644 (file)
@@ -24,26 +24,51 @@ using DBus;
 using GLib;
 using Gtk;
 
+
+public DiskHealth disk_health;
+
 public class DiskHealth : Gtk.Builder {
 
         string uifile = "gnome-disk-health.ui";
 
         public bool create_widgets(string disk_string) {
+                test = null;
+
                 try {
                         add_from_file (uifile);
                         Gtk.Widget window = (Gtk.Widget) get_object("DiskHealthDialog");
 
+                        Gtk.TreeView tree_view = (Gtk.TreeView) get_object ("attributeTreeView");
+
+                        /* id, name, text, icon, current, worst, threshold, type, verdict */
+                        list_store = new Gtk.ListStore(9, typeof(uint8), typeof(string), typeof(string), typeof(string), typeof(string), typeof(string), typeof(string), typeof(string), typeof(string));
+
+                        tree_view.set_model(list_store);
+
+                        tree_view.insert_column_with_attributes (-1, null, new Gtk.CellRendererPixbuf(), "icon-name", 3, null);
+                        tree_view.insert_column_with_attributes(-1, "Name", new Gtk.CellRendererText(), "text", 1, null);
+
+                        Gtk.CellRenderer cell = new Gtk.CellRendererText();
+                        cell.set("xalign", 1.0, null);
+                        tree_view.insert_column_with_attributes (-1, "Value", cell, "text", 2, null);
+
                         if (!setup_connection(disk_string))
                                 return false;
 
                         if (!fill_in_data())
                                 return false;
 
+                        setup_refresh_timer();
+
                         window.show_all();
                         window.destroy += Gtk.main_quit;
 
                         ((Gtk.Button) get_object("closeButton")).clicked += Gtk.main_quit;
 
+                        ((Gtk.Button) get_object("refreshButton")).clicked += refresh;
+
+                        ((Gtk.Button) get_object("selfTestButton")).clicked += selfTest;
+
                 } catch (GLib.Error e) {
                         stderr.printf("Failed to create main window: %s\n", e.message);
                         return false;
@@ -56,6 +81,8 @@ public class DiskHealth : Gtk.Builder {
         private dynamic DBus.Object manager;
         private DBus.ObjectPath dbus_path;
         private dynamic DBus.Object disk;
+        private Gtk.ListStore list_store;
+        private string test;
 
         public bool setup_connection(string disk_string) {
                 try {
@@ -86,6 +113,58 @@ public class DiskHealth : Gtk.Builder {
                 return true;
         }
 
+        public void refresh() {
+                try {
+                        disk.readSmartData(true);
+                        fill_in_data();
+                        setup_refresh_timer();
+                } catch (DBus.Error e) {
+                        stderr.printf("D-Bus error: %s\n", e.message);
+                }
+        }
+
+        public uint refresh_time;
+        public uint refresh_timer = 0;
+
+        public void setup_refresh_timer() {
+
+                uint t;
+
+                if (refresh_time <= 0)
+                        t = 5*60;
+                else if (refresh_time == 1)
+                        t = 5; /* if 1 min is request, we do 10s
+                                * instead, since we know that
+                                * the minimal value is 1min */
+                else
+                        t = refresh_time*60;
+
+                if (t > 5*60)
+                        t = 5*60;
+
+                stderr.printf("Setting wakeup to %u (%u)\n", t, refresh_time);
+
+                disk_health = this;
+
+                if (refresh_timer > 0)
+                        Source.remove(refresh_timer);
+                refresh_timer = Timeout.add_seconds(t,
+                                () => {
+                                            stderr.printf("Woke up\n");
+                                            disk_health.refresh();
+                                            return false;
+                                });
+        }
+
+        public void selfTest() {
+                try {
+                        disk.startSelfTest(test);
+                        refresh();
+                } catch (DBus.Error e) {
+                        stderr.printf("D-Bus error: %s\n", e.message);
+                }
+        }
+
         public bool fill_in_data() {
 
                 try {
@@ -124,10 +203,47 @@ public class DiskHealth : Gtk.Builder {
                 ((Gtk.Label) get_object("healthLabel")).set_label("");
                 ((Gtk.Label) get_object("badSectorsLabel")).set_label("");
                 ((Gtk.Label) get_object("temperatureLabel")).set_label("");
+                ((Gtk.Label) get_object("powerOnLabel")).set_label("");
 
                 return fill_in_no_self_test_data();
         }
 
+        public string format_pretty(uint64 value, string unit) {
+
+                switch (unit) {
+
+                        case "mseconds":
+
+                                if (value >= (uint64)1000*60*60*24*365)
+                                        return "%0.1f years".printf(((double) value)/(1000.0*60*60*24*365));
+                                else if (value >= (uint64) 1000*60*60*24*30)
+                                        return "%0.1f months".printf(((double) value)/(1000.0*60*60*24*30));
+                                else if (value >= 1000*60*60*24)
+                                        return "%0.1f days".printf(((double) value)/(1000.0*60*60*24));
+                                else if (value >= 1000*60*60)
+                                        return "%0.1f h".printf(((double) value)/(1000.0*60*60));
+                                else if (value >= 1000*60)
+                                        return "%0.1f min".printf(((double) value)/(1000.0*60));
+                                else if (value >= 1000)
+                                        return "%0.1f s".printf(((double) value)/(1000.0));
+                                else
+                                        return "%llu ms".printf(value);
+
+                        case "mkelvin":
+                                return "%0.1f °C".printf(((double) value - 273150) / 1000);
+
+                        case "sectors":
+                                return "%llu sectors".printf(value);
+
+                        case "none":
+                                return "%llu".printf(value);
+
+                }
+
+                return "n/a";
+
+        }
+
         public bool fill_in_smart_data() {
                 try {
 
@@ -136,16 +252,103 @@ public class DiskHealth : Gtk.Builder {
                         bool b = disk.checkSmartStatus();
 
                         if (b)
-                                ((Gtk.Label) get_object("healthLabel")).set_label("Disk reports to be healthy.");
+                                ((Gtk.Label) get_object("healthLabel")).set_label("The disk reports to be healthy.");
+                        else
+                                ((Gtk.Label) get_object("healthLabel")).set_label("The disk reports that it has already failed or is expected to fail in the next 24h.");
+
+                        DBus.ObjectPath[] attrs = disk.getAttributes();
+
+                        uint64 temp = 0;
+                        uint64 rsc = 0;
+                        uint64 rec = 0;
+                        uint64 cps = 0;
+                        uint64 ou = 0;
+                        uint64 pon = 0;
+
+                        list_store.clear();
+
+                        foreach (DBus.ObjectPath a in attrs) {
+                                dynamic DBus.Object attribute;
+                                uint8 id;
+                                bool good, online, prefailure;
+                                string name;
+                                uint64 pretty_value;
+                                string pretty_unit;
+                                uint8 current, worst, threshold;
+
+                                attribute = connection.get_object("net.poettering.SmartKit", a, "net.poettering.SmartKit.Attribute");
+
+                                /* id, name, text, icon, current, worst, threshold, type, verdict */
+
+                                id = attribute.getId();
+                                name = attribute.getName();
+                                pretty_value = attribute.getPrettyValue();
+                                pretty_unit = attribute.getPrettyUnit();
+                                good = attribute.isGood();
+                                current = attribute.getCurrentValue();
+                                worst = attribute.getWorstValue();
+                                threshold = attribute.getThreshold();
+                                online = attribute.isOnline();
+                                prefailure = attribute.isPrefailure();
+
+                                Gtk.TreeIter iter;
+                                list_store.append(out iter);
+                                list_store.set(iter,
+                                               0, id,
+                                               1, name,
+                                               2, format_pretty(pretty_value, pretty_unit),
+                                               3, good ? "dialog-ok" : "dialog-warning",
+                                               4, "%u".printf(current),
+                                               5, "%u".printf(worst),
+                                               6, "%u".printf(threshold),
+                                               7, "%s/%s".printf(online ? "Online" : "Offline", prefailure ? "Prefailure" : "Old Age"),
+                                               8, good ? "OK" : "FAILURE",
+                                               -1);
+
+                                if (name == "reallocated-sector-count")
+                                        rsc = pretty_value;
+                                if (name == "reallocated-event-count")
+                                        rec = pretty_value;
+                                if (name == "current-pending-sector")
+                                        cps = pretty_value;
+                                if (name == "offline-uncorrectable")
+                                        ou = pretty_value;
+
+                                if (name == "temperature-celsius-1" ||
+                                    name == "temperature-celsius-2" ||
+                                    name == "airflow-temperature-celsius")
+                                        if (pretty_value > temp)
+                                                temp = pretty_value;
+
+                                if (name == "power-on-minutes" ||
+                                    name == "power-on-seconds" ||
+                                    name == "power-on-hours")
+                                        pon = pretty_value;
+                        }
+
+                        uint64 sectors = cps + ou + (rsc > rec ? rsc : rec);
+                        if (sectors > 0)
+                                ((Gtk.Label) get_object("badSectorsLabel")).set_markup("<b>Warning:</b> The disk reports to have %llu bad sectors.".printf(sectors));
+                        else
+                                ((Gtk.Label) get_object("badSectorsLabel")).set_label("The disk reports to have no bad sectors.");
+
+                        if (temp > 0)
+                                ((Gtk.Label) get_object("temperatureLabel")).set_label("The current temperature of the disk is %0.1f °C.".printf((double) (temp - 273150) / 1000));
                         else
-                                ((Gtk.Label) get_object("healthLabel")).set_label("Disk reports that it has already failed or is expected to fail in the next 24h.");
+                                ((Gtk.Label) get_object("temperatureLabel")).set_label("");
+
+
+                        if (pon > 0)
+                                ((Gtk.Label) get_object("powerOnLabel")).set_label("The disk has been powered on for %s.".printf(format_pretty(pon, "mseconds")));
+                        else
+                                ((Gtk.Label) get_object("powerOnLabel")).set_label("");
 
                         bool a = disk.getStartTestAvailable();
                         b = disk.getConveyanceTestAvailable();
                         bool c = disk.getShortAndExtendedTestAvailable();
 
                         if (a && (b || c))
-                                return fill_in_self_test_data();
+                                return fill_in_self_test_data(c, b);
                         else
                                 return fill_in_no_self_test_data();
 
@@ -155,7 +358,7 @@ public class DiskHealth : Gtk.Builder {
                 }
         }
 
-        public bool fill_in_self_test_data() {
+        public bool fill_in_self_test_data(bool sae, bool c) {
                 try {
                         bool show_percent = false;
                         string text;
@@ -191,7 +394,7 @@ public class DiskHealth : Gtk.Builder {
                                         text = "The previous self-test completed having a test element that failed and the device is suspected of having handling damage.";
                                         break;
                                 case "inprogress":
-                                        text = "Self-test in progres...";
+                                        text = "Self-test in progress...";
                                         show_percent = true;
                                         break;
 
@@ -200,7 +403,6 @@ public class DiskHealth : Gtk.Builder {
                                         break;
                         }
 
-
                         ((Gtk.Label) get_object("selfTestLabel")).set_label(text);
 
                         if (show_percent) {
@@ -208,11 +410,40 @@ public class DiskHealth : Gtk.Builder {
 
                                 ((Gtk.ProgressBar) get_object("selfTestProgressBar")).set_fraction((double) (100-percent)/100);
                                 ((Gtk.ProgressBar) get_object("selfTestProgressBar")).set_text("%u%% remaining".printf(percent));
-                        } else
+                        } else {
+                                ((Gtk.ProgressBar) get_object("selfTestProgressBar")).set_fraction(0.0);
                                 ((Gtk.ProgressBar) get_object("selfTestProgressBar")).set_text("n/a");
+                        }
 
                         ((Gtk.ProgressBar) get_object("selfTestProgressBar")).set_sensitive(show_percent);
 
+                        if (state == "inprogress") {
+                                ((Gtk.Button) get_object("selfTestButton")).set_label("Abort Self-Test");
+                                bool b = disk.getAbortTestAvailable();
+                                ((Gtk.Button) get_object("selfTestButton")).set_sensitive(b);
+
+                                this.test = "abort";
+
+                                if (sae)
+                                        this.refresh_time = disk.getShortTestPollingMinutes();
+                                else
+                                        this.refresh_time = disk.getConveyanceTestPollingMinutes();
+
+
+                        } else {
+                                uint saet, ct;
+
+                                ((Gtk.Button) get_object("selfTestButton")).set_label("Start Self-Test");
+                                ((Gtk.Button) get_object("selfTestButton")).set_sensitive(true);
+
+                                if (sae)
+                                        this.test = "short";
+                                else
+                                        this.test = "conveyance";
+
+                                this.refresh_time = 0;
+                        }
+
                 } catch (DBus.Error e) {
                         stderr.printf("D-Bus error: %s\n", e.message);
                         return false;
@@ -226,6 +457,7 @@ public class DiskHealth : Gtk.Builder {
                 ((Gtk.Button) get_object("selfTestButton")).set_sensitive(false);
                 ((Gtk.ProgressBar) get_object("selfTestProgressBar")).set_sensitive(false);
 
+                test = null;
                 return true;
         }
 
index 7e60403e4ad8d635b9bde057bd2bf155961b2989..1cbc41e0074852251b457dfd9f86e5000521d821 100644 (file)
@@ -85,13 +85,14 @@ public interface DiskAPI {
         public abstract uint getExtendedTestPollingMinutes() throws Error;
         public abstract uint getConveyanceTestPollingMinutes() throws Error;
 
-/*         public abstract DBus.ObjectPath[] getAttributes() throws Error; */
+        public abstract DBus.ObjectPath[] getAttributes() throws Error;
 }
 
 [DBus (name = "net.poettering.SmartKit.Manager")]
 public interface ManagerAPI {
         public abstract DBus.ObjectPath getDiskByUDI(string udi) throws Error;
         public abstract DBus.ObjectPath getDiskByPath(string path) throws Error;
+        public abstract DBus.ObjectPath[] getDisks() throws Error;
 }
 
 string clean_path(string s) {
@@ -114,7 +115,7 @@ public class Attribute : GLib.Object, AttributeAPI {
         public Disk disk { get; construct; }
         public DBus.Connection connection { get; construct; }
 
-        public uint8 id;
+        public uint8 _id;
         public string name;
         public SmartAttributeUnit pretty_unit;
         public uint8 threshold;
@@ -132,7 +133,7 @@ public class Attribute : GLib.Object, AttributeAPI {
         }
 
         public void set(SmartAttributeParsedData a) {
-                id = a.id;
+                _id = a.id;
                 name = a.name;
                 pretty_unit = a.pretty_unit;
                 threshold = a.threshold;
@@ -153,7 +154,7 @@ public class Attribute : GLib.Object, AttributeAPI {
         }
 
         public uint8 getId() throws Error {
-                return id;
+                return _id;
         }
 
         public string getName() throws Error {
@@ -169,10 +170,12 @@ public class Attribute : GLib.Object, AttributeAPI {
                                 return "none";
                         case SmartAttributeUnit.MSECONDS:
                                 return "mseconds";
+                        case SmartAttributeUnit.SECTORS:
+                                return "sectors";
                         case SmartAttributeUnit.MKELVIN:
                                 return "mkelvin";
                         default:
-                                throw new Error.UNKNOWN_UNIT("Unit unknown.");
+                                throw new Error.UNKNOWN_UNIT("Unit unknown %i.", pretty_unit);
                 }
         }
 
@@ -245,6 +248,12 @@ public class Disk : GLib.Object, DiskAPI {
         }
 
         private void attribute_callback(void* disk, SmartAttributeParsedData a) {
+                foreach (Attribute attr in attributes)
+                        if (attr._id == a.id) {
+                                attr.set(a);
+                                return;
+                        }
+
                 Attribute attr;
 
                 attr = new Attribute(this, this.connection);
@@ -350,9 +359,11 @@ public class Disk : GLib.Object, DiskAPI {
 
                 if (this.disk.smart_read_data() < 0)
                         throw new Error.SYSTEM("smart_read_data() failed: %s", Smart.strerror(Smart.errno));
+
+                populate_attributes();
         }
 
-        public void startSelfTest(string test) {
+        public void startSelfTest(string test) throws Error {
                 SmartSelfTest t;
 
                 switch (test) {
@@ -373,7 +384,7 @@ public class Disk : GLib.Object, DiskAPI {
                         throw new Error.SYSTEM("smart_self_test() failed: %s", Smart.strerror(Smart.errno));
         }
 
-        public void abortSelfTest() {
+        public void abortSelfTest() throws Error {
 
                 if (this.disk.smart_self_test(SmartSelfTest.ABORT) < 0)
                         throw new Error.SYSTEM("smart_self_test() failed: %s", Smart.strerror(Smart.errno));
@@ -517,6 +528,18 @@ public class Disk : GLib.Object, DiskAPI {
                 return d->conveyance_test_polling_minutes;
         }
 
+        public DBus.ObjectPath[] getAttributes() throws Error {
+                DBus.ObjectPath[] p = new DBus.ObjectPath[attributes.length()];
+
+                int i = 0;
+                foreach (Attribute a in attributes) {
+                        p[i++] = new DBus.ObjectPath(a.dbus_path);
+                }
+
+                return p;
+        }
+
+
 /*     public uint64 size { */
 /*         get { */
 /*             uint64 s; */
@@ -581,6 +604,18 @@ public class Manager : GLib.Object, ManagerAPI {
 
                 throw new Error.NOT_FOUND("Device not found");
         }
+
+        public DBus.ObjectPath[] getDisks() throws Error {
+                DBus.ObjectPath[] p = new DBus.ObjectPath[disks.length()];
+
+                int i = 0;
+                foreach (Disk d in disks) {
+                        p[i++] = new DBus.ObjectPath(d.dbus_path);
+                }
+
+                return p;
+        }
+
 }
 
 int main() {