extarct s3 data with decompression
This commit is contained in:
parent
933f895a67
commit
5813ecfee3
|
@ -1,18 +1,16 @@
|
||||||
#!/usr/bin/python3 -u
|
#!/usr/bin/python2 -u
|
||||||
# coding=utf-8
|
# coding=utf-8
|
||||||
|
|
||||||
import logging
|
import logging
|
||||||
import re
|
import re
|
||||||
import socket
|
import socket
|
||||||
import sys
|
import sys
|
||||||
import typing
|
import gobject
|
||||||
|
|
||||||
from gi.repository import GLib as glib
|
|
||||||
import signals
|
import signals
|
||||||
import config as cfg
|
import config as cfg
|
||||||
|
|
||||||
from dbus.mainloop.glib import DBusGMainLoop
|
from dbus.mainloop.glib import DBusGMainLoop
|
||||||
from pymodbus.client import ModbusSerialClient as Modbus
|
from pymodbus.client.sync import ModbusSerialClient as Modbus
|
||||||
from pymodbus.exceptions import ModbusException, ModbusIOException
|
from pymodbus.exceptions import ModbusException, ModbusIOException
|
||||||
from pymodbus.other_message import ReportSlaveIdRequest
|
from pymodbus.other_message import ReportSlaveIdRequest
|
||||||
from pymodbus.pdu import ExceptionResponse
|
from pymodbus.pdu import ExceptionResponse
|
||||||
|
@ -23,353 +21,334 @@ from python_libs.ie_dbus.dbus_service import DBusService
|
||||||
# trick the pycharm type-checker into thinking Callable is in scope, not used at runtime
|
# trick the pycharm type-checker into thinking Callable is in scope, not used at runtime
|
||||||
# noinspection PyUnreachableCode
|
# noinspection PyUnreachableCode
|
||||||
if False:
|
if False:
|
||||||
from typing import Callable, List, Iterable, NoReturn
|
from typing import Callable, List, Iterable, NoReturn
|
||||||
|
|
||||||
|
|
||||||
RESET_REGISTER = 0x2087
|
RESET_REGISTER = 0x2087
|
||||||
SETTINGS_SERVICE_PREFIX = 'com.victronenergy.settings'
|
|
||||||
INVERTER_SERVICE_PREFIX = 'com.victronenergy.vebus.'
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def init_modbus(tty):
|
def init_modbus(tty):
|
||||||
# type: (str) -> Modbus
|
# type: (str) -> Modbus
|
||||||
|
|
||||||
logging.debug('initializing Modbus')
|
logging.debug('initializing Modbus')
|
||||||
|
|
||||||
return Modbus(
|
return Modbus(
|
||||||
port='/dev/' + tty,
|
port='/dev/' + tty,
|
||||||
method=cfg.MODE,
|
method=cfg.MODE,
|
||||||
baudrate=cfg.BAUD_RATE,
|
baudrate=cfg.BAUD_RATE,
|
||||||
stopbits=cfg.STOP_BITS,
|
stopbits=cfg.STOP_BITS,
|
||||||
bytesize=cfg.BYTE_SIZE,
|
bytesize=cfg.BYTE_SIZE,
|
||||||
timeout=cfg.TIMEOUT,
|
timeout=cfg.TIMEOUT,
|
||||||
parity=cfg.PARITY)
|
parity=cfg.PARITY)
|
||||||
|
|
||||||
|
|
||||||
def init_udp_socket():
|
def init_udp_socket():
|
||||||
# type: () -> socket
|
# type: () -> socket
|
||||||
|
|
||||||
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
|
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
|
||||||
s.setblocking(False)
|
s.setblocking(False)
|
||||||
|
|
||||||
return s
|
return s
|
||||||
|
|
||||||
|
|
||||||
def report_slave_id(modbus, slave_address):
|
def report_slave_id(modbus, slave_address):
|
||||||
# type: (Modbus, int) -> str
|
# type: (Modbus, int) -> str
|
||||||
|
|
||||||
slave = str(slave_address)
|
slave = str(slave_address)
|
||||||
|
|
||||||
logging.debug('requesting slave id from node ' + slave)
|
logging.debug('requesting slave id from node ' + slave)
|
||||||
|
|
||||||
with modbus:
|
with modbus:
|
||||||
|
|
||||||
request = ReportSlaveIdRequest(unit=slave_address)
|
request = ReportSlaveIdRequest(unit=slave_address)
|
||||||
response = modbus.execute(request)
|
response = modbus.execute(request)
|
||||||
|
|
||||||
if response is ExceptionResponse or issubclass(type(response), ModbusException):
|
if response is ExceptionResponse or issubclass(type(response), ModbusException):
|
||||||
raise Exception('failed to get slave id from ' + slave + ' : ' + str(response))
|
raise Exception('failed to get slave id from ' + slave + ' : ' + str(response))
|
||||||
|
|
||||||
return response.identifier
|
return response.identifier
|
||||||
|
|
||||||
|
|
||||||
def identify_battery(modbus, slave_address):
|
def identify_battery(modbus, slave_address):
|
||||||
# type: (Modbus, int) -> Battery
|
# type: (Modbus, int) -> Battery
|
||||||
|
|
||||||
logging.info('identifying battery...')
|
logging.info('identifying battery...')
|
||||||
|
|
||||||
hardware_version, bms_version, ampere_hours = parse_slave_id(modbus, slave_address)
|
hardware_version, bms_version, ampere_hours = parse_slave_id(modbus, slave_address)
|
||||||
firmware_version = read_firmware_version(modbus, slave_address)
|
firmware_version = read_firmware_version(modbus, slave_address)
|
||||||
|
|
||||||
specs = Battery(
|
specs = Battery(
|
||||||
slave_address=slave_address,
|
slave_address=slave_address,
|
||||||
hardware_version=hardware_version,
|
hardware_version=hardware_version,
|
||||||
firmware_version=firmware_version,
|
firmware_version=firmware_version,
|
||||||
bms_version=bms_version,
|
bms_version=bms_version,
|
||||||
ampere_hours=ampere_hours)
|
ampere_hours=ampere_hours)
|
||||||
|
|
||||||
logging.info('battery identified:\n{0}'.format(str(specs)))
|
logging.info('battery identified:\n{0}'.format(str(specs)))
|
||||||
|
|
||||||
return specs
|
return specs
|
||||||
|
|
||||||
|
|
||||||
def identify_batteries(modbus):
|
def identify_batteries(modbus):
|
||||||
# type: (Modbus) -> List[Battery]
|
# type: (Modbus) -> List[Battery]
|
||||||
|
|
||||||
def _identify_batteries():
|
def _identify_batteries():
|
||||||
slave_address = 0
|
slave_address = 0
|
||||||
n_missing = -255
|
n_missing = -255
|
||||||
|
|
||||||
while n_missing < 3:
|
while n_missing < 3:
|
||||||
slave_address += 1
|
slave_address += 1
|
||||||
try:
|
try:
|
||||||
yield identify_battery(modbus, slave_address)
|
yield identify_battery(modbus, slave_address)
|
||||||
n_missing = 0
|
n_missing = 0
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logging.info('failed to identify battery at {0} : {1}'.format(str(slave_address), str(e)))
|
logging.info('failed to identify battery at {0} : {1}'.format(str(slave_address), str(e)))
|
||||||
n_missing += 1
|
n_missing += 1
|
||||||
|
|
||||||
logging.info('giving up searching for further batteries')
|
logging.info('giving up searching for further batteries')
|
||||||
|
|
||||||
batteries = list(_identify_batteries()) # dont be lazy!
|
batteries = list(_identify_batteries()) # dont be lazy!
|
||||||
|
|
||||||
n = len(batteries)
|
n = len(batteries)
|
||||||
logging.info('found ' + str(n) + (' battery' if n == 1 else ' batteries'))
|
logging.info('found ' + str(n) + (' battery' if n == 1 else ' batteries'))
|
||||||
|
|
||||||
return batteries
|
return batteries
|
||||||
|
|
||||||
|
|
||||||
def parse_slave_id(modbus, slave_address):
|
def parse_slave_id(modbus, slave_address):
|
||||||
# type: (Modbus, int) -> (str, str, int)
|
# type: (Modbus, int) -> (str, str, int)
|
||||||
|
|
||||||
slave_id = report_slave_id(modbus, slave_address)
|
slave_id = report_slave_id(modbus, slave_address)
|
||||||
|
|
||||||
sid = re.sub(r'[^\x20-\x7E]', '', slave_id) # remove weird special chars
|
sid = re.sub(r'[^\x20-\x7E]', '', slave_id) # remove weird special chars
|
||||||
|
|
||||||
match = re.match('(?P<hw>48TL(?P<ah>[0-9]+)) *(?P<bms>.*)', sid)
|
match = re.match('(?P<hw>48TL(?P<ah>[0-9]+)) *(?P<bms>.*)', sid)
|
||||||
|
|
||||||
if match is None:
|
if match is None:
|
||||||
raise Exception('no known battery found')
|
raise Exception('no known battery found')
|
||||||
|
|
||||||
return match.group('hw').strip(), match.group('bms').strip(), int(match.group('ah').strip())
|
return match.group('hw').strip(), match.group('bms').strip(), int(match.group('ah').strip())
|
||||||
|
|
||||||
|
|
||||||
def read_firmware_version(modbus, slave_address):
|
def read_firmware_version(modbus, slave_address):
|
||||||
# type: (Modbus, int) -> str
|
# type: (Modbus, int) -> str
|
||||||
|
|
||||||
logging.debug('reading firmware version')
|
logging.debug('reading firmware version')
|
||||||
|
|
||||||
with modbus:
|
with modbus:
|
||||||
|
|
||||||
response = read_modbus_registers(modbus, slave_address, base_address=1054, count=1)
|
response = read_modbus_registers(modbus, slave_address, base_address=1054, count=1)
|
||||||
register = response.registers[0]
|
register = response.registers[0]
|
||||||
|
|
||||||
return '{0:0>4X}'.format(register)
|
return '{0:0>4X}'.format(register)
|
||||||
|
|
||||||
|
|
||||||
def read_modbus_registers(modbus, slave_address, base_address=cfg.BASE_ADDRESS, count=cfg.NO_OF_REGISTERS):
|
def read_modbus_registers(modbus, slave_address, base_address=cfg.BASE_ADDRESS, count=cfg.NO_OF_REGISTERS):
|
||||||
# type: (Modbus, int, int, int) -> ReadInputRegistersResponse
|
# type: (Modbus, int, int, int) -> ReadInputRegistersResponse
|
||||||
|
|
||||||
logging.debug('requesting modbus registers {0}-{1}'.format(base_address, base_address + count))
|
logging.debug('requesting modbus registers {0}-{1}'.format(base_address, base_address + count))
|
||||||
|
|
||||||
return modbus.read_input_registers(
|
return modbus.read_input_registers(
|
||||||
address=base_address,
|
address=base_address,
|
||||||
count=count,
|
count=count,
|
||||||
unit=slave_address)
|
unit=slave_address)
|
||||||
|
|
||||||
|
|
||||||
def read_battery_status(modbus, battery):
|
def read_battery_status(modbus, battery):
|
||||||
# type: (Modbus, Battery) -> BatteryStatus
|
# type: (Modbus, Battery) -> BatteryStatus
|
||||||
"""
|
"""
|
||||||
Read the modbus registers containing the battery's status info.
|
Read the modbus registers containing the battery's status info.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
logging.debug('reading battery status')
|
logging.debug('reading battery status')
|
||||||
|
|
||||||
with modbus:
|
with modbus:
|
||||||
data = read_modbus_registers(modbus, battery.slave_address)
|
data = read_modbus_registers(modbus, battery.slave_address)
|
||||||
return BatteryStatus(battery, data.registers)
|
return BatteryStatus(battery, data.registers)
|
||||||
|
|
||||||
|
|
||||||
def publish_values_on_dbus(service, battery_signals, battery_statuses):
|
def publish_values_on_dbus(service, battery_signals, battery_statuses):
|
||||||
# type: (DBusService, Iterable[BatterySignal], Iterable[BatteryStatus]) -> ()
|
# type: (DBusService, Iterable[BatterySignal], Iterable[BatteryStatus]) -> ()
|
||||||
|
|
||||||
publish_individuals(service, battery_signals, battery_statuses)
|
publish_individuals(service, battery_signals, battery_statuses)
|
||||||
publish_aggregates(service, battery_signals, battery_statuses)
|
publish_aggregates(service, battery_signals, battery_statuses)
|
||||||
|
|
||||||
|
|
||||||
def publish_aggregates(service, signals, battery_statuses):
|
def publish_aggregates(service, signals, battery_statuses):
|
||||||
# type: (DBusService, Iterable[BatterySignal], Iterable[BatteryStatus]) -> ()
|
# type: (DBusService, Iterable[BatterySignal], Iterable[BatteryStatus]) -> ()
|
||||||
|
|
||||||
for s in signals:
|
for s in signals:
|
||||||
if s.aggregate is None:
|
if s.aggregate is None:
|
||||||
continue
|
continue
|
||||||
values = [s.get_value(battery_status) for battery_status in battery_statuses]
|
values = [s.get_value(battery_status) for battery_status in battery_statuses]
|
||||||
value = s.aggregate(values)
|
value = s.aggregate(values)
|
||||||
|
service.own_properties.set(s.dbus_path, value, s.unit)
|
||||||
service.own_properties.set(s.dbus_path, value, s.unit)
|
|
||||||
|
|
||||||
|
|
||||||
def publish_individuals(service, signals, battery_statuses):
|
def publish_individuals(service, signals, battery_statuses):
|
||||||
# type: (DBusService, Iterable[BatterySignal], Iterable[BatteryStatus]) -> ()
|
# type: (DBusService, Iterable[BatterySignal], Iterable[BatteryStatus]) -> ()
|
||||||
|
|
||||||
for signal in signals:
|
for signal in signals:
|
||||||
for battery_status in battery_statuses:
|
for battery_status in battery_statuses:
|
||||||
address = battery_status.battery.slave_address
|
address = battery_status.battery.slave_address
|
||||||
dbus_path = '/_Battery/' + str(address) + signal.dbus_path
|
dbus_path = '/_Battery/' + str(address) + signal.dbus_path
|
||||||
value = signal.get_value(battery_status)
|
value = signal.get_value(battery_status)
|
||||||
service.own_properties.set(dbus_path, value, signal.unit)
|
service.own_properties.set(dbus_path, value, signal.unit)
|
||||||
|
|
||||||
|
|
||||||
def publish_service_signals(service, signals):
|
def publish_service_signals(service, signals):
|
||||||
# type: (DBusService, Iterable[ServiceSignal]) -> NoReturn
|
# type: (DBusService, Iterable[ServiceSignal]) -> NoReturn
|
||||||
|
|
||||||
for signal in signals:
|
for signal in signals:
|
||||||
service.own_properties.set(signal.dbus_path, signal.value, signal.unit)
|
service.own_properties.set(signal.dbus_path, signal.value, signal.unit)
|
||||||
|
|
||||||
|
|
||||||
def upload_status_to_innovenergy(sock, statuses):
|
def upload_status_to_innovenergy(sock, statuses):
|
||||||
# type: (socket, Iterable[BatteryStatus]) -> bool
|
# type: (socket, Iterable[BatteryStatus]) -> bool
|
||||||
|
|
||||||
logging.debug('upload status')
|
logging.debug('upload status')
|
||||||
|
|
||||||
try:
|
try:
|
||||||
for s in statuses:
|
for s in statuses:
|
||||||
sock.sendto(s.serialize(), (cfg.INNOVENERGY_SERVER_IP, cfg.INNOVENERGY_SERVER_PORT))
|
sock.sendto(s.serialize(), (cfg.INNOVENERGY_SERVER_IP, cfg.INNOVENERGY_SERVER_PORT))
|
||||||
except:
|
except:
|
||||||
logging.debug('FAILED')
|
logging.debug('FAILED')
|
||||||
return False
|
return False
|
||||||
else:
|
else:
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
|
||||||
def print_usage():
|
def print_usage():
|
||||||
print ('Usage: ' + __file__ + ' <serial device>')
|
print ('Usage: ' + __file__ + ' <serial device>')
|
||||||
print ('Example: ' + __file__ + ' ttyUSB0')
|
print ('Example: ' + __file__ + ' ttyUSB0')
|
||||||
|
|
||||||
|
|
||||||
def parse_cmdline_args(argv):
|
def parse_cmdline_args(argv):
|
||||||
# type: (List[str]) -> str
|
# type: (List[str]) -> str
|
||||||
|
|
||||||
if len(argv) == 0:
|
if len(argv) == 0:
|
||||||
logging.info('missing command line argument for tty device')
|
logging.info('missing command line argument for tty device')
|
||||||
print_usage()
|
print_usage()
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
|
|
||||||
return argv[0]
|
return argv[0]
|
||||||
|
|
||||||
|
|
||||||
def reset_batteries(modbus, batteries):
|
def reset_batteries(modbus, batteries):
|
||||||
# type: (Modbus, Iterable[Battery]) -> NoReturn
|
# type: (Modbus, Iterable[Battery]) -> NoReturn
|
||||||
|
|
||||||
logging.info('Resetting batteries...')
|
logging.info('Resetting batteries...')
|
||||||
|
|
||||||
for battery in batteries:
|
for battery in batteries:
|
||||||
|
|
||||||
result = modbus.write_registers(RESET_REGISTER, [1], unit=battery.slave_address)
|
result = modbus.write_registers(RESET_REGISTER, [1], unit=battery.slave_address)
|
||||||
|
|
||||||
# expecting a ModbusIOException (timeout)
|
# expecting a ModbusIOException (timeout)
|
||||||
# BMS can no longer reply because it is already reset
|
# BMS can no longer reply because it is already reset
|
||||||
success = isinstance(result, ModbusIOException)
|
success = isinstance(result, ModbusIOException)
|
||||||
|
|
||||||
outcome = 'successfully' if success else 'FAILED to'
|
outcome = 'successfully' if success else 'FAILED to'
|
||||||
logging.info('Battery {0} {1} reset'.format(str(battery.slave_address), outcome))
|
logging.info('Battery {0} {1} reset'.format(str(battery.slave_address), outcome))
|
||||||
|
|
||||||
logging.info('Shutting down fz-sonick driver')
|
logging.info('Shutting down fz-sonick driver')
|
||||||
exit(0)
|
exit(0)
|
||||||
|
|
||||||
|
|
||||||
alive = True # global alive flag, watchdog_task clears it, update_task sets it
|
alive = True # global alive flag, watchdog_task clears it, update_task sets it
|
||||||
|
|
||||||
|
|
||||||
def create_update_task(modbus, service, batteries):
|
def create_update_task(modbus, service, batteries):
|
||||||
# type: (Modbus, DBusService, Iterable[Battery]) -> Callable[[],bool]
|
# type: (Modbus, DBusService, Iterable[Battery]) -> Callable[[],bool]
|
||||||
"""
|
"""
|
||||||
Creates an update task which runs the main update function
|
Creates an update task which runs the main update function
|
||||||
and resets the alive flag
|
and resets the alive flag
|
||||||
"""
|
"""
|
||||||
_socket = init_udp_socket()
|
_socket = init_udp_socket()
|
||||||
_signals = signals.init_battery_signals()
|
_signals = signals.init_battery_signals()
|
||||||
|
|
||||||
def update_task():
|
def update_task():
|
||||||
# type: () -> bool
|
# type: () -> bool
|
||||||
|
|
||||||
global alive
|
global alive
|
||||||
|
|
||||||
logging.debug('starting update cycle')
|
logging.debug('starting update cycle')
|
||||||
|
|
||||||
# Checking if we have excess power and if so charge batteries more
|
if service.own_properties.get('/ResetBatteries').value == 1:
|
||||||
|
reset_batteries(modbus, batteries)
|
||||||
|
|
||||||
target = service.remote_properties.get(get_service(SETTINGS_SERVICE_PREFIX) + '/Settings/CGwacs/AcPowerSetPoint').value or 0
|
statuses = [read_battery_status(modbus, battery) for battery in batteries]
|
||||||
actual = service.remote_properties.get(get_service(INVERTER_SERVICE_PREFIX) + '/Ac/Out/P').value or 0
|
|
||||||
|
|
||||||
if actual>target:
|
publish_values_on_dbus(service, _signals, statuses)
|
||||||
service.own_properties.set('/Info/MaxChargeCurrent').value = min([battery.i_max for battery in batteries])
|
upload_status_to_innovenergy(_socket, statuses)
|
||||||
|
|
||||||
if service.own_properties.get('/ResetBatteries').value == 1:
|
logging.debug('finished update cycle\n')
|
||||||
reset_batteries(modbus, batteries)
|
|
||||||
|
|
||||||
statuses = [read_battery_status(modbus, battery) for battery in batteries]
|
alive = True
|
||||||
|
|
||||||
publish_values_on_dbus(service, _signals, statuses)
|
return True
|
||||||
upload_status_to_innovenergy(_socket, statuses)
|
|
||||||
|
|
||||||
logging.debug('finished update cycle\n')
|
return update_task
|
||||||
|
|
||||||
alive = True
|
|
||||||
|
|
||||||
return True
|
|
||||||
|
|
||||||
return update_task
|
|
||||||
|
|
||||||
|
|
||||||
def create_watchdog_task(main_loop):
|
def create_watchdog_task(main_loop):
|
||||||
# type: (DBusGMainLoop) -> Callable[[],bool]
|
# type: (DBusGMainLoop) -> Callable[[],bool]
|
||||||
"""
|
"""
|
||||||
Creates a Watchdog task that monitors the alive flag.
|
Creates a Watchdog task that monitors the alive flag.
|
||||||
The watchdog kills the main loop if the alive flag is not periodically reset by the update task.
|
The watchdog kills the main loop if the alive flag is not periodically reset by the update task.
|
||||||
Who watches the watchdog?
|
Who watches the watchdog?
|
||||||
"""
|
"""
|
||||||
|
def watchdog_task():
|
||||||
|
# type: () -> bool
|
||||||
|
|
||||||
def watchdog_task():
|
global alive
|
||||||
# type: () -> bool
|
|
||||||
|
|
||||||
global alive
|
if alive:
|
||||||
|
logging.debug('watchdog_task: update_task is alive')
|
||||||
|
alive = False
|
||||||
|
return True
|
||||||
|
else:
|
||||||
|
logging.info('watchdog_task: killing main loop because update_task is no longer alive')
|
||||||
|
main_loop.quit()
|
||||||
|
return False
|
||||||
|
|
||||||
if alive:
|
return watchdog_task
|
||||||
logging.debug('watchdog_task: update_task is alive')
|
|
||||||
alive = False
|
|
||||||
return True
|
|
||||||
else:
|
|
||||||
logging.info('watchdog_task: killing main loop because update_task is no longer alive')
|
|
||||||
main_loop.quit()
|
|
||||||
return False
|
|
||||||
|
|
||||||
return watchdog_task
|
|
||||||
|
|
||||||
def get_service(self, prefix: str) -> Optional[unicode]:
|
|
||||||
service = next((s for s in self.available_services if s.startswith(prefix)), None)
|
|
||||||
if service is None:
|
|
||||||
raise Exception('no service matching ' + prefix + '* available')
|
|
||||||
|
|
||||||
return service
|
|
||||||
|
|
||||||
|
|
||||||
def main(argv):
|
def main(argv):
|
||||||
# type: (List[str]) -> ()
|
# type: (List[str]) -> ()
|
||||||
|
|
||||||
logging.basicConfig(level=cfg.LOG_LEVEL)
|
logging.basicConfig(level=cfg.LOG_LEVEL)
|
||||||
logging.info('starting ' + __file__)
|
logging.info('starting ' + __file__)
|
||||||
|
|
||||||
tty = parse_cmdline_args(argv)
|
tty = parse_cmdline_args(argv)
|
||||||
modbus = init_modbus(tty)
|
modbus = init_modbus(tty)
|
||||||
|
|
||||||
batteries = identify_batteries(modbus)
|
batteries = identify_batteries(modbus)
|
||||||
|
|
||||||
if len(batteries) <= 0:
|
if len(batteries) <= 0:
|
||||||
sys.exit(2)
|
sys.exit(2)
|
||||||
|
|
||||||
service = DBusService(service_name=cfg.SERVICE_NAME_PREFIX + tty)
|
service = DBusService(service_name=cfg.SERVICE_NAME_PREFIX + tty)
|
||||||
|
|
||||||
service.own_properties.set('/ResetBatteries', value=False, writable=True) # initial value = False
|
service.own_properties.set('/ResetBatteries', value=False, writable=True) # initial value = False
|
||||||
|
|
||||||
main_loop = GLib.MainLoop()
|
main_loop = gobject.MainLoop()
|
||||||
|
|
||||||
service_signals = signals.init_service_signals(batteries)
|
service_signals = signals.init_service_signals(batteries)
|
||||||
publish_service_signals(service, service_signals)
|
publish_service_signals(service, service_signals)
|
||||||
|
|
||||||
update_task = create_update_task(modbus, service, batteries)
|
update_task = create_update_task(modbus, service, batteries)
|
||||||
update_task() # run it right away, so that all props are initialized before anyone can ask
|
update_task() # run it right away, so that all props are initialized before anyone can ask
|
||||||
watchdog_task = create_watchdog_task(main_loop)
|
watchdog_task = create_watchdog_task(main_loop)
|
||||||
|
|
||||||
GLib.timeout_add(cfg.UPDATE_INTERVAL * 2, watchdog_task, priority = GLib.PRIORITY_LOW) # add watchdog first
|
gobject.timeout_add(cfg.UPDATE_INTERVAL * 2, watchdog_task, priority = gobject.PRIORITY_LOW) # add watchdog first
|
||||||
GLib.timeout_add(cfg.UPDATE_INTERVAL, update_task, priority = GLib.PRIORITY_LOW) # call update once every update_interval
|
gobject.timeout_add(cfg.UPDATE_INTERVAL, update_task, priority = gobject.PRIORITY_LOW) # call update once every update_interval
|
||||||
|
|
||||||
logging.info('starting gobject.MainLoop')
|
logging.info('starting gobject.MainLoop')
|
||||||
main_loop.run()
|
main_loop.run()
|
||||||
logging.info('gobject.MainLoop was shut down')
|
logging.info('gobject.MainLoop was shut down')
|
||||||
|
|
||||||
sys.exit(0xFF) # reaches this only on error
|
sys.exit(0xFF) # reaches this only on error
|
||||||
|
|
||||||
|
|
||||||
main(sys.argv[1:])
|
main(sys.argv[1:])
|
||||||
|
|
Loading…
Reference in New Issue