コード例 #1
0
    def __init__(self, parent):
        self.ind_parent = parent
        self._list_store = Gtk.ListStore(str, str)
        self._tree_view = Gtk.TreeView(self._list_store)

        self.sensor_mgr = SensorManager()
        self.sensor_mgr.fill_liststore(self._list_store)
コード例 #2
0
    def __init__(self):
        self._preferences_dialog = None
        self._help_dialog = None

        #fn, self.tindicator = tempfile.mkstemp(suffix=".svg")

        #with open(self.tindicator, "w") as f:
        #    svg = '<?xml version="1.0" encoding="UTF-8" \
        #                standalone="no"?><svg id="empty" xmlns="http://www.w3.org/2000/svg" \
        #                height="22" width="1" version="1.0" \
        #                xmlns:xlink="http://www.w3.org/1999/xlink"></svg>'
        #    f.write(svg)
        #    f.close()

        #self.ind = appindicator.Indicator.new("indicator-sysmonitor", self.tindicator, \
        #                                      appindicator.IndicatorCategory.SYSTEM_SERVICES)
        self.ind = Gtk.Button.new()
        #self.ind.set_ordering_index(0)

        #self.ind.set_status(appindicator.IndicatorStatus.ACTIVE)
        self.ind.set_label("Init...")

        self._create_menu()

        self.alive = Event()
        self.alive.set()

        self.sensor_mgr = SensorManager()
        self.load_settings()
コード例 #3
0
    def __init__(self):
        self._preferences_dialog = None
        self._help_dialog = None

        self.ind = Gtk.Button.new()
        self.ind.set_label("Init...")

        self._create_menu()

        self.alive = Event()
        self.alive.set()

        self.sensor_mgr = SensorManager()
        self.load_settings()
コード例 #4
0
    def __init__(self, uuid):
        Budgie.Applet.__init__(self)

        # Add a button to our UI
        logging.info("start")

        if not os.path.exists(SensorManager.SETTINGS_FILE):
            sensor_mgr = SensorManager()
            sensor_mgr.save_settings()
        
        self.app = IndicatorSysmonitor()
        self.button = self.app.ind
        self.button.set_relief(Gtk.ReliefStyle.NONE)
        self.add(self.button)
        self.show_all()
コード例 #5
0
    def __init__(self, uuid):
        Budgie.Applet.__init__(self)

        # Add a button to our UI
        logging.info("start")

        if not os.path.exists(SensorManager.SETTINGS_FILE):
            sensor_mgr = SensorManager()
            sensor_mgr.save_settings()

        self.app = IndicatorSysmonitor()
        self.button = self.app.ind
        self.button.set_relief(Gtk.ReliefStyle.NONE)
        self.add(self.button)
        self.show_all()
コード例 #6
0
    def __init__(self, parent):
        """It creates the widget of the dialogs"""
        Gtk.Dialog.__init__(self)
        self.ind_parent = parent
        self.custom_entry = None
        self.interval_entry = None
        self.sensor_mgr = SensorManager()
        self._create_content()
        self.set_data()
        self.show_all()

        # not implemented yet - just hide
        self.display_icon_checkbutton.set_visible(False)
        self.iconpath_button.set_visible(False)
        self.iconpath_entry.set_visible(False)
コード例 #7
0
    def __init__(self):
        self._preferences_dialog = None
        self._help_dialog = None

        #fn, self.tindicator = tempfile.mkstemp(suffix=".svg")

        #with open(self.tindicator, "w") as f:
        #    svg = '<?xml version="1.0" encoding="UTF-8" \
        #                standalone="no"?><svg id="empty" xmlns="http://www.w3.org/2000/svg" \
        #                height="22" width="1" version="1.0" \
        #                xmlns:xlink="http://www.w3.org/1999/xlink"></svg>'
        #    f.write(svg)
        #    f.close()

        #self.ind = appindicator.Indicator.new("indicator-sysmonitor", self.tindicator, \
        #                                      appindicator.IndicatorCategory.SYSTEM_SERVICES)
        self.ind = Gtk.Button.new()
        #self.ind.set_ordering_index(0)

        #self.ind.set_status(appindicator.IndicatorStatus.ACTIVE)
        self.ind.set_label("Init...")

        self._create_menu()

        self.alive = Event()
        self.alive.set()

        self.sensor_mgr = SensorManager()
        self.load_settings()
コード例 #8
0
    def __init__(self, parent):
        self.ind_parent = parent
        self._list_store = Gtk.ListStore(str, str)
        self._tree_view = Gtk.TreeView(self._list_store)

        self.sensor_mgr = SensorManager()
        self.sensor_mgr.fill_liststore(self._list_store)
コード例 #9
0
 def __init__(self, parent):
     """It creates the widget of the dialogs"""
     Gtk.Dialog.__init__(self)
     self.ind_parent = parent
     self.custom_entry = None
     self.interval_entry = None
     self.sensor_mgr = SensorManager()
     self._create_content()
     self.set_data()
     self.show_all()
コード例 #10
0
    def __init__(self):
        self._preferences_dialog = None
        self._help_dialog = None

        self.ind = Gtk.Button.new()
        self.ind.set_label("Init...")

        self._create_menu()

        self.alive = Event()
        self.alive.set()

        self.sensor_mgr = SensorManager()
        self.load_settings()
コード例 #11
0
    def __init__(self, parent):
        """It creates the widget of the dialogs"""
        Gtk.Dialog.__init__(self)
        self.ind_parent = parent
        self.custom_entry = None
        self.interval_entry = None
        self.sensor_mgr = SensorManager()
        self._create_content()
        self.set_data()
        self.show_all()

        # not implemented yet - just hide
        self.display_icon_checkbutton.set_visible(False)
        self.iconpath_button.set_visible(False)
        self.iconpath_entry.set_visible(False)
コード例 #12
0
# App setup
app = Flask(__name__)
app.config['SECRET_KEY'] = 'secret!'
app.logger.disabled = True
socketio = SocketIO(app, async_mode=async_mode)
thread = None
thread_lock = Lock()

namespace = '/socket'

# Other setup
start_time = time.time()

valve_manager = ValveManager()
sensor_manager = SensorManager()


def client_tester():
    i = 0
    while True:
        # TODO: Add better client test
        # Code to test Client
        send_log_data('Hello World!')
        send_sensor_data(
            sensor_manager.get_sensor_by_name("Pressure Sensor 1"))
        send_sensor_data(
            sensor_manager.get_sensor_by_name("Temperature Sensor 1"))
        # socketio.emit('sensor_data', {'time': time.time() - start_time,
        #                               'name': 'sensor1',
        #                               'value': i})
