def main(): """ The main function runs a loop that waits for om bus calls, drives the leds and reads the switch. """ try: logger.info('Starting led service...') config = ConfigParser() config.read(constants.get_config_file()) i2c_address = int(config.get('OpenMotics', 'leds_i2c_address'), 16) led_controller = LedController(Hardware.get_i2c_device(), i2c_address, Hardware.get_gpio_input()) led_controller.start() led_controller.set_led(Hardware.Led.POWER, True) signal_request = {'stop': False} def stop(signum, frame): """ This function is called on SIGTERM. """ _ = signum, frame logger.info('Stopping led service...') led_controller.stop() logger.info('Stopping led service...Done') signal_request['stop'] = True signal(SIGTERM, stop) logger.info('Starting led service... Done') while not signal_request['stop']: time.sleep(1) except Exception as exception: logger.exception('Error starting led service: {0}'.format(exception))
def main(): """ The main function runs a loop that waits for dbus calls, drives the leds and reads the switch. """ try: config = ConfigParser() config.read(constants.get_config_file()) i2c_address = int(config.get('OpenMotics', 'leds_i2c_address'), 16) led_controller = LedController(Hardware.get_i2c_device(), i2c_address, Hardware.get_gpio_input()) led_controller.start() led_controller.set_led(Hardware.Led.POWER, True) DBusService('led_service', event_receiver=lambda *args, **kwargs: led_controller.event_receiver(*args, **kwargs), get_state=led_controller.get_state) LOGGER.log("Running led service.") mainloop = gobject.MainLoop() gobject.timeout_add(250, led_controller.drive_leds) gobject.timeout_add(250, led_controller.check_button) mainloop.run() except Exception as exception: LOGGER.log('Error starting led service: {0}'.format(exception))
def __init__(self, bus, path, i2c_device, i2c_address, input_button): dbus.service.Object.__init__(self, bus, path) self._i2c_device = i2c_device self._i2c_address = i2c_address self._input_button = input_button self._input_button_pressed_since = None self._network_enabled = False self._network_activity = False self._network_bytes = 0 self._serial_activity = {4: False, 5: False} self._enabled_leds = {} self._previous_leds = {} self._last_i2c_led_code = 0 self._authorized_mode = False self._authorized_timeout = 0 self._check_states_thread = None self._gpio_led_config = Hardware.get_gpio_led_config() self._i2c_led_config = Hardware.get_i2c_led_config() for led in self._gpio_led_config.keys() + self._i2c_led_config.keys(): self._enabled_leds[led] = False self._write_leds()
def main(): """ The main function runs a loop that waits for dbus calls, drives the leds and reads the switch. """ try: config = ConfigParser() config.read(constants.get_config_file()) dbus.mainloop.glib.DBusGMainLoop(set_as_default=True) system_bus = dbus.SystemBus() _ = dbus.service.BusName("com.openmotics.status", system_bus) # Initializes the bus # The above `_ = dbus...` need to be there, or the bus won't be initialized i2c_device = Hardware.get_i2c_device() i2c_address = int(config.get('OpenMotics', 'leds_i2c_address'), 16) status = StatusObject(system_bus, '/com/openmotics/status', i2c_device, i2c_address, Hardware.get_gpio_input()) status.start() status.set_led(Hardware.Led.POWER, True) LOGGER.log("Running led service.") mainloop = gobject.MainLoop() gobject.timeout_add(250, status.drive_leds) gobject.timeout_add(250, status.check_button) mainloop.run() except Exception as exception: LOGGER.log('Error starting led service: {0}'.format(exception))
def __init__(self, i2c_device, i2c_address, input_button): self._i2c_device = i2c_device self._i2c_address = i2c_address self._input_button = input_button self._input_button_pressed_since = None self._input_button_released = True self._ticks = 0 self._network_enabled = False self._network_activity = False self._network_bytes = 0 self._serial_activity = {4: False, 5: False} self._enabled_leds = {} self._previous_leds = {} self._last_i2c_led_code = 0 self._indicate_started = 0 self._indicate_pointer = 0 self._indicate_sequence = [True, False, False, False] self._authorized_mode = False self._authorized_timeout = 0 self._check_states_thread = None self._leds_thread = None self._button_thread = None self._last_run_i2c = 0 self._last_run_gpio = 0 self._last_state_check = 0 self._last_button_check = 0 self._running = False self._message_client = MessageClient('led_service') self._message_client.add_event_handler(self.event_receiver) self._message_client.set_state_handler(self.get_state) self._gpio_led_config = Hardware.get_gpio_led_config() self._i2c_led_config = Hardware.get_i2c_led_config() for led in self._gpio_led_config.keys() + self._i2c_led_config.keys(): self._enabled_leds[led] = False self._write_leds()
def __init__(self, i2c_device, i2c_address, input_button): self._i2c_device = i2c_device self._i2c_address = i2c_address self._input_button = input_button self._input_button_pressed_since = None self._input_button_released = True self._ticks = 0 self._network_enabled = False self._network_activity = False self._network_bytes = 0 self._serial_activity = {4: False, 5: False} self._enabled_leds = {} self._previous_leds = {} self._last_i2c_led_code = 0 self._indicate_started = 0 self._indicate_pointer = 0 self._indicate_sequence = [True, False, False, False] self._authorized_mode = False self._authorized_timeout = 0 self._check_states_thread = None self._last_run_i2c = 0 self._last_run_gpio = 0 self._last_state_check = 0 self._last_button_check = 0 self._gpio_led_config = Hardware.get_gpio_led_config() self._i2c_led_config = Hardware.get_i2c_led_config() for led in self._gpio_led_config.keys() + self._i2c_led_config.keys(): self._enabled_leds[led] = False self._write_leds()
class FrontpanelController(object): INDICATE_TIMEOUT = 30 AUTH_MODE_PRESS_DURATION = 5 AUTH_MODE_TIMEOUT = 60 BOARD_TYPE = Hardware.get_board_type() MAIN_INTERFACE = Hardware.get_main_interface() class Leds(object): EXPANSION = 'EXPANSION' STATUS_GREEN = 'STATUS_GREEN' STATUS_RED = 'STATUS_RED' CAN_STATUS_GREEN = 'CAN_STATUS_GREEN' CAN_STATUS_RED = 'CAN_STATUS_RED' CAN_COMMUNICATION = 'CAN_COMMUNICATION' P1 = 'P1' LAN_GREEN = 'LAN_GREEN' LAN_RED = 'LAN_RED' CLOUD = 'CLOUD' SETUP = 'SETUP' RELAYS_1_8 = 'RELAYS_1_8' RELAYS_9_16 = 'RELAYS_9_16' OUTPUTS_DIG_1_4 = 'OUTPUTS_DIG_1_4' OUTPUTS_DIG_5_7 = 'OUTPUTS_DIG_5_7' OUTPUTS_ANA_1_4 = 'OUTPUTS_ANA_1_4' INPUTS = 'INPUTS' POWER = 'POWER' ALIVE = 'ALIVE' VPN = 'VPN' COMMUNICATION_1 = 'COMMUNICATION_1' COMMUNICATION_2 = 'COMMUNICATION_2' class LedStates(object): OFF = 'OFF' BLINKING_25 = 'BLINKING_25' BLINKING_50 = 'BLINKING_50' BLINKING_75 = 'BLINKING_75' SOLID = 'SOLID' class Buttons(object): SELECT = 'SELECT' SETUP = 'SETUP' ACTION = 'ACTION' CAN_POWER = 'CAN_POWER' class ButtonStates(object): PRESSED = 'PRESSED' RELEASED = 'RELEASED' class SerialPorts(object): MASTER_API = 'MASTER_API' ENERGY = 'ENERGY' P1 = 'P1' @Inject def __init__(self, master_controller=INJECTED, power_communicator=INJECTED): # type: (MasterController, PowerCommunicator) -> None self._master_controller = master_controller self._power_communicator = power_communicator self._network_carrier = None self._network_activity = None self._network_activity_scan_counter = 0 self._network_bytes = 0 self._check_network_activity_thread = None self._authorized_mode = False self._authorized_mode_timeout = 0 self._indicate = False self._indicate_timeout = 0 self._master_stats = 0, 0 self._power_stats = 0, 0 @property def authorized_mode(self): # return Platform.get_platform() == Platform.Type.CORE_PLUS or self._authorized_mode # Needed to validate Brain+ with no front panel attached return self._authorized_mode def event_receiver(self, event, payload): if event == OMBusEvents.CLOUD_REACHABLE: self._report_cloud_reachable(payload) elif event == OMBusEvents.VPN_OPEN: self._report_vpn_open(payload) elif event == OMBusEvents.CONNECTIVITY: self._report_connectivity(payload) def start(self): self._check_network_activity_thread = DaemonThread( name='frontpanel', target=self._do_frontpanel_tasks, interval=0.5) self._check_network_activity_thread.start() def stop(self): if self._check_network_activity_thread is not None: self._check_network_activity_thread.stop() def _report_carrier(self, carrier): # type: (bool) -> None raise NotImplementedError() def _report_connectivity(self, connectivity): # type: (bool) -> None raise NotImplementedError() def _report_network_activity(self, activity): # type: (bool) -> None raise NotImplementedError() def _report_serial_activity(self, serial_port, activity): # type: (str, Optional[bool]) -> None raise NotImplementedError() def _report_cloud_reachable(self, reachable): # type: (bool) -> None raise NotImplementedError() def _report_vpn_open(self, vpn_open): # type: (bool) -> None raise NotImplementedError() def indicate(self): self._indicate = True self._indicate_timeout = time.time( ) + FrontpanelController.INDICATE_TIMEOUT def _do_frontpanel_tasks(self): # Check network activity try: with open( '/sys/class/net/{0}/carrier'.format( FrontpanelController.MAIN_INTERFACE), 'r') as fh_up: line = fh_up.read() carrier = int(line) == 1 carrier_changed = self._network_carrier != carrier if carrier_changed: self._network_carrier = carrier self._report_carrier(carrier) # Check network activity every second, or if the carrier changed if self._network_activity_scan_counter >= 9 or carrier_changed: self._network_activity_scan_counter = 0 network_activity = False if self._network_carrier: # There's no activity when there's no carrier with open('/proc/net/dev', 'r') as fh_stat: for line in fh_stat.readlines(): if FrontpanelController.MAIN_INTERFACE not in line: continue received, transmitted = 0, 0 parts = line.split() if len(parts) == 17: received = parts[1] transmitted = parts[9] elif len(parts) == 16: (_, received) = tuple(parts[0].split(':')) transmitted = parts[8] new_bytes = received + transmitted if self._network_bytes != new_bytes: self._network_bytes = new_bytes network_activity = True else: network_activity = False if self._network_activity != network_activity: self._report_network_activity(network_activity) self._network_activity = network_activity self._network_activity_scan_counter += 1 except Exception as exception: logger.error( 'Error while checking network activity: {0}'.format(exception)) # Monitor serial activity try: stats = self._master_controller.get_communication_statistics() new_master_stats = (stats['bytes_read'], stats['bytes_written']) activity = self._master_stats[0] != new_master_stats[ 0] or self._master_stats[1] != new_master_stats[1] self._report_serial_activity( FrontpanelController.SerialPorts.MASTER_API, activity) self._master_stats = new_master_stats if self._power_communicator is None: new_power_stats = 0, 0 else: stats = self._power_communicator.get_communication_statistics() new_power_stats = (stats['bytes_read'], stats['bytes_written']) activity = self._power_stats[0] != new_power_stats[ 0] or self._power_stats[1] != new_power_stats[1] self._report_serial_activity( FrontpanelController.SerialPorts.ENERGY, activity) self._power_stats = new_power_stats activity = None # type: Optional[bool] # TODO: Load P1/RS232 activity self._report_serial_activity(FrontpanelController.SerialPorts.P1, activity) except Exception as exception: logger.error( 'Error while checking serial activity: {0}'.format(exception)) # Clear indicate timeout if time.time() > self._indicate_timeout: self._indicate = False
class FrontpanelClassicController(FrontpanelController): IOCTL_I2C_SLAVE = 0x0703 BOARD_TYPE = Hardware.get_board_type() ACTION_BUTTON_GPIO = 38 if BOARD_TYPE == Hardware.BoardType.BB else 26 BUTTON = FrontpanelController.Buttons.ACTION AUTH_MODE_LEDS = [ FrontpanelController.Leds.ALIVE, FrontpanelController.Leds.CLOUD, FrontpanelController.Leds.VPN, FrontpanelController.Leds.COMMUNICATION_1, FrontpanelController.Leds.COMMUNICATION_2 ] if not BOARD_TYPE == Hardware.BoardType.BB: GPIO_LED_CONFIG = { FrontpanelController.Leds.POWER: 60, FrontpanelController.Leds.STATUS_RED: 48 } I2C_LED_CONFIG = { FrontpanelController.Leds.COMMUNICATION_1: 64, FrontpanelController.Leds.COMMUNICATION_2: 128, FrontpanelController.Leds.VPN: 16, FrontpanelController.Leds.ALIVE: 1, FrontpanelController.Leds.CLOUD: 4 } else: GPIO_LED_CONFIG = { FrontpanelController.Leds.POWER: 75, FrontpanelController.Leds.STATUS_RED: 60, FrontpanelController.Leds.ALIVE: 49 } I2C_LED_CONFIG = { FrontpanelController.Leds.COMMUNICATION_1: 64, FrontpanelController.Leds.COMMUNICATION_2: 128, FrontpanelController.Leds.VPN: 16, FrontpanelController.Leds.CLOUD: 4 } I2C_DEVICE = '/dev/i2c-2' if BOARD_TYPE == Hardware.BoardType.BB else '/dev/i2c-1' ALL_LEDS = [ FrontpanelController.Leds.POWER, FrontpanelController.Leds.STATUS_RED, FrontpanelController.Leds.COMMUNICATION_1, FrontpanelController.Leds.COMMUNICATION_2, FrontpanelController.Leds.VPN, FrontpanelController.Leds.ALIVE, FrontpanelController.Leds.CLOUD ] BLINK_SEQUENCE = { FrontpanelController.LedStates.OFF: [], FrontpanelController.LedStates.BLINKING_25: [0], FrontpanelController.LedStates.BLINKING_50: [0, 1], FrontpanelController.LedStates.BLINKING_75: [0, 1, 2], FrontpanelController.LedStates.SOLID: [0, 1, 2, 3] } @Inject def __init__(self, leds_i2c_address=INJECTED): # type: (int) -> None super(FrontpanelClassicController, self).__init__() self._leds_i2c_address = leds_i2c_address self._button_states = {} # type: Dict[str, bool] self._poll_button_thread = None self._write_leds_thread = None self._enabled_leds = {} # type: Dict[str, str] self._previous_leds = {} # type: Dict[str, bool] self._last_i2c_led_code = None # type: Optional[int] self._button_pressed_since = None # type: Optional[float] self._button_released = False self._blink_counter = 0 def _poll_button(self): # Check new state with open( '/sys/class/gpio/gpio{0}/value'.format( FrontpanelClassicController.ACTION_BUTTON_GPIO), 'r') as fh_inp: line = fh_inp.read() button_pressed = int(line) == 0 self._button_states[ FrontpanelClassicController.BUTTON] = button_pressed # Check for authorized mode if not button_pressed: self._button_released = True if self._authorized_mode: if time.time() > self._authorized_mode_timeout or ( button_pressed and self._button_released): self._authorized_mode = False else: if button_pressed: self._button_released = False if self._button_pressed_since is None: self._button_pressed_since = time.time() if time.time( ) - self._button_pressed_since > FrontpanelController.AUTH_MODE_PRESS_DURATION: self._authorized_mode = True self._authorized_mode_timeout = time.time( ) + FrontpanelController.AUTH_MODE_TIMEOUT self._button_pressed_since = None else: self._button_pressed_since = None def start(self): super(FrontpanelClassicController, self).start() # Enable power led self._enabled_leds[FrontpanelController.Leds. POWER] = FrontpanelController.LedStates.SOLID # Start polling/writing threads self._poll_button_thread = DaemonThread(name='buttonpoller', target=self._poll_button, interval=0.25) self._poll_button_thread.start() self._write_leds_thread = DaemonThread(name='ledwriter', target=self._write_leds, interval=0.25) self._write_leds_thread.start() def stop(self): super(FrontpanelClassicController, self).stop() if self._poll_button_thread is not None: self._poll_button_thread.stop() if self._write_leds_thread is not None: self._write_leds_thread.stop() def _report_carrier(self, carrier): # type: (bool) -> None state = FrontpanelController.LedStates.OFF if carrier else FrontpanelController.LedStates.SOLID self._enabled_leds[FrontpanelController.Leds.STATUS_RED] = state def _report_connectivity(self, connectivity): # type: (bool) -> None pass # No support for connectivity def _report_network_activity(self, activity): # type: (bool) -> None state = FrontpanelController.LedStates.BLINKING_50 if activity else FrontpanelController.LedStates.OFF self._enabled_leds[FrontpanelController.Leds.ALIVE] = state def _report_serial_activity(self, serial_port, activity): # type: (str, Optional[bool]) -> None led = { FrontpanelController.SerialPorts.ENERGY: FrontpanelController.Leds.COMMUNICATION_1, FrontpanelController.SerialPorts.MASTER_API: FrontpanelController.Leds.COMMUNICATION_2 }.get(serial_port) if led is None: return state = FrontpanelController.LedStates.BLINKING_50 if activity else FrontpanelController.LedStates.OFF self._enabled_leds[led] = state def _report_cloud_reachable(self, reachable): # type: (bool) -> None state = FrontpanelController.LedStates.SOLID if reachable else FrontpanelController.LedStates.OFF self._enabled_leds[FrontpanelController.Leds.CLOUD] = state def _report_vpn_open(self, vpn_open): # type: (bool) -> None state = FrontpanelController.LedStates.SOLID if vpn_open else FrontpanelController.LedStates.OFF self._enabled_leds[FrontpanelController.Leds.VPN] = state def _write_leds(self): # Override for indicate if self._indicate: self._enabled_leds[ FrontpanelController.Leds. STATUS_RED] = FrontpanelController.LedStates.BLINKING_25 # Map blinking states current_leds = self._map_states() # Drive I2C leds try: code = 0x0 for led in FrontpanelClassicController.I2C_LED_CONFIG: if current_leds.get(led, False) is True: code |= FrontpanelClassicController.I2C_LED_CONFIG[led] if self._authorized_mode: # Light all leds in authorized mode for led in FrontpanelClassicController.AUTH_MODE_LEDS: code |= FrontpanelClassicController.I2C_LED_CONFIG.get( led, 0x0) code = (~code) & 0xFF # Push code if needed if code != self._last_i2c_led_code: self._last_i2c_led_code = code with open(FrontpanelClassicController.I2C_DEVICE, 'r+', 1) as i2c: fcntl.ioctl(i2c, FrontpanelClassicController.IOCTL_I2C_SLAVE, self._leds_i2c_address) i2c.write(chr(code)) except Exception as ex: logger.error('Error while writing to i2c: {0}'.format(ex)) # Drive GPIO leds try: for led in FrontpanelClassicController.GPIO_LED_CONFIG: on = current_leds.get(led, False) if self._previous_leds.get(led) != on: self._previous_leds[led] = on try: gpio = FrontpanelClassicController.GPIO_LED_CONFIG[led] with open('/sys/class/gpio/gpio{0}/value'.format(gpio), 'w') as fh_s: fh_s.write('1' if on else '0') except IOError: pass # The GPIO doesn't exist or is read only except Exception as ex: logger.error('Error while writing to GPIO: {0}'.format(ex)) def _map_states(self): # type: () -> Dict[str, bool] current_leds = {} # type: Dict[str, bool] for led in FrontpanelClassicController.ALL_LEDS: requested_state = self._enabled_leds.get( led, FrontpanelController.LedStates.OFF) if requested_state == FrontpanelController.LedStates.OFF: current_leds[led] = False else: current_leds[ led] = self._blink_counter in FrontpanelClassicController.BLINK_SEQUENCE[ requested_state] self._blink_counter += 1 if self._blink_counter >= 4: self._blink_counter = 0 return current_leds