annotate velib_python/settingsdevice.py @ 8:9c0435a617db

Import velib_python
author Daniel O'Connor <darius@dons.net.au>
date Sun, 05 Dec 2021 14:35:36 +1030
parents
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
8
9c0435a617db Import velib_python
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
1 import dbus
9c0435a617db Import velib_python
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
2 import logging
9c0435a617db Import velib_python
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
3 import time
9c0435a617db Import velib_python
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
4 from functools import partial
9c0435a617db Import velib_python
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
5
9c0435a617db Import velib_python
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
6 # Local imports
9c0435a617db Import velib_python
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
7 from vedbus import VeDbusItemImport
9c0435a617db Import velib_python
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
8
9c0435a617db Import velib_python
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
9 ## Indexes for the setting dictonary.
9c0435a617db Import velib_python
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
10 PATH = 0
9c0435a617db Import velib_python
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
11 VALUE = 1
9c0435a617db Import velib_python
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
12 MINIMUM = 2
9c0435a617db Import velib_python
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
13 MAXIMUM = 3
9c0435a617db Import velib_python
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
14 SILENT = 4
9c0435a617db Import velib_python
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
15
9c0435a617db Import velib_python
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
16 ## The Settings Device class.
9c0435a617db Import velib_python
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
17 # Used by python programs, such as the vrm-logger, to read and write settings they
9c0435a617db Import velib_python
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
18 # need to store on disk. And since these settings might be changed from a different
9c0435a617db Import velib_python
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
19 # source, such as the GUI, the program can pass an eventCallback that will be called
9c0435a617db Import velib_python
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
20 # as soon as some setting is changed.
9c0435a617db Import velib_python
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
21 #
9c0435a617db Import velib_python
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
22 # The settings are stored in flash via the com.victronenergy.settings service on dbus.
9c0435a617db Import velib_python
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
23 # See https://github.com/victronenergy/localsettings for more info.
9c0435a617db Import velib_python
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
24 #
9c0435a617db Import velib_python
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
25 # If there are settings in de supportSettings list which are not yet on the dbus,
9c0435a617db Import velib_python
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
26 # and therefore not yet in the xml file, they will be added through the dbus-addSetting
9c0435a617db Import velib_python
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
27 # interface of com.victronenergy.settings.
9c0435a617db Import velib_python
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
28 class SettingsDevice(object):
9c0435a617db Import velib_python
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
29 ## The constructor processes the tree of dbus-items.
9c0435a617db Import velib_python
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
30 # @param bus the system-dbus object
9c0435a617db Import velib_python
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
31 # @param name the dbus-service-name of the settings dbus service, 'com.victronenergy.settings'
9c0435a617db Import velib_python
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
32 # @param supportedSettings dictionary with all setting-names, and their defaultvalue, min, max and whether
9c0435a617db Import velib_python
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
33 # the setting is silent. The 'silent' entry is optional. If set to true, no changes in the setting will
9c0435a617db Import velib_python
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
34 # be logged by localsettings.
9c0435a617db Import velib_python
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
35 # @param eventCallback function that will be called on changes on any of these settings
9c0435a617db Import velib_python
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
36 # @param timeout Maximum interval to wait for localsettings. An exception is thrown at the end of the
9c0435a617db Import velib_python
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
37 # interval if the localsettings D-Bus service has not appeared yet.
9c0435a617db Import velib_python
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
38 def __init__(self, bus, supportedSettings, eventCallback, name='com.victronenergy.settings', timeout=0):
9c0435a617db Import velib_python
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
39 logging.debug("===== Settings device init starting... =====")
9c0435a617db Import velib_python
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
40 self._bus = bus
9c0435a617db Import velib_python
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
41 self._dbus_name = name
9c0435a617db Import velib_python
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
42 self._eventCallback = eventCallback
9c0435a617db Import velib_python
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
43 self._values = {} # stored the values, used to pass the old value along on a setting change
9c0435a617db Import velib_python
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
44 self._settings = {}
9c0435a617db Import velib_python
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
45
9c0435a617db Import velib_python
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
46 count = 0
9c0435a617db Import velib_python
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
47 while True:
9c0435a617db Import velib_python
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
48 if 'com.victronenergy.settings' in self._bus.list_names():
9c0435a617db Import velib_python
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
49 break
9c0435a617db Import velib_python
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
50 if count == timeout:
9c0435a617db Import velib_python
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
51 raise Exception("The settings service com.victronenergy.settings does not exist!")
9c0435a617db Import velib_python
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
52 count += 1
9c0435a617db Import velib_python
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
53 logging.info('waiting for settings')
9c0435a617db Import velib_python
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
54 time.sleep(1)
9c0435a617db Import velib_python
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
55
9c0435a617db Import velib_python
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
56 # Add the items.
9c0435a617db Import velib_python
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
57 self.addSettings(supportedSettings)
9c0435a617db Import velib_python
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
58
9c0435a617db Import velib_python
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
59 logging.debug("===== Settings device init finished =====")
9c0435a617db Import velib_python
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
60
9c0435a617db Import velib_python
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
61 def addSettings(self, settings):
9c0435a617db Import velib_python
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
62 for setting, options in settings.items():
9c0435a617db Import velib_python
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
63 silent = len(options) > SILENT and options[SILENT]
9c0435a617db Import velib_python
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
64 busitem = self.addSetting(options[PATH], options[VALUE],
9c0435a617db Import velib_python
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
65 options[MINIMUM], options[MAXIMUM], silent, callback=partial(self.handleChangedSetting, setting))
9c0435a617db Import velib_python
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
66 self._settings[setting] = busitem
9c0435a617db Import velib_python
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
67 self._values[setting] = busitem.get_value()
9c0435a617db Import velib_python
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
68
9c0435a617db Import velib_python
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
69 def addSetting(self, path, value, _min, _max, silent=False, callback=None):
9c0435a617db Import velib_python
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
70 busitem = VeDbusItemImport(self._bus, self._dbus_name, path, callback)
9c0435a617db Import velib_python
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
71 if busitem.exists and (value, _min, _max, silent) == busitem._proxy.GetAttributes():
9c0435a617db Import velib_python
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
72 logging.debug("Setting %s found" % path)
9c0435a617db Import velib_python
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
73 else:
9c0435a617db Import velib_python
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
74 logging.info("Setting %s does not exist yet or must be adjusted" % path)
9c0435a617db Import velib_python
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
75
9c0435a617db Import velib_python
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
76 # Prepare to add the setting. Most dbus types extend the python
9c0435a617db Import velib_python
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
77 # type so it is only necessary to additionally test for Int64.
9c0435a617db Import velib_python
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
78 if isinstance(value, (int, dbus.Int64)):
9c0435a617db Import velib_python
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
79 itemType = 'i'
9c0435a617db Import velib_python
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
80 elif isinstance(value, float):
9c0435a617db Import velib_python
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
81 itemType = 'f'
9c0435a617db Import velib_python
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
82 else:
9c0435a617db Import velib_python
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
83 itemType = 's'
9c0435a617db Import velib_python
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
84
9c0435a617db Import velib_python
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
85 # Add the setting
9c0435a617db Import velib_python
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
86 # TODO, make an object that inherits VeDbusItemImport, and complete the D-Bus settingsitem interface
9c0435a617db Import velib_python
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
87 settings_item = VeDbusItemImport(self._bus, self._dbus_name, '/Settings', createsignal=False)
9c0435a617db Import velib_python
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
88 setting_path = path.replace('/Settings/', '', 1)
9c0435a617db Import velib_python
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
89 if silent:
9c0435a617db Import velib_python
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
90 settings_item._proxy.AddSilentSetting('', setting_path, value, itemType, _min, _max)
9c0435a617db Import velib_python
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
91 else:
9c0435a617db Import velib_python
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
92 settings_item._proxy.AddSetting('', setting_path, value, itemType, _min, _max)
9c0435a617db Import velib_python
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
93
9c0435a617db Import velib_python
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
94 busitem = VeDbusItemImport(self._bus, self._dbus_name, path, callback)
9c0435a617db Import velib_python
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
95
9c0435a617db Import velib_python
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
96 return busitem
9c0435a617db Import velib_python
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
97
9c0435a617db Import velib_python
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
98 def handleChangedSetting(self, setting, servicename, path, changes):
9c0435a617db Import velib_python
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
99 oldvalue = self._values[setting] if setting in self._values else None
9c0435a617db Import velib_python
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
100 self._values[setting] = changes['Value']
9c0435a617db Import velib_python
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
101
9c0435a617db Import velib_python
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
102 if self._eventCallback is None:
9c0435a617db Import velib_python
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
103 return
9c0435a617db Import velib_python
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
104
9c0435a617db Import velib_python
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
105 self._eventCallback(setting, oldvalue, changes['Value'])
9c0435a617db Import velib_python
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
106
9c0435a617db Import velib_python
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
107 def setDefault(self, path):
9c0435a617db Import velib_python
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
108 item = VeDbusItemImport(self._bus, self._dbus_name, path, createsignal=False)
9c0435a617db Import velib_python
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
109 item.set_default()
9c0435a617db Import velib_python
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
110
9c0435a617db Import velib_python
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
111 def __getitem__(self, setting):
9c0435a617db Import velib_python
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
112 return self._settings[setting].get_value()
9c0435a617db Import velib_python
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
113
9c0435a617db Import velib_python
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
114 def __setitem__(self, setting, newvalue):
9c0435a617db Import velib_python
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
115 result = self._settings[setting].set_value(newvalue)
9c0435a617db Import velib_python
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
116 if result != 0:
9c0435a617db Import velib_python
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
117 # Trying to make some false change to our own settings? How dumb!
9c0435a617db Import velib_python
Daniel O'Connor <darius@dons.net.au>
parents:
diff changeset
118 assert False