コード例 #13
0
class SensorsListModel(object):
    """A TreeView showing the available sensors. It allows to
    add/edit/delete custom sensors."""

    def __init__(self, parent):
        self.ind_parent = parent
        self._list_store = Gtk.ListStore(str, str)
        self._tree_view = Gtk.TreeView(self._list_store)

        self.sensor_mgr = SensorManager()
        self.sensor_mgr.fill_liststore(self._list_store)

    def get_view(self):
        """It's called from Preference. It creates the view and returns it"""
        vbox = Gtk.VBox(False, 3)
        # create columns
        renderer = Gtk.CellRendererText()
        renderer.set_property('editable', False)
        column = Gtk.TreeViewColumn(_('Sensor'), renderer, text=0)
        self._tree_view.append_column(column)

        renderer = Gtk.CellRendererText()
        renderer.set_property('editable', False)
        column = Gtk.TreeViewColumn(_('Description'), renderer, text=1)
        self._tree_view.append_column(column)

        self._tree_view.expand_all()
        sw = Gtk.ScrolledWindow()
        sw.add_with_viewport(self._tree_view)
        vbox.pack_start(sw, True, True, 0)

        # add buttons
        hbox = Gtk.HBox()
        new_button = Gtk.Button.new_from_stock(Gtk.STOCK_NEW)
        new_button.connect('clicked', self._on_edit_sensor)
        hbox.pack_start(new_button, False, False, 0)

        edit_button = Gtk.Button.new_from_stock(Gtk.STOCK_EDIT)
        edit_button.connect('clicked', self._on_edit_sensor, False)
        hbox.pack_start(edit_button, False, False, 1)

        del_button = Gtk.Button.new_from_stock(Gtk.STOCK_DELETE)
        del_button.connect('clicked', self._on_del_sensor)
        hbox.pack_start(del_button, False, False, 2)

        add_button = Gtk.Button.new_from_stock(Gtk.STOCK_ADD)
        add_button.connect('clicked', self._on_add_sensor)
        hbox.pack_end(add_button, False, False, 3)
        vbox.pack_end(hbox, False, False, 1)

        frame = Gtk.Frame.new(_('Sensors'))
        frame.add(vbox)
        return frame

    def _get_selected_row(self):
        """Returns an iter for the selected rows in the view or None."""
        model, pathlist = self._tree_view.get_selection().get_selected_rows()
        if len(pathlist):
            path = pathlist.pop()
            return model.get_iter(path)
        return None

    def _on_add_sensor(self, evnt=None, data=None):
        tree_iter = self._get_selected_row()
        if tree_iter is None:
            return

        sensor = self._list_store.get_value(tree_iter, 0)
        self.ind_parent.custom_entry.insert_text(
            "{{{}}}".format(sensor), -1)

    def _on_edit_sensor(self, evnt=None, blank=True):
        """Raises a dialog with a form to add/edit a sensor"""
        name = desc = cmd = ""
        tree_iter = None
        if not blank:
            # edit, so get the info from the selected row
            tree_iter = self._get_selected_row()
            if tree_iter is None:
                return

            name = self._list_store.get_value(tree_iter, 0)
            desc = self._list_store.get_value(tree_iter, 1)
            cmd = self.sensor_mgr.get_command(name)

            if cmd is True:  # default sensor
                raise_dialog(
                    self.ind_parent,
                    Gtk.DialogFlags.DESTROY_WITH_PARENT | Gtk.DialogFlags.MODAL,
                    Gtk.MessageType.ERROR, Gtk.ButtonsType.OK,
                    _("Can not edit the default sensors."), _("Error"))
                return

        dialog = Gtk.Dialog(_("Edit Sensor"), self.ind_parent,
                            Gtk.DialogFlags.MODAL | Gtk.DialogFlags.DESTROY_WITH_PARENT,
                            (Gtk.STOCK_CANCEL, Gtk.ResponseType.REJECT,
                             Gtk.STOCK_OK, Gtk.ResponseType.ACCEPT))
        vbox = dialog.get_content_area()

        hbox = Gtk.HBox()
        label = Gtk.Label(_("Sensor"))
        sensor_entry = Gtk.Entry()
        sensor_entry.set_text(name)
        hbox.pack_start(label, False, False, 0)
        hbox.pack_end(sensor_entry, False, False, 1)
        vbox.pack_start(hbox, False, False, 0)

        hbox = Gtk.HBox()
        label = Gtk.Label(_("Description"))
        desc_entry = Gtk.Entry()
        desc_entry.set_text(desc)
        hbox.pack_start(label, False, False, 0)
        hbox.pack_end(desc_entry, False, False, 1)
        vbox.pack_start(hbox, False, False, 1)

        hbox = Gtk.HBox()
        label = Gtk.Label(_("Command"))
        cmd_entry = Gtk.Entry()

        cmd_entry.set_text(cmd)
        hbox.pack_start(label, False, False, 0)
        hbox.pack_end(cmd_entry, False, False, 1)
        vbox.pack_end(hbox, False, False, 2)

        dialog.show_all()
        response = dialog.run()

        if response == Gtk.ResponseType.ACCEPT:
            try:
                newname, desc, cmd = str(sensor_entry.get_text()), \
                                     str(desc_entry.get_text()), str(cmd_entry.get_text())

                if blank:
                    self.sensor_mgr.add(newname, desc, cmd)
                else:
                    self.sensor_mgr.edit(name, newname, desc, cmd)
                    self._list_store.remove(tree_iter)

                self._list_store.append([newname, desc])
                # issue 3: why we are doing a character replacement when clicking
                # new - who knows ... lets just comment this out
                # ctext = self.ind_parent.custom_entry.get_text()

                # self.ind_parent.custom_entry.set_text(
                #    ctext.replace(name, newname))

            except ISMError as ex:
                raise_dialog(
                    self.ind_parent,
                    Gtk.DialogFlags.DESTROY_WITH_PARENT | Gtk.DialogFlags.MODAL,
                    Gtk.MessageType.ERROR, Gtk.ButtonsType.OK,
                    ex, _("Error"))

        dialog.destroy()

    def _on_del_sensor(self, evnt=None, data=None):
        """Remove a custom sensor."""
        tree_iter = self._get_selected_row()
        if tree_iter is None:
            return

        name = self._list_store.get_value(tree_iter, 0)
        try:
            self.sensor_mgr.delete(name)
            self._list_store.remove(tree_iter)
            ctext = self.ind_parent.custom_entry.get_text()
            self.ind_parent.custom_entry.set_text(
                ctext.replace("{{{}}}".format(name), ""))

        except ISMError as ex:
            raise_dialog(
                self.ind_parent,
                Gtk.DialogFlags.DESTROY_WITH_PARENT | Gtk.DialogFlags.MODAL,
                Gtk.MessageType.ERROR, Gtk.ButtonsType.OK,
                ex, _("Error"))
