Beispiel #1
0
 def _process_supervised(self):
     for service, method in self._supervised.items():
         # Do an async call. If the owner of the service does not answer, we do not want to wait for
         # the timeout here.
         method.call_async(error_handler=lambda x: exit_on_error(
             self._supervise_failed, service, x))
     return True
Beispiel #2
0
	def set_sources(self, dbusmonitor, settings, dbusservice):
		SystemCalcDelegate.set_sources(self, dbusmonitor, settings, dbusservice)
		self._buzzer_on = False
		self._timer = None
		# Find GPIO buzzer
		gpio_paths = sc_utils.gpio_paths(BuzzerControl.GPIO_BUZZER_PATH)
		self._gpio_path = None
		if len(gpio_paths) > 0:
			self._gpio_path = os.path.join(gpio_paths[0], 'value')
			logging.info('GPIO buzzer found: {}'.format(self._gpio_path))
		# Find PWM buzzer
		self._pwm_frequency = None
		try:
			pwm_frequency = sc_utils.gpio_paths(BuzzerControl.PWM_BUZZER_PATH)
			if len(pwm_frequency) > 0:
				self._pwm_frequency = int(pwm_frequency[0])
				logging.info('PWM buzzer found @ frequency: {}'.format(self._pwm_frequency))
		except ValueError:
			logging.error('Parsing of PWM buzzer settings at %s failed', BuzzerControl.PWM_BUZZER_PATH)
		if self._gpio_path == None and self._pwm_frequency == None:
			logging.info('No buzzer found')
			return
		self._dbusservice.add_path('/Buzzer/State', value=0, writeable=True,
			onchangecallback=lambda p,v: exit_on_error(self._on_buzzer_state_changed, v))
		# Reset the buzzer so the buzzer state equals the D-Bus value. It will also silence the buzzer after
		# a restart of the service/system.
		self._set_buzzer(False)
	def set_sources(self, dbusmonitor, settings, dbusservice):
		SystemCalcDelegate.set_sources(self, dbusmonitor, settings, dbusservice)
		# Find GPIO buzzer
		gpio_paths = sc_utils.gpio_paths(BuzzerControl.GPIO_BUZZER_PATH)
		if len(gpio_paths) > 0:
			self._gpio_path = os.path.join(gpio_paths[0], 'value')
			logging.info('GPIO buzzer found: {}'.format(self._gpio_path))
		# Find PWM buzzer
		self._pwm_frequency = None
		try:
			pwm_frequency = sc_utils.gpio_paths(BuzzerControl.PWM_BUZZER_PATH)
			if len(pwm_frequency) > 0:
				self._pwm_frequency = int(pwm_frequency[0])
				logging.info('PWM buzzer found @ frequency: {}'.format(self._pwm_frequency))
		except ValueError:
			logging.error('Parsing of PWM buzzer settings at %s failed', BuzzerControl.PWM_BUZZER_PATH)
		if self._gpio_path is None and self._pwm_frequency is None:
			logging.info('No buzzer found')
			return
		self._dbusservice.add_path('/Buzzer/State', value=0, writeable=True,
			onchangecallback=lambda p, v: exit_on_error(self._on_buzzer_state_changed, v))
		# Reset the buzzer so the buzzer state equals the D-Bus value. It will also silence the buzzer after
		# a restart of the service/system.
		self._set_buzzer(False)
 def _on_socket_in(self, src, condition):
     exit_on_error(self._client.loop_read)
     return True
	def _on_socket_in(self, src, condition):
		exit_on_error(self._client.loop_read)
		return True