コード例 #14
0
class Preferences(Gtk.Dialog):
    """It define the the Preferences Dialog and its operations."""
    AUTOSTART_DIR = '{}/.config/autostart' \
        .format(os.getenv("HOME"))
    AUTOSTART_PATH = '{}/.config/autostart/indicator-sysmonitor.desktop' \
        .format(os.getenv("HOME"))
    DESKTOP_PATH = '/usr/share/applications/indicator-sysmonitor.desktop'
    sensors_regex = re.compile("{.+?}")

    SETTINGS_FILE = os.getenv("HOME") + '/.cache/indicator-sysmonitor/preferences.json'
    settings = {}

    def __init__(self, parent):
        """It creates the widget of the dialogs"""
        Gtk.Dialog.__init__(self)
        self.ind_parent = parent
        self.custom_entry = None
        self.interval_entry = None
        self.sensor_mgr = SensorManager()
        self._create_content()
        self.set_data()
        self.show_all()

        # not implemented yet - just hide
        self.display_icon_checkbutton.set_visible(False)
        self.iconpath_button.set_visible(False)
        self.iconpath_entry.set_visible(False)

    def _create_content(self):
        """It creates the content for this dialog."""
        self.connect('delete-event', self.on_cancel)
        self.set_title(_('Preferences'))
        self.set_size_request(600, 600)
        self.set_position(Gtk.WindowPosition.CENTER_ALWAYS)

        ui = Gtk.Builder()
        file_path = os.path.dirname(os.path.abspath(__file__))
        ui.add_from_file(file_path + '/preferences.ui')
        self.autostart_check = ui.get_object('autostart_check')
        self.autostart_check.set_active(self.get_autostart())
        version_label = ui.get_object('version_label')
        version_label.set_label(_('This is indicator-sysmonitor version: {}').format(VERSION))
        self.custom_entry = ui.get_object('custom_entry')
        self.interval_entry = ui.get_object('interval_entry')

        self.display_icon_checkbutton = ui.get_object('display_icon_checkbutton')
        self.iconpath_entry = ui.get_object('iconpath_entry')
        self.iconpath_button = ui.get_object('iconpath_button')

        sensors_list = SensorsListModel(self)
        vbox = ui.get_object('advanced_box')
        vbox.pack_start(sensors_list.get_view(), True, True, 3)

        # footer {{{
        vbox = self.get_content_area()
        notebook = ui.get_object('preferences_notebook')
        vbox.pack_start(notebook, True, True, 4)
        handlers = {
            "on_test": self.on_test,
            "on_save": self.on_save,
            "on_cancel": self.on_cancel
        }
        ui.connect_signals(handlers)
        buttons = ui.get_object('footer_buttonbox')
        vbox.pack_end(buttons, False, False, 5)
        # }}}
        
        self.set_resizable(False)

    def save_prefs(self):
            """It stores the current settings to the config file."""

            try:
                os.makedirs(os.path.dirname(Preferences.PREF_SETTINGS_FILE), exist_ok=True)
                with open(Preferences.PREF_SETTINGS_FILE, 'w') as f:
                    f.write(json.dumps(self.pref_settings))

            except Exception as ex:
                logging.exception(ex)
                logging.error('Writing settings failed')

    def load_settings(self):
            """It gets the settings from the config file and
            sets them to the correct vars"""
            try:
                with open(Preferences.PREF.SETTINGS_FILE, 'r') as f:
                    self.settings = json.load(f)

            except Exception as ex:
                logging.exception(ex)
                logging.error('Reading settings failed')

    def on_iconpath_button_clicked(self, *args):
        pass

    def on_display_icon_checkbutton_toggled(self, *args):
        if not self.display_icon_checkbutton.get_active():
            self.iconpath_entry.set_text('')
            self.iconpath_entry.set_sensitive(False)
            self.iconpath_button.set_sensitive(False)
        else:
            self.iconpath_entry.set_sensitive(True)
            self.iconpath_button.set_sensitive(True)

    def on_test(self, evnt=None, data=None):
        """The action of the test button."""
        try:
            self.update_parent()
        except Exception as ex:
            error_dialog = Gtk.MessageDialog(
                None, Gtk.DialogFlags.DESTROY_WITH_PARENT, Gtk.MessageType.ERROR,
                Gtk.ButtonsType.CLOSE, ex)
            error_dialog.set_title("Error")
            error_dialog.run()
            error_dialog.destroy()
            return False

    def on_save(self, evnt=None, data=None):
        """The action of the save button."""
        try:
            self.update_parent()
        except Exception as ex:
            error_dialog = Gtk.MessageDialog(
                None, Gtk.DialogFlags.DESTROY_WITH_PARENT, Gtk.MessageType.ERROR,
                Gtk.ButtonsType.CLOSE, ex)
            error_dialog.set_title("Error")
            error_dialog.run()
            error_dialog.destroy()
            return False

        self.ind_parent.save_settings()
        self.update_autostart()
        self.destroy()

    def on_cancel(self, evnt=None, data=None):
        """The action of the cancel button."""
        self.ind_parent.load_settings()
        self.destroy()

    def update_parent(self, evnt=None, data=None):
        """It gets the config info from the widgets and sets them to the vars.
        It does NOT update the config file."""
        custom_text = self.custom_entry.get_text()

        # check if the sensors are supported
        sensors = Preferences.sensors_regex.findall(custom_text)
        for sensor in sensors:
            sensor = sensor[1:-1]
            if not self.sensor_mgr.exists(sensor):
                raise ISMError(_("{{{}}} sensor not supported.").
                               format(sensor))
            # Check if the sensor is well-formed
            self.sensor_mgr.check(sensor)

        try:
            interval = float(self.interval_entry.get_text())
            if interval <= 0:
                raise ISMError(_("Interval value is not valid."))

        except ValueError:
            raise ISMError(_("Interval value is not valid."))

        self.sensor_mgr.set_custom_text(custom_text)
        self.sensor_mgr.set_interval(interval)
        # settings["custom_text"] = custom_text
        # settings["interval"] = interval
        # TODO: on_startup
        self.ind_parent.update_indicator_guide()

    def set_data(self):
        """It sets the widgets with the config data."""
        self.custom_entry.set_text(self.sensor_mgr.get_custom_text())
        self.interval_entry.set_text(str(self.sensor_mgr.get_interval()))

    def update_autostart(self):
        autostart = self.autostart_check.get_active()
        if not autostart:
            try:
                os.remove(Preferences.AUTOSTART_PATH)
            except:
                pass
        else:
            try:
                if not os.path.exists(Preferences.AUTOSTART_DIR):
                    os.makedirs(Preferences.AUTOSTART_DIR)

                shutil.copy(Preferences.DESKTOP_PATH,
                            Preferences.AUTOSTART_PATH)
            except Exception as ex:
                logging.exception(ex)

    def get_autostart(self):
        return os.path.exists(Preferences.AUTOSTART_PATH)
コード例 #15
0
class BaseStation():
    def __init__(self):
        """
        1) Establish link with IOT Hub
        2) Request for farm data
        3) Initialize sensor threads and handlers
        4) Wait for remote invocations and deliver them to the correct handler
        """
        self._init_azure()
        self._load_sensor_manager()
        self._establish_incoming_link()
        self._load_farm_data()
        self._init_sensors()
        self._idle()

    def _init_azure(self):
        """
        Azure SDK methods are wrapped by these helper classes
        """
        self._hub = IoTHubWrapper()

    def _load_sensor_manager(self):
        """
        Sensors are managed by the SensorManager. On init, the module loads list of sensor mappings 
        (ID, sensor type) from cosmos via the Hub
        """
        self._sensor_manager = SensorManager(self._hub)

    def _establish_incoming_link(self):
        """
        A separate thread starts listening for method invocations indefinitely
        """
        self._listen_thread = self._hub.listen_indefinitely(
            self._remote_method_handler)

    def _remote_method_handler(self, message):
        """
        Do something based on input from cloud (called from indefinite listener)
        """
        {
            "FLY_DRONE": self._sensor_manager.dispatch(message),
        }[message.event]

    def _load_farm_data(self):
        """
        Load all farm related data from the cloud
        Note that this is not a synchronus request and is serviced by the listen thread separately
        We enforce an abstracted synchronus behaviour
        """
        message = RequestMessage('FARM_DATA_LOAD', {})
        response = self._hub.request_from_hub(message)

        farm.initialize(response.data)

    def _init_sensors(self):
        """
        Based on the fetched farm data, initialize sensors
        """
        self._sensor_manager.init_sensors()

    def _idle(self):
        """
        Main control finally idles here. ctrl + c to end.
        """
        logger.info("Close window to end at any time to end simulation")
        try:
            self._listen_thread.join()
        except KeyboardInterrupt:
            logger.info("Ending simulations")
コード例 #16
0
class SensorsListModel(object):
    """A TreeView showing the available sensors. It allows to
    add/edit/delete custom sensors."""
    def __init__(self, parent):
        self.ind_parent = parent
        self._list_store = Gtk.ListStore(str, str)
        self._tree_view = Gtk.TreeView(self._list_store)

        self.sensor_mgr = SensorManager()
        self.sensor_mgr.fill_liststore(self._list_store)

    def get_view(self):
        """It's called from Preference. It creates the view and returns it"""
        vbox = Gtk.VBox(False, 3)
        # create columns
        renderer = Gtk.CellRendererText()
        renderer.set_property('editable', False)
        column = Gtk.TreeViewColumn(_('Sensor'), renderer, text=0)
        self._tree_view.append_column(column)

        renderer = Gtk.CellRendererText()
        renderer.set_property('editable', False)
        column = Gtk.TreeViewColumn(_('Description'), renderer, text=1)
        self._tree_view.append_column(column)

        self._tree_view.expand_all()
        sw = Gtk.ScrolledWindow()
        sw.add_with_viewport(self._tree_view)
        vbox.pack_start(sw, True, True, 0)

        # add buttons
        hbox = Gtk.HBox()
        new_button = Gtk.Button.new_from_stock(Gtk.STOCK_NEW)
        new_button.connect('clicked', self._on_edit_sensor)
        hbox.pack_start(new_button, False, False, 0)

        edit_button = Gtk.Button.new_from_stock(Gtk.STOCK_EDIT)
        edit_button.connect('clicked', self._on_edit_sensor, False)
        hbox.pack_start(edit_button, False, False, 1)

        del_button = Gtk.Button.new_from_stock(Gtk.STOCK_DELETE)
        del_button.connect('clicked', self._on_del_sensor)
        hbox.pack_start(del_button, False, False, 2)

        add_button = Gtk.Button.new_from_stock(Gtk.STOCK_ADD)
        add_button.connect('clicked', self._on_add_sensor)
        hbox.pack_end(add_button, False, False, 3)
        vbox.pack_end(hbox, False, False, 1)

        frame = Gtk.Frame.new(_('Sensors'))
        frame.add(vbox)
        return frame

    def _get_selected_row(self):
        """Returns an iter for the selected rows in the view or None."""
        model, pathlist = self._tree_view.get_selection().get_selected_rows()
        if len(pathlist):
            path = pathlist.pop()
            return model.get_iter(path)
        return None

    def _on_add_sensor(self, evnt=None, data=None):
        tree_iter = self._get_selected_row()
        if tree_iter is None:
            return

        sensor = self._list_store.get_value(tree_iter, 0)
        self.ind_parent.custom_entry.insert_text("{{{}}}".format(sensor), -1)

    def _on_edit_sensor(self, evnt=None, blank=True):
        """Raises a dialog with a form to add/edit a sensor"""
        name = desc = cmd = ""
        tree_iter = None
        if not blank:
            # edit, so get the info from the selected row
            tree_iter = self._get_selected_row()
            if tree_iter is None:
                return

            name = self._list_store.get_value(tree_iter, 0)
            desc = self._list_store.get_value(tree_iter, 1)
            cmd = self.sensor_mgr.get_command(name)

            if cmd is True:  # default sensor
                raise_dialog(
                    self.ind_parent, Gtk.DialogFlags.DESTROY_WITH_PARENT
                    | Gtk.DialogFlags.MODAL, Gtk.MessageType.ERROR,
                    Gtk.ButtonsType.OK, _("Can not edit the default sensors."),
                    _("Error"))
                return

        dialog = Gtk.Dialog(
            _("Edit Sensor"), self.ind_parent,
            Gtk.DialogFlags.MODAL | Gtk.DialogFlags.DESTROY_WITH_PARENT,
            (Gtk.STOCK_CANCEL, Gtk.ResponseType.REJECT, Gtk.STOCK_OK,
             Gtk.ResponseType.ACCEPT))
        vbox = dialog.get_content_area()

        hbox = Gtk.HBox()
        label = Gtk.Label(_("Sensor"))
        sensor_entry = Gtk.Entry()
        sensor_entry.set_text(name)
        hbox.pack_start(label, False, False, 0)
        hbox.pack_end(sensor_entry, False, False, 1)
        vbox.pack_start(hbox, False, False, 0)

        hbox = Gtk.HBox()
        label = Gtk.Label(_("Description"))
        desc_entry = Gtk.Entry()
        desc_entry.set_text(desc)
        hbox.pack_start(label, False, False, 0)
        hbox.pack_end(desc_entry, False, False, 1)
        vbox.pack_start(hbox, False, False, 1)

        hbox = Gtk.HBox()
        label = Gtk.Label(_("Command"))
        cmd_entry = Gtk.Entry()

        cmd_entry.set_text(cmd)
        hbox.pack_start(label, False, False, 0)
        hbox.pack_end(cmd_entry, False, False, 1)
        vbox.pack_end(hbox, False, False, 2)

        dialog.show_all()
        response = dialog.run()

        if response == Gtk.ResponseType.ACCEPT:
            try:
                newname, desc, cmd = str(sensor_entry.get_text()), \
                                     str(desc_entry.get_text()), str(cmd_entry.get_text())

                if blank:
                    self.sensor_mgr.add(newname, desc, cmd)
                else:
                    self.sensor_mgr.edit(name, newname, desc, cmd)
                    self._list_store.remove(tree_iter)

                self._list_store.append([newname, desc])
                # issue 3: why we are doing a character replacement when clicking
                # new - who knows ... lets just comment this out
                # ctext = self.ind_parent.custom_entry.get_text()

                # self.ind_parent.custom_entry.set_text(
                #    ctext.replace(name, newname))

            except ISMError as ex:
                raise_dialog(
                    self.ind_parent, Gtk.DialogFlags.DESTROY_WITH_PARENT
                    | Gtk.DialogFlags.MODAL, Gtk.MessageType.ERROR,
                    Gtk.ButtonsType.OK, ex, _("Error"))

        dialog.destroy()

    def _on_del_sensor(self, evnt=None, data=None):
        """Remove a custom sensor."""
        tree_iter = self._get_selected_row()
        if tree_iter is None:
            return

        name = self._list_store.get_value(tree_iter, 0)
        try:
            self.sensor_mgr.delete(name)
            self._list_store.remove(tree_iter)
            ctext = self.ind_parent.custom_entry.get_text()
            self.ind_parent.custom_entry.set_text(
                ctext.replace("{{{}}}".format(name), ""))

        except ISMError as ex:
            raise_dialog(
                self.ind_parent,
                Gtk.DialogFlags.DESTROY_WITH_PARENT | Gtk.DialogFlags.MODAL,
                Gtk.MessageType.ERROR, Gtk.ButtonsType.OK, ex, _("Error"))