Beispiel #6
0
    def __init__(self,
                 dbusmonitor_gen=None,
                 dbusservice_gen=None,
                 settings_device_gen=None):
        self.STATE_IDLE = 0
        self.STATE_CHARGING = 1
        self.STATE_DISCHARGING = 2

        self.BATSERVICE_DEFAULT = 'default'
        self.BATSERVICE_NOBATTERY = 'nobattery'

        # Why this dummy? Because DbusMonitor expects these values to be there, even though we don't
        # need them. So just add some dummy data. This can go away when DbusMonitor is more generic.
        dummy = {
            'code': None,
            'whenToLog': 'configChange',
            'accessLevel': None
        }
        dbus_tree = {
            'com.victronenergy.solarcharger': {
                '/Connected': dummy,
                '/ProductName': dummy,
                '/Mgmt/Connection': dummy,
                '/Dc/0/Voltage': dummy,
                '/Dc/0/Current': dummy
            },
            'com.victronenergy.pvinverter': {
                '/Connected': dummy,
                '/ProductName': dummy,
                '/Mgmt/Connection': dummy,
                '/Ac/L1/Power': dummy,
                '/Ac/L2/Power': dummy,
                '/Ac/L3/Power': dummy,
                '/Position': dummy,
                '/ProductId': dummy
            },
            'com.victronenergy.battery': {
                '/Connected': dummy,
                '/ProductName': dummy,
                '/Mgmt/Connection': dummy,
                '/Dc/0/Voltage': dummy,
                '/Dc/0/Current': dummy,
                '/Dc/0/Power': dummy,
                '/Soc': dummy,
                '/TimeToGo': dummy,
                '/ConsumedAmphours': dummy,
                '/ProductId': dummy
            },
            'com.victronenergy.vebus': {
                '/Ac/ActiveIn/ActiveInput': dummy,
                '/Ac/ActiveIn/L1/P': dummy,
                '/Ac/ActiveIn/L2/P': dummy,
                '/Ac/ActiveIn/L3/P': dummy,
                '/Ac/Out/L1/P': dummy,
                '/Ac/Out/L2/P': dummy,
                '/Ac/Out/L3/P': dummy,
                '/Connected': dummy,
                '/Hub4/AcPowerSetpoint': dummy,
                '/ProductId': dummy,
                '/ProductName': dummy,
                '/Mgmt/Connection': dummy,
                '/Mode': dummy,
                '/State': dummy,
                '/Dc/0/Voltage': dummy,
                '/Dc/0/Current': dummy,
                '/Dc/0/Power': dummy,
                '/Soc': dummy
            },
            'com.victronenergy.charger': {
                '/Connected': dummy,
                '/ProductName': dummy,
                '/Mgmt/Connection': dummy,
                '/Dc/0/Voltage': dummy,
                '/Dc/0/Current': dummy
            },
            'com.victronenergy.grid': {
                '/Connected': dummy,
                '/ProductName': dummy,
                '/Mgmt/Connection': dummy,
                '/ProductId': dummy,
                '/DeviceType': dummy,
                '/Ac/L1/Power': dummy,
                '/Ac/L2/Power': dummy,
                '/Ac/L3/Power': dummy
            },
            'com.victronenergy.genset': {
                '/Connected': dummy,
                '/ProductName': dummy,
                '/Mgmt/Connection': dummy,
                '/ProductId': dummy,
                '/DeviceType': dummy,
                '/Ac/L1/Power': dummy,
                '/Ac/L2/Power': dummy,
                '/Ac/L3/Power': dummy
            },
            'com.victronenergy.settings': {
                '/Settings/SystemSetup/AcInput1': dummy,
                '/Settings/SystemSetup/AcInput2': dummy
            }
        }

        if dbusmonitor_gen is None:
            self._dbusmonitor = DbusMonitor(dbus_tree,
                                            self._dbus_value_changed,
                                            self._device_added,
                                            self._device_removed)
        else:
            self._dbusmonitor = dbusmonitor_gen(dbus_tree)

        # Connect to localsettings
        supported_settings = {
            'batteryservice': [
                '/Settings/SystemSetup/BatteryService',
                self.BATSERVICE_DEFAULT, 0, 0
            ],
            'hasdcsystem': ['/Settings/SystemSetup/HasDcSystem', 0, 0, 1],
            'writevebussoc': ['/Settings/SystemSetup/WriteVebusSoc', 0, 0, 1]
        }

        if settings_device_gen is None:
            self._settings = SettingsDevice(
                bus=dbus.SessionBus() if 'DBUS_SESSION_BUS_ADDRESS'
                in os.environ else dbus.SystemBus(),
                supportedSettings=supported_settings,
                eventCallback=self._handlechangedsetting)
        else:
            self._settings = settings_device_gen(supported_settings,
                                                 self._handlechangedsetting)

        # put ourselves on the dbus
        if dbusservice_gen is None:
            self._dbusservice = VeDbusService('com.victronenergy.system')
        else:
            self._dbusservice = dbusservice_gen('com.victronenergy.system')

        self._dbusservice.add_mandatory_paths(
            processname=__file__,
            processversion=softwareVersion,
            connection='data from other dbus processes',
            deviceinstance=0,
            productid=None,
            productname=None,
            firmwareversion=None,
            hardwareversion=None,
            connected=1)

        # At this moment, VRM portal ID is the MAC address of the CCGX. Anyhow, it should be string uniquely
        # identifying the CCGX.
        self._dbusservice.add_path('/Serial',
                                   value=get_vrm_portal_id(),
                                   gettextcallback=lambda x: str(x))
        self._dbusservice.add_path('/Relay/0/State',
                                   value=None,
                                   writeable=True,
                                   onchangecallback=lambda p, v: exit_on_error(
                                       self._on_relay_state_changed, p, v))

        self._dbusservice.add_path('/AvailableBatteryServices',
                                   value=None,
                                   gettextcallback=self._gettext)
        self._dbusservice.add_path('/AvailableBatteryMeasurements', value=None)
        self._dbusservice.add_path('/AutoSelectedBatteryService',
                                   value=None,
                                   gettextcallback=self._gettext)
        self._dbusservice.add_path('/AutoSelectedBatteryMeasurement',
                                   value=None,
                                   gettextcallback=self._gettext)
        self._dbusservice.add_path('/ActiveBatteryService',
                                   value=None,
                                   gettextcallback=self._gettext)
        self._dbusservice.add_path('/PvInvertersProductIds', value=None)
        self._dbusservice.add_path('/Dc/Battery/Alarms/CircuitBreakerTripped',
                                   value=None)
        self._summeditems = {
            '/Ac/Grid/L1/Power': {
                'gettext': '%.0F W'
            },
            '/Ac/Grid/L2/Power': {
                'gettext': '%.0F W'
            },
            '/Ac/Grid/L3/Power': {
                'gettext': '%.0F W'
            },
            '/Ac/Grid/Total/Power': {
                'gettext': '%.0F W'
            },
            '/Ac/Grid/NumberOfPhases': {
                'gettext': '%.0F W'
            },
            '/Ac/Grid/ProductId': {
                'gettext': '%s'
            },
            '/Ac/Grid/DeviceType': {
                'gettext': '%s'
            },
            '/Ac/Genset/L1/Power': {
                'gettext': '%.0F W'
            },
            '/Ac/Genset/L2/Power': {
                'gettext': '%.0F W'
            },
            '/Ac/Genset/L3/Power': {
                'gettext': '%.0F W'
            },
            '/Ac/Genset/Total/Power': {
                'gettext': '%.0F W'
            },
            '/Ac/Genset/NumberOfPhases': {
                'gettext': '%.0F W'
            },
            '/Ac/Genset/ProductId': {
                'gettext': '%s'
            },
            '/Ac/Genset/DeviceType': {
                'gettext': '%s'
            },
            '/Ac/Consumption/L1/Power': {
                'gettext': '%.0F W'
            },
            '/Ac/Consumption/L2/Power': {
                'gettext': '%.0F W'
            },
            '/Ac/Consumption/L3/Power': {
                'gettext': '%.0F W'
            },
            '/Ac/Consumption/Total/Power': {
                'gettext': '%.0F W'
            },
            '/Ac/Consumption/NumberOfPhases': {
                'gettext': '%.0F W'
            },
            '/Ac/PvOnOutput/L1/Power': {
                'gettext': '%.0F W'
            },
            '/Ac/PvOnOutput/L2/Power': {
                'gettext': '%.0F W'
            },
            '/Ac/PvOnOutput/L3/Power': {
                'gettext': '%.0F W'
            },
            '/Ac/PvOnOutput/Total/Power': {
                'gettext': '%.0F W'
            },
            '/Ac/PvOnOutput/NumberOfPhases': {
                'gettext': '%.0F W'
            },
            '/Ac/PvOnGrid/L1/Power': {
                'gettext': '%.0F W'
            },
            '/Ac/PvOnGrid/L2/Power': {
                'gettext': '%.0F W'
            },
            '/Ac/PvOnGrid/L3/Power': {
                'gettext': '%.0F W'
            },
            '/Ac/PvOnGrid/Total/Power': {
                'gettext': '%.0F W'
            },
            '/Ac/PvOnGrid/NumberOfPhases': {
                'gettext': '%.0F W'
            },
            '/Ac/PvOnGenset/L1/Power': {
                'gettext': '%.0F W'
            },
            '/Ac/PvOnGenset/L2/Power': {
                'gettext': '%.0F W'
            },
            '/Ac/PvOnGenset/L3/Power': {
                'gettext': '%.0F W'
            },
            '/Ac/PvOnGenset/NumberOfPhases': {
                'gettext': '%d'
            },
            '/Ac/PvOnGenset/Total/Power': {
                'gettext': '%.0F W'
            },
            '/Dc/Pv/Power': {
                'gettext': '%.0F W'
            },
            '/Dc/Pv/Current': {
                'gettext': '%.1F A'
            },
            '/Dc/Battery/Voltage': {
                'gettext': '%.2F V'
            },
            '/Dc/Battery/Current': {
                'gettext': '%.1F A'
            },
            '/Dc/Battery/Power': {
                'gettext': '%.0F W'
            },
            '/Dc/Battery/Soc': {
                'gettext': '%.0F %%'
            },
            '/Dc/Battery/State': {
                'gettext': '%s'
            },
            '/Dc/Battery/TimeToGo': {
                'gettext': '%.0F s'
            },
            '/Dc/Battery/ConsumedAmphours': {
                'gettext': '%.1F Ah'
            },
            '/Dc/Charger/Power': {
                'gettext': '%.0F %%'
            },
            '/Dc/Vebus/Current': {
                'gettext': '%.1F A'
            },
            '/Dc/Vebus/Power': {
                'gettext': '%.0F W'
            },
            '/Dc/System/Power': {
                'gettext': '%.0F W'
            },
            '/Hub': {
                'gettext': '%s'
            },
            '/Ac/ActiveIn/Source': {
                'gettext': '%s'
            },
            '/VebusService': {
                'gettext': '%s'
            }
        }

        for path in self._summeditems.keys():
            self._dbusservice.add_path(path,
                                       value=None,
                                       gettextcallback=self._gettext)

        self._batteryservice = None
        self._determinebatteryservice()

        self._supervised = {}
        self._lg_battery = None

        if self._batteryservice is None:
            logger.info("Battery service initialized to None (setting == %s)" %
                        self._settings['batteryservice'])

        self._changed = True
        for service, instance in self._dbusmonitor.get_service_list().items():
            self._device_added(service, instance, do_service_change=False)

        self._handleservicechange()
        self._updatevalues()
        try:
            self._relay_file_read = open(relayGpioFile, 'rt')
            self._relay_file_write = open(relayGpioFile, 'wt')
            self._update_relay_state()
            gobject.timeout_add(5000, exit_on_error, self._update_relay_state)
        except IOError:
            self._relay_file_read = None
            self._relay_file_write = None
            logging.warn('Could not open %s (relay)' % relayGpioFile)

        self._writeVebusSocCounter = 9
        gobject.timeout_add(1000, exit_on_error, self._handletimertick)
        gobject.timeout_add(60000, exit_on_error, self._process_supervised)