コード例 #17
0
 def _load_sensor_manager(self):
     """
     Sensors are managed by the SensorManager. On init, the module loads list of sensor mappings 
     (ID, sensor type) from cosmos via the Hub
     """
     self._sensor_manager = SensorManager(self._hub)
コード例 #18
0
class Preferences(Gtk.Dialog):
    """It define the the Preferences Dialog and its operations."""
    AUTOSTART_DIR = '{}/.config/autostart' \
        .format(os.getenv("HOME"))
    AUTOSTART_PATH = '{}/.config/autostart/indicator-sysmonitor.desktop' \
        .format(os.getenv("HOME"))
    DESKTOP_PATH = '/usr/share/applications/indicator-sysmonitor.desktop'
    sensors_regex = re.compile("{.+?}")

    SETTINGS_FILE = os.getenv(
        "HOME") + '/.cache/indicator-sysmonitor/preferences.json'
    settings = {}

    def __init__(self, parent):
        """It creates the widget of the dialogs"""
        Gtk.Dialog.__init__(self)
        self.ind_parent = parent
        self.custom_entry = None
        self.interval_entry = None
        self.sensor_mgr = SensorManager()
        self._create_content()
        self.set_data()
        self.show_all()

        # not implemented yet - just hide
        self.display_icon_checkbutton.set_visible(False)
        self.iconpath_button.set_visible(False)
        self.iconpath_entry.set_visible(False)

    def _create_content(self):
        """It creates the content for this dialog."""
        self.connect('delete-event', self.on_cancel)
        self.set_title(_('Preferences'))
        self.set_size_request(600, 600)
        self.set_position(Gtk.WindowPosition.CENTER_ALWAYS)

        ui = Gtk.Builder()
        file_path = os.path.dirname(os.path.abspath(__file__))
        ui.add_from_file(file_path + '/preferences.ui')
        self.autostart_check = ui.get_object('autostart_check')
        self.autostart_check.set_active(self.get_autostart())
        version_label = ui.get_object('version_label')
        version_label.set_label(
            _('This is indicator-sysmonitor version: {}').format(VERSION))
        self.custom_entry = ui.get_object('custom_entry')
        self.interval_entry = ui.get_object('interval_entry')

        self.display_icon_checkbutton = ui.get_object(
            'display_icon_checkbutton')
        self.iconpath_entry = ui.get_object('iconpath_entry')
        self.iconpath_button = ui.get_object('iconpath_button')

        sensors_list = SensorsListModel(self)
        vbox = ui.get_object('advanced_box')
        vbox.pack_start(sensors_list.get_view(), True, True, 3)

        # footer {{{
        vbox = self.get_content_area()
        notebook = ui.get_object('preferences_notebook')
        vbox.pack_start(notebook, True, True, 4)
        handlers = {
            "on_test": self.on_test,
            "on_save": self.on_save,
            "on_cancel": self.on_cancel
        }
        ui.connect_signals(handlers)
        buttons = ui.get_object('footer_buttonbox')
        vbox.pack_end(buttons, False, False, 5)
        # }}}

        self.set_resizable(False)

    def save_prefs(self):
        """It stores the current settings to the config file."""

        try:
            os.makedirs(os.path.dirname(Preferences.PREF_SETTINGS_FILE),
                        exist_ok=True)
            with open(Preferences.PREF_SETTINGS_FILE, 'w') as f:
                f.write(json.dumps(self.pref_settings))

        except Exception as ex:
            logging.exception(ex)
            logging.error('Writing settings failed')

    def load_settings(self):
        """It gets the settings from the config file and
            sets them to the correct vars"""
        try:
            with open(Preferences.PREF.SETTINGS_FILE, 'r') as f:
                self.settings = json.load(f)

        except Exception as ex:
            logging.exception(ex)
            logging.error('Reading settings failed')

    def on_iconpath_button_clicked(self, *args):
        pass

    def on_display_icon_checkbutton_toggled(self, *args):
        if not self.display_icon_checkbutton.get_active():
            self.iconpath_entry.set_text('')
            self.iconpath_entry.set_sensitive(False)
            self.iconpath_button.set_sensitive(False)
        else:
            self.iconpath_entry.set_sensitive(True)
            self.iconpath_button.set_sensitive(True)

    def on_test(self, evnt=None, data=None):
        """The action of the test button."""
        try:
            self.update_parent()
        except Exception as ex:
            error_dialog = Gtk.MessageDialog(
                None, Gtk.DialogFlags.DESTROY_WITH_PARENT,
                Gtk.MessageType.ERROR, Gtk.ButtonsType.CLOSE, ex)
            error_dialog.set_title("Error")
            error_dialog.run()
            error_dialog.destroy()
            return False

    def on_save(self, evnt=None, data=None):
        """The action of the save button."""
        try:
            self.update_parent()
        except Exception as ex:
            error_dialog = Gtk.MessageDialog(
                None, Gtk.DialogFlags.DESTROY_WITH_PARENT,
                Gtk.MessageType.ERROR, Gtk.ButtonsType.CLOSE, ex)
            error_dialog.set_title("Error")
            error_dialog.run()
            error_dialog.destroy()
            return False

        self.ind_parent.save_settings()
        self.update_autostart()
        self.destroy()

    def on_cancel(self, evnt=None, data=None):
        """The action of the cancel button."""
        self.ind_parent.load_settings()
        self.destroy()

    def update_parent(self, evnt=None, data=None):
        """It gets the config info from the widgets and sets them to the vars.
        It does NOT update the config file."""
        custom_text = self.custom_entry.get_text()

        # check if the sensors are supported
        sensors = Preferences.sensors_regex.findall(custom_text)
        for sensor in sensors:
            sensor = sensor[1:-1]
            if not self.sensor_mgr.exists(sensor):
                raise ISMError(
                    _("{{{}}} sensor not supported.").format(sensor))
            # Check if the sensor is well-formed
            self.sensor_mgr.check(sensor)

        try:
            interval = int(self.interval_entry.get_text())
            if interval <= 0:
                raise ISMError(_("Interval value is not valid."))

        except ValueError:
            raise ISMError(_("Interval value is not valid."))

        self.sensor_mgr.set_custom_text(custom_text)
        self.sensor_mgr.set_interval(interval)
        # settings["custom_text"] = custom_text
        # settings["interval"] = interval
        # TODO: on_startup
        self.ind_parent.update_settings()
        self.ind_parent.update_indicator_guide()

    def set_data(self):
        """It sets the widgets with the config data."""
        self.custom_entry.set_text(self.sensor_mgr.get_custom_text())
        self.interval_entry.set_text(str(self.sensor_mgr.get_interval()))

    def update_autostart(self):
        autostart = self.autostart_check.get_active()
        if not autostart:
            try:
                os.remove(Preferences.AUTOSTART_PATH)
            except:
                pass
        else:
            try:
                if not os.path.exists(Preferences.AUTOSTART_DIR):
                    os.makedirs(Preferences.AUTOSTART_DIR)

                shutil.copy(Preferences.DESKTOP_PATH,
                            Preferences.AUTOSTART_PATH)
            except Exception as ex:
                logging.exception(ex)

    def get_autostart(self):
        return os.path.exists(Preferences.AUTOSTART_PATH)
コード例 #19
0
class IndicatorSysmonitor(object):
    SENSORS_DISABLED = False

    def __init__(self):
        self._preferences_dialog = None
        self._help_dialog = None

        self.ind = Gtk.Button.new()
        self.ind.set_label("Init...")

        self._create_menu()

        self.alive = Event()
        self.alive.set()

        self.sensor_mgr = SensorManager()
        self.load_settings()

    def _create_menu(self):
        """Creates the main menu and shows it."""
        # create menu {{{
        menu = Gtk.Menu()
        # add System Monitor menu item
        full_sysmon = Gtk.MenuItem(_('System Monitor'))
        full_sysmon.connect('activate', self.on_full_sysmon_activated)
        menu.add(full_sysmon)
        menu.add(Gtk.SeparatorMenuItem())

        # add preferences menu item
        pref_menu = Gtk.MenuItem(_('Preferences'))
        pref_menu.connect('activate', self.on_preferences_activated)
        menu.add(pref_menu)

        # add help menu item
        help_menu = Gtk.MenuItem(_('Help'))
        help_menu.connect('activate', self._on_help)
        menu.add(help_menu)

        menu.show_all()

        self.popup = menu
        self.ind.connect('clicked', self.popup_menu)
        logging.info("Menu shown")
        # }}} menu done!

    def popup_menu(self, *args):
        self.popup.popup(None, None, None, None, 0,
                         Gtk.get_current_event_time())

    def update_indicator_guide(self):

        guide = self.sensor_mgr.get_guide()

    def update(self, data):
        # data is the dict of all sensors and their values
        # { name, label }

        # look through data and find out if there are any icons to be set
        for sensor in data:
            test_str = data[sensor].lower()
            if "use_icon" in test_str:
                path = data[sensor].split(":")[1]
                print(path)
                self.ind.set_icon_full(path, "")
                # now strip the icon output from data so that it is not displayed
                remaining = test_str.split("use_icon")[0].strip()
                if not remaining:
                    remaining = " "

                data[sensor] = remaining

            if "clear_icon" in test_str:
                self.ind.set_icon_full(self.tindicator, "")

                remaining = test_str.split("clear_icon")[0].strip()
                if not remaining:
                    remaining = " "

                data[sensor] = remaining

        label = self.sensor_mgr.get_label(data)

        def update_label(label):
            self.ind.set_label(label)
            return False

        if label and self.ind:
            GLib.idle_add(update_label, label.strip())

    def load_settings(self):

        self.sensor_mgr.load_settings()
        self.sensor_mgr.initiate_fetcher(self)
        self.update_indicator_guide()

    # @staticmethod
    def save_settings(self):
        self.sensor_mgr.save_settings()

    def update_settings(self):
        self.sensor_mgr.initiate_fetcher(self)

    # actions raised from menu
    def on_preferences_activated(self, event=None):
        """Raises the preferences dialog. If it's already open, it's
        focused"""
        if self._preferences_dialog is not None:
            self._preferences_dialog.present()
            return

        self._preferences_dialog = Preferences(self)
        self._preferences_dialog.run()
        self._preferences_dialog = None

    def on_full_sysmon_activated(self, event=None):
        os.system('gnome-system-monitor &')

    def on_exit(self, event=None, data=None):
        """Action call when the main programs is closed."""
        # cleanup temporary indicator icon
        os.remove(self.tindicator)
        # close the open dialogs
        if self._help_dialog is not None:
            self._help_dialog.destroy()

        if self._preferences_dialog is not None:
            self._preferences_dialog.destroy()

        logging.info("Terminated")
        self.alive.clear()  # DM: why bother with Event() ???

        try:
            Gtk.main_quit()
        except RuntimeError:
            pass

    def _on_help(self, event=None, data=None):
        """Raise a dialog with info about the app."""
        if self._help_dialog is not None:
            self._help_dialog.present()
            return

        self._help_dialog = Gtk.MessageDialog(
            None, Gtk.DialogFlags.DESTROY_WITH_PARENT, Gtk.MessageType.INFO,
            Gtk.ButtonsType.OK, None)

        self._help_dialog.set_title(_("Help"))
        self._help_dialog.set_markup(HELP_MSG)
        self._help_dialog.run()
        self._help_dialog.destroy()
        self._help_dialog = None
コード例 #20
0
class IndicatorSysmonitor(object):
    SENSORS_DISABLED = False

    def __init__(self):
        self._preferences_dialog = None
        self._help_dialog = None

        #fn, self.tindicator = tempfile.mkstemp(suffix=".svg")

        #with open(self.tindicator, "w") as f:
        #    svg = '<?xml version="1.0" encoding="UTF-8" \
        #                standalone="no"?><svg id="empty" xmlns="http://www.w3.org/2000/svg" \
        #                height="22" width="1" version="1.0" \
        #                xmlns:xlink="http://www.w3.org/1999/xlink"></svg>'
        #    f.write(svg)
        #    f.close()

        #self.ind = appindicator.Indicator.new("indicator-sysmonitor", self.tindicator, \
        #                                      appindicator.IndicatorCategory.SYSTEM_SERVICES)
        self.ind = Gtk.Button.new()
        #self.ind.set_ordering_index(0)

        #self.ind.set_status(appindicator.IndicatorStatus.ACTIVE)
        self.ind.set_label("Init...")

        self._create_menu()

        self.alive = Event()
        self.alive.set()

        self.sensor_mgr = SensorManager()
        self.load_settings()

    def _create_menu(self):
        """Creates the main menu and shows it."""
        # create menu {{{
        menu = Gtk.Menu()
        # add System Monitor menu item
        full_sysmon = Gtk.MenuItem(_('System Monitor'))
        full_sysmon.connect('activate', self.on_full_sysmon_activated)
        menu.add(full_sysmon)
        menu.add(Gtk.SeparatorMenuItem())

        # add preferences menu item
        pref_menu = Gtk.MenuItem(_('Preferences'))
        pref_menu.connect('activate', self.on_preferences_activated)
        menu.add(pref_menu)

        # add help menu item
        help_menu = Gtk.MenuItem(_('Help'))
        help_menu.connect('activate', self._on_help)
        menu.add(help_menu)

        # add preference menu item
        #exit_menu = Gtk.MenuItem(_('Quit'))
        #exit_menu.connect('activate', self.on_exit)
        #menu.add(exit_menu)

        menu.show_all()

        self.popup = menu
        self.ind.connect('clicked', self.popup_menu)
        logging.info("Menu shown")
        # }}} menu done!

    def popup_menu(self, *args):
        self.popup.popup(None, None, None, None, 0,
                         Gtk.get_current_event_time())

    def update_indicator_guide(self):

        guide = self.sensor_mgr.get_guide()

        #self.ind.set_property("label-guide", guide)

    def update(self, data):
        # data is the dict of all sensors and their values
        # { name, label }

        # look through data and find out if there are any icons to be set
        for sensor in data:
            test_str = data[sensor].lower()
            if "use_icon" in test_str:
                path = data[sensor].split(":")[1]
                print(path)
                self.ind.set_icon_full(path, "")
                # now strip the icon output from data so that it is not displayed
                remaining = test_str.split("use_icon")[0].strip()
                if not remaining:
                    remaining = " "

                data[sensor] = remaining

            if "clear_icon" in test_str:
                self.ind.set_icon_full(self.tindicator, "")

                remaining = test_str.split("clear_icon")[0].strip()
                if not remaining:
                    remaining = " "

                data[sensor] = remaining

        label = self.sensor_mgr.get_label(data)

        Gdk.threads_enter()
        self.ind.set_label(label.strip())
        Gdk.threads_leave()

        #self.ind.set_title(label.strip())

    def load_settings(self):

        self.sensor_mgr.load_settings()
        self.sensor_mgr.initiate_fetcher(self)
        self.update_indicator_guide()

    # @staticmethod
    def save_settings(self):
        self.sensor_mgr.save_settings()

    # actions raised from menu
    def on_preferences_activated(self, event=None):
        """Raises the preferences dialog. If it's already open, it's
        focused"""
        if self._preferences_dialog is not None:
            self._preferences_dialog.present()
            return

        self._preferences_dialog = Preferences(self)
        self._preferences_dialog.run()
        self._preferences_dialog = None

    def on_full_sysmon_activated(self, event=None):
        os.system('gnome-system-monitor &')

    def on_exit(self, event=None, data=None):
        """Action call when the main programs is closed."""
        # cleanup temporary indicator icon
        os.remove(self.tindicator)
        # close the open dialogs
        if self._help_dialog is not None:
            self._help_dialog.destroy()

        if self._preferences_dialog is not None:
            self._preferences_dialog.destroy()

        logging.info("Terminated")
        self.alive.clear()  # DM: why bother with Event() ???

        try:
            Gtk.main_quit()
        except RuntimeError:
            pass

    def _on_help(self, event=None, data=None):
        """Raise a dialog with info about the app."""
        if self._help_dialog is not None:
            self._help_dialog.present()
            return

        self._help_dialog = Gtk.MessageDialog(
            None, Gtk.DialogFlags.DESTROY_WITH_PARENT, Gtk.MessageType.INFO,
            Gtk.ButtonsType.OK, None)

        self._help_dialog.set_title(_("Help"))
        self._help_dialog.set_markup(HELP_MSG)
        self._help_dialog.run()
        self._help_dialog.destroy()
        self._help_dialog = None
コード例 #21
0
class IndicatorSysmonitor(object):
    SENSORS_DISABLED = False

    def __init__(self):
        self._preferences_dialog = None
        self._help_dialog = None

        self.ind = Gtk.Button.new()
        self.ind.set_label("Init...")

        self._create_menu()

        self.alive = Event()
        self.alive.set()

        self.sensor_mgr = SensorManager()
        self.load_settings()

    def _create_menu(self):
        """Creates the main menu and shows it."""
        # create menu {{{
        menu = Gtk.Menu()
        # add System Monitor menu item
        full_sysmon = Gtk.MenuItem(_('System Monitor'))
        full_sysmon.connect('activate', self.on_full_sysmon_activated)
        menu.add(full_sysmon)
        menu.add(Gtk.SeparatorMenuItem())

        # add preferences menu item
        pref_menu = Gtk.MenuItem(_('Preferences'))
        pref_menu.connect('activate', self.on_preferences_activated)
        menu.add(pref_menu)

        # add help menu item
        help_menu = Gtk.MenuItem(_('Help'))
        help_menu.connect('activate', self._on_help)
        menu.add(help_menu)

        menu.show_all()

        self.popup = menu
        self.ind.connect('clicked', self.popup_menu)
        logging.info("Menu shown")
        # }}} menu done!

    def popup_menu(self, *args):
        self.popup.popup(None, None, None, None, 0, Gtk.get_current_event_time())

    def update_indicator_guide(self):

        guide = self.sensor_mgr.get_guide()

    def update(self, data):
        # data is the dict of all sensors and their values
        # { name, label }

        # look through data and find out if there are any icons to be set
        for sensor in data:
            test_str = data[sensor].lower()
            if "use_icon" in test_str:
                path = data[sensor].split(":")[1]
                print(path)
                self.ind.set_icon_full(path, "")
                # now strip the icon output from data so that it is not displayed
                remaining = test_str.split("use_icon")[0].strip()
                if not remaining:
                    remaining = " "

                data[sensor] = remaining

            if "clear_icon" in test_str:
                self.ind.set_icon_full(self.tindicator, "")

                remaining = test_str.split("clear_icon")[0].strip()
                if not remaining:
                    remaining = " "

                data[sensor] = remaining

        label = self.sensor_mgr.get_label(data)


        def update_label(label):
            self.ind.set_label(label)
            return False
        if label and self.ind:
            GLib.idle_add(update_label, label.strip())

    def load_settings(self):

        self.sensor_mgr.load_settings()
        self.sensor_mgr.initiate_fetcher(self)
        self.update_indicator_guide()

    # @staticmethod
    def save_settings(self):
        self.sensor_mgr.save_settings()

    # actions raised from menu
    def on_preferences_activated(self, event=None):
        """Raises the preferences dialog. If it's already open, it's
        focused"""
        if self._preferences_dialog is not None:
            self._preferences_dialog.present()
            return

        self._preferences_dialog = Preferences(self)
        self._preferences_dialog.run()
        self._preferences_dialog = None

    def on_full_sysmon_activated(self, event=None):
        os.system('gnome-system-monitor &')

    def on_exit(self, event=None, data=None):
        """Action call when the main programs is closed."""
        # cleanup temporary indicator icon
        os.remove(self.tindicator)
        # close the open dialogs
        if self._help_dialog is not None:
            self._help_dialog.destroy()

        if self._preferences_dialog is not None:
            self._preferences_dialog.destroy()

        logging.info("Terminated")
        self.alive.clear()  # DM: why bother with Event() ???

        try:
            Gtk.main_quit()
        except RuntimeError:
            pass

    def _on_help(self, event=None, data=None):
        """Raise a dialog with info about the app."""
        if self._help_dialog is not None:
            self._help_dialog.present()
            return

        self._help_dialog = Gtk.MessageDialog(
            None, Gtk.DialogFlags.DESTROY_WITH_PARENT, Gtk.MessageType.INFO,
            Gtk.ButtonsType.OK, None)

        self._help_dialog.set_title(_("Help"))
        self._help_dialog.set_markup(HELP_MSG)
        self._help_dialog.run()
        self._help_dialog.destroy()
        self._help_dialog = None
コード例 #22
0
ファイル: visual.py プロジェクト: conorpp/smart-shirt
        xyz = sens.get_point('24')
        if None not in xyz:
            xyz = sens.lowpass('24', xyz, 15)
            xyz = sens.get_point_normal(xyz)
            rightArm.set_uparm(xyz)

        xyz = sens.get_point('25')
        if None not in xyz:
            xyz = sens.lowpass('25', xyz, 15)
            xyz = sens.get_point_normal(xyz)
            rightArm.set_wrist(xyz)

        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)

        leftArm.draw()
        rightArm.draw()

        # updates the display
        pygame.display.flip()
        pygame.time.wait(2)


if __name__ == "__main__":
    s = SensorManager()
    s.calibrate()
    s.poll_sensor()
    s.clear_sensors()

    visualize(s)
コード例 #23
0
class IndicatorSysmonitor(object):
    SENSORS_DISABLED = False

    def __init__(self):
        self._preferences_dialog = None
        self._help_dialog = None

        #fn, self.tindicator = tempfile.mkstemp(suffix=".svg")

        #with open(self.tindicator, "w") as f:
        #    svg = '<?xml version="1.0" encoding="UTF-8" \
        #                standalone="no"?><svg id="empty" xmlns="http://www.w3.org/2000/svg" \
        #                height="22" width="1" version="1.0" \
        #                xmlns:xlink="http://www.w3.org/1999/xlink"></svg>'
        #    f.write(svg)
        #    f.close()

        #self.ind = appindicator.Indicator.new("indicator-sysmonitor", self.tindicator, \
        #                                      appindicator.IndicatorCategory.SYSTEM_SERVICES)
        self.ind = Gtk.Button.new()
        #self.ind.set_ordering_index(0)

        #self.ind.set_status(appindicator.IndicatorStatus.ACTIVE)
        self.ind.set_label("Init...")

        self._create_menu()

        self.alive = Event()
        self.alive.set()

        self.sensor_mgr = SensorManager()
        self.load_settings()

    def _create_menu(self):
        """Creates the main menu and shows it."""
        # create menu {{{
        menu = Gtk.Menu()
        # add System Monitor menu item
        full_sysmon = Gtk.MenuItem(_('System Monitor'))
        full_sysmon.connect('activate', self.on_full_sysmon_activated)
        menu.add(full_sysmon)
        menu.add(Gtk.SeparatorMenuItem())

        # add preferences menu item
        pref_menu = Gtk.MenuItem(_('Preferences'))
        pref_menu.connect('activate', self.on_preferences_activated)
        menu.add(pref_menu)

        # add help menu item
        help_menu = Gtk.MenuItem(_('Help'))
        help_menu.connect('activate', self._on_help)
        menu.add(help_menu)

        # add preference menu item
        #exit_menu = Gtk.MenuItem(_('Quit'))
        #exit_menu.connect('activate', self.on_exit)
        #menu.add(exit_menu)

        menu.show_all()
        
        self.popup = menu
        self.ind.connect('clicked', self.popup_menu)
        logging.info("Menu shown")
        # }}} menu done!

    def popup_menu(self, *args):
        self.popup.popup(None, None, None, None, 0, Gtk.get_current_event_time())
        
    def update_indicator_guide(self):

        guide = self.sensor_mgr.get_guide()

        #self.ind.set_property("label-guide", guide)

    def update(self, data):
        # data is the dict of all sensors and their values
        # { name, label }

        # look through data and find out if there are any icons to be set
        for sensor in data:
            test_str = data[sensor].lower()
            if "use_icon" in test_str:
                path = data[sensor].split(":")[1]
                print(path)
                self.ind.set_icon_full(path, "")
                # now strip the icon output from data so that it is not displayed
                remaining = test_str.split("use_icon")[0].strip()
                if not remaining:
                    remaining = " "

                data[sensor] = remaining

            if "clear_icon" in test_str:
                self.ind.set_icon_full(self.tindicator, "")

                remaining = test_str.split("clear_icon")[0].strip()
                if not remaining:
                    remaining = " "

                data[sensor] = remaining

        label = self.sensor_mgr.get_label(data)

        Gdk.threads_enter()
        self.ind.set_label(label.strip())
        Gdk.threads_leave()
        
        #self.ind.set_title(label.strip())

    def load_settings(self):

        self.sensor_mgr.load_settings()
        self.sensor_mgr.initiate_fetcher(self)
        self.update_indicator_guide()

    # @staticmethod
    def save_settings(self):
        self.sensor_mgr.save_settings()

    # actions raised from menu
    def on_preferences_activated(self, event=None):
        """Raises the preferences dialog. If it's already open, it's
        focused"""
        if self._preferences_dialog is not None:
            self._preferences_dialog.present()
            return

        self._preferences_dialog = Preferences(self)
        self._preferences_dialog.run()
        self._preferences_dialog = None

    def on_full_sysmon_activated(self, event=None):
        os.system('gnome-system-monitor &')

    def on_exit(self, event=None, data=None):
        """Action call when the main programs is closed."""
        # cleanup temporary indicator icon
        os.remove(self.tindicator)
        # close the open dialogs
        if self._help_dialog is not None:
            self._help_dialog.destroy()

        if self._preferences_dialog is not None:
            self._preferences_dialog.destroy()

        logging.info("Terminated")
        self.alive.clear()  # DM: why bother with Event() ???

        try:
            Gtk.main_quit()
        except RuntimeError:
            pass

    def _on_help(self, event=None, data=None):
        """Raise a dialog with info about the app."""
        if self._help_dialog is not None:
            self._help_dialog.present()
            return

        self._help_dialog = Gtk.MessageDialog(
            None, Gtk.DialogFlags.DESTROY_WITH_PARENT, Gtk.MessageType.INFO,
            Gtk.ButtonsType.OK, None)

        self._help_dialog.set_title(_("Help"))
        self._help_dialog.set_markup(HELP_MSG)
        self._help_dialog.run()
        self._help_dialog.destroy()
        self._help_dialog = None