def test_crc_checking(self):
        """ Test the crc checking in the MasterCommunciator. """
        action = master_api.sensor_humidity_list()

        out_fields = {}
        for i in range(0, 32):
            out_fields['hum%d' % i] = master_api.Svt(master_api.Svt.RAW, i)
        out_fields['crc'] = [ord('C'), 1, 240]

        out_fields2 = {}
        for i in range(0, 32):
            out_fields2['hum%d' % i] = master_api.Svt(master_api.Svt.RAW, 2 * i)
        out_fields2['crc'] = [ord('C'), 0, 0]

        serial_mock = SerialMock([sin(action.create_input(1)),
                                  sout(action.create_output(1, out_fields)),
                                  sin(action.create_input(2)),
                                  sout(action.create_output(2, out_fields2))])

        comm = MasterCommunicator(serial_mock, init_master=False)
        comm.start()

        output = comm.do_command(action)
        self.assertEquals('\x00', output['hum0'].get_byte())
        self.assertEquals('\x01', output['hum1'].get_byte())

        self.assertRaises(CrcCheckFailedException, lambda: comm.do_command(action))
    def test_background_consumer(self):
        """ Test the background consumer mechanism. """
        action = master_api.basic_action()
        in_fields = {"action_type": 1, "action_number": 2}
        out_fields = {"resp": "OK"}

        serial_mock = SerialMock([
                        sout("OL\x00\x01\x03\x0c\r\n"), sin(action.create_input(1, in_fields)),
                        sout("junkOL\x00\x02\x03\x0c\x05\x06\r\n here"),
                        sout(action.create_output(1, out_fields))])

        comm = MasterCommunicator(serial_mock, init_master=False)
        comm.enable_passthrough()

        got_output = {"phase": 1}

        def callback(output):
            """ Callback that check if the correct result was returned for OL. """
            if got_output["phase"] == 1:
                self.assertEquals([(3, int(12 * 10.0 / 6.0))], output["outputs"])
                got_output["phase"] = 2
            elif got_output["phase"] == 2:
                self.assertEquals([(3, int(12 * 10.0 / 6.0)), (5, int(6 * 10.0 / 6.0))],
                                  output["outputs"])
                got_output["phase"] = 3

        comm.register_consumer(BackgroundConsumer(master_api.output_list(), 0, callback))
        comm.start()

        self.assertEquals("OK", comm.do_command(action, in_fields)["resp"])
        self.assertEquals(3, got_output["phase"])
        self.assertEquals("junk here", comm.get_passthrough_data())
    def test_watchdog(self):
        """ Test the watchdog. """
        action = master_api.basic_action()
        in_fields = {"action_type": 1, "action_number": 2}

        serial_mock = SerialMock([
            sin(action.create_input(1, in_fields)),
            sin(action.create_input(2, in_fields)),
            sin(action.create_input(3, in_fields))
        ])

        timeout = False
        watchdog = {}

        def callback():
            """ Callback for the watchdog """
            watchdog['done'] = True

        comm = MasterCommunicator(serial_mock,
                                  init_master=False,
                                  watchdog_period=0.5,
                                  watchdog_callback=callback)
        comm.start()

        try:
            comm.do_command(action, in_fields, timeout=0.1)
        except CommunicationTimedOutException:
            timeout = True

        time.sleep(1)

        self.assertTrue(timeout)
        self.assertFalse('done' in watchdog)

        timeout = False
        try:
            comm.do_command(action, in_fields, timeout=0.1)
        except CommunicationTimedOutException:
            timeout = True

        self.assertTrue(timeout)

        timeout = False
        try:
            comm.do_command(action, in_fields, timeout=0.1)
        except CommunicationTimedOutException:
            timeout = True

        time.sleep(1.5)

        self.assertTrue(timeout)
        self.assertTrue('done' in watchdog)
    def test_do_command(self):
        """ Test for standard behavior MasterCommunicator.do_command. """
        action = master_api.basic_action()
        in_fields = {"action_type": 1, "action_number": 2}
        out_fields = {"resp": "OK"}

        serial_mock = SerialMock(
                        [sin(action.create_input(1, in_fields)),
                         sout(action.create_output(1, out_fields))])

        comm = MasterCommunicator(serial_mock, init_master=False)
        comm.start()

        output = comm.do_command(action, in_fields)
        self.assertEquals("OK", output["resp"])
    def test_do_command_timeout(self):
        """ Test for timeout in MasterCommunicator.do_command. """
        action = master_api.basic_action()
        in_fields = {"action_type": 1, "action_number": 2}

        serial_mock = SerialMock([sin(action.create_input(1, in_fields))])

        comm = MasterCommunicator(serial_mock, init_master=False)
        comm.start()

        try:
            comm.do_command(action, in_fields, timeout=0.1)
            self.assertTrue(False)
        except CommunicationTimedOutException:
            pass
    def test_send_passthrough_data(self):
        """ Test the passthrough if no other communications are going on. """
        pt_input = "data from passthrough"
        pt_output = "got it !"
        serial_mock = SerialMock([sin(pt_input), sout(pt_output)])

        comm = MasterCommunicator(serial_mock, init_master=False)
        comm.enable_passthrough()
        comm.start()

        comm.send_passthrough_data(pt_input)
        self.assertEquals(pt_output, comm.get_passthrough_data())
    def test_do_command(self):
        """ Test for standard behavior MasterCommunicator.do_command. """
        action = master_api.basic_action()
        in_fields = {"action_type": 1, "action_number": 2}
        out_fields = {"resp": "OK"}

        serial_mock = SerialMock([
            sin(action.create_input(1, in_fields)),
            sout(action.create_output(1, out_fields))
        ])

        comm = MasterCommunicator(serial_mock, init_master=False)
        comm.start()

        output = comm.do_command(action, in_fields)
        self.assertEquals("OK", output["resp"])
예제 #8
0
    def test_passthrough(self):
        """ Test the passthrough. """
        master_mock = SerialMock([
                        sout("data for the passthrough"), sin("response"),
                        sout("more data"), sin("more response")])

        passthrough_mock = SerialMock([
                        sin("data for the passthrough"), sout("response"),
                        sin("more data"), sout("more response")])

        master_communicator = MasterCommunicator(master_mock, init_master=False)
        master_communicator.enable_passthrough()
        master_communicator.start()

        passthrough = PassthroughService(master_communicator, passthrough_mock)
        passthrough.start()

        time.sleep(1)

        self.assertEquals(33, master_communicator.get_bytes_read())
        self.assertEquals(21, master_communicator.get_bytes_written())

        self.assertEquals(33, master_mock.bytes_read)
        self.assertEquals(21, master_mock.bytes_written)

        self.assertEquals(21, passthrough_mock.bytes_read)
        self.assertEquals(33, passthrough_mock.bytes_written)

        passthrough.stop()
    def test_send_passthrough_data(self):
        """ Test the passthrough if no other communications are going on. """
        pt_input = "data from passthrough"
        pt_output = "got it !"
        serial_mock = SerialMock([sin(pt_input), sout(pt_output)])

        comm = MasterCommunicator(serial_mock, init_master=False)
        comm.enable_passthrough()
        comm.start()

        comm.send_passthrough_data(pt_input)
        self.assertEquals(pt_output, comm.get_passthrough_data())
예제 #10
0
    def test_do_command_split_data(self):
        """ Test MasterCommunicator.do_command when the data is split over multiple reads. """
        action = master_api.basic_action()
        in_fields = {"action_type": 1, "action_number": 2}
        out_fields = {"resp": "OK"}

        sequence = []
        for i in range(1, 18):
            sequence.append(sin(action.create_input(i, in_fields)))
            output_bytes = action.create_output(i, out_fields)
            sequence.append(sout(output_bytes[:i]))
            sequence.append(sout(output_bytes[i:]))

        serial_mock = SerialMock(sequence)

        comm = MasterCommunicator(serial_mock, init_master=False)
        comm.start()

        for i in range(1, 18):
            self.assertEquals("OK", comm.do_command(action, in_fields)["resp"])
    def test_do_command_split_data(self):
        """ Test MasterCommunicator.do_command when the data is split over multiple reads. """
        action = master_api.basic_action()
        in_fields = {"action_type": 1, "action_number": 2}
        out_fields = {"resp": "OK"}

        sequence = []
        for i in range(1, 18):
            sequence.append(sin(action.create_input(i, in_fields)))
            output_bytes = action.create_output(i, out_fields)
            sequence.append(sout(output_bytes[:i]))
            sequence.append(sout(output_bytes[i:]))

        serial_mock = SerialMock(sequence)

        comm = MasterCommunicator(serial_mock, init_master=False)
        comm.start()

        for i in range(1, 18):
            self.assertEquals("OK", comm.do_command(action, in_fields)["resp"])
예제 #12
0
    def test_passthrough_output(self):
        """ Test the passthrough output if no other communications are going on. """
        serial_mock = SerialMock(
            [sout("passthrough"),
             sout(" my "), sout("data")])

        comm = MasterCommunicator(serial_mock, init_master=False)
        comm.enable_passthrough()
        comm.start()

        self.assertEquals("passthrough", comm.get_passthrough_data())
        self.assertEquals(" my ", comm.get_passthrough_data())
        self.assertEquals("data", comm.get_passthrough_data())
예제 #13
0
    def test_bytes_counter(self):
        """ Test the number of bytes written and read from the serial port. """
        action = master_api.basic_action()
        in_fields = {"action_type": 1, "action_number": 2}
        out_fields = {"resp": "OK"}

        serial_mock = SerialMock([
            sin(action.create_input(1, in_fields)),
            sout("hello"),
            sout(action.create_output(1, out_fields))
        ])

        comm = MasterCommunicator(serial_mock, init_master=False)
        comm.enable_passthrough()
        comm.start()

        self.assertEquals("OK", comm.do_command(action, in_fields)["resp"])
        self.assertEquals("hello", comm.get_passthrough_data())

        self.assertEquals(21, comm.get_bytes_written())
        self.assertEquals(5 + 18, comm.get_bytes_read())
예제 #14
0
    def test_passthrough(self):
        """ Test the passthrough. """
        master_mock = SerialMock([
            sout("data for the passthrough"),
            sin("response"),
            sout("more data"),
            sin("more response")
        ])

        passthrough_mock = SerialMock([
            sin("data for the passthrough"),
            sout("response"),
            sin("more data"),
            sout("more response")
        ])

        master_communicator = MasterCommunicator(master_mock,
                                                 init_master=False)
        master_communicator.start()

        passthrough = PassthroughService(master_communicator, passthrough_mock)
        passthrough.start()

        time.sleep(1)

        self.assertEquals(33, master_communicator.get_bytes_read())
        self.assertEquals(21, master_communicator.get_bytes_written())

        self.assertEquals(33, master_mock.bytes_read)
        self.assertEquals(21, master_mock.bytes_written)

        self.assertEquals(21, passthrough_mock.bytes_read)
        self.assertEquals(33, passthrough_mock.bytes_written)

        passthrough.stop()
예제 #15
0
    def test_crc_checking(self):
        """ Test the crc checking in the MasterCommunciator. """
        action = master_api.sensor_humidity_list()

        out_fields = {}
        for i in range(0, 32):
            out_fields['hum%d' % i] = master_api.Svt(master_api.Svt.RAW, i)
        out_fields['crc'] = [ord('C'), 1, 240]

        out_fields2 = {}
        for i in range(0, 32):
            out_fields2['hum%d' % i] = master_api.Svt(master_api.Svt.RAW,
                                                      2 * i)
        out_fields2['crc'] = [ord('C'), 0, 0]

        serial_mock = SerialMock([
            sin(action.create_input(1)),
            sout(action.create_output(1, out_fields)),
            sin(action.create_input(2)),
            sout(action.create_output(2, out_fields2))
        ])

        comm = MasterCommunicator(serial_mock, init_master=False)
        comm.start()

        output = comm.do_command(action)
        self.assertEquals('\x00', output['hum0'].get_byte())
        self.assertEquals('\x01', output['hum1'].get_byte())

        self.assertRaises(CrcCheckFailedException,
                          lambda: comm.do_command(action))
    def test_passthrough_output(self):
        """ Test the passthrough output if no other communications are going on. """
        serial_mock = SerialMock([sout("passthrough"), sout(" my "), sout("data")])

        comm = MasterCommunicator(serial_mock, init_master=False)
        comm.enable_passthrough()
        comm.start()

        self.assertEquals("passthrough", comm.get_passthrough_data())
        self.assertEquals(" my ", comm.get_passthrough_data())
        self.assertEquals("data", comm.get_passthrough_data())
예제 #17
0
    def test_background_consumer(self):
        """ Test the background consumer mechanism. """
        action = master_api.basic_action()
        in_fields = {"action_type": 1, "action_number": 2}
        out_fields = {"resp": "OK"}

        serial_mock = SerialMock([
            sout("OL\x00\x01\x03\x0c\r\n"),
            sin(action.create_input(1, in_fields)),
            sout("junkOL\x00\x02\x03\x0c\x05\x06\r\n here"),
            sout(action.create_output(1, out_fields))
        ])
        SetUpTestInjections(controller_serial=serial_mock)

        comm = MasterCommunicator(init_master=False)
        comm.enable_passthrough()

        got_output = {"phase": 1}

        def callback(output):
            """ Callback that check if the correct result was returned for OL. """
            if got_output["phase"] == 1:
                self.assertEquals([(3, int(12 * 10.0 / 6.0))],
                                  output["outputs"])
                got_output["phase"] = 2
            elif got_output["phase"] == 2:
                self.assertEquals([(3, int(12 * 10.0 / 6.0)),
                                   (5, int(6 * 10.0 / 6.0))],
                                  output["outputs"])
                got_output["phase"] = 3

        comm.register_consumer(
            BackgroundConsumer(master_api.output_list(), 0, callback))
        comm.start()

        self.assertEquals("OK", comm.do_command(action, in_fields)["resp"])
        self.assertEquals(3, got_output["phase"])
        self.assertEquals("junk here", comm.get_passthrough_data())
    def test_bytes_counter(self):
        """ Test the number of bytes written and read from the serial port. """
        action = master_api.basic_action()
        in_fields = {"action_type": 1, "action_number": 2}
        out_fields = {"resp": "OK"}

        serial_mock = SerialMock(
                        [sin(action.create_input(1, in_fields)),
                         sout("hello"),
                         sout(action.create_output(1, out_fields))])

        comm = MasterCommunicator(serial_mock, init_master=False)
        comm.enable_passthrough()
        comm.start()

        self.assertEquals("OK", comm.do_command(action, in_fields)["resp"])
        self.assertEquals("hello", comm.get_passthrough_data())

        self.assertEquals(21, comm.get_bytes_written())
        self.assertEquals(5 + 18, comm.get_bytes_read())
예제 #19
0
    def test_background_consumer_passthrough(self):
        """ Test the background consumer with passing the data to the passthrough. """
        serial_mock = SerialMock([sout("OL\x00\x01"), sout("\x03\x0c\r\n")])
        comm = MasterCommunicator(serial_mock, init_master=False)
        comm.enable_passthrough()

        got_output = {"passed": False}

        def callback(output):
            """ Callback that check if the correct result was returned for OL. """
            self.assertEquals([(3, int(12 * 10.0 / 6.0))], output["outputs"])
            got_output["passed"] = True

        comm.register_consumer(
            BackgroundConsumer(master_api.output_list(), 0, callback, True))
        comm.start()

        self.assertEquals(True, got_output["passed"])
        self.assertEquals("OL\x00\x01\x03\x0c\r\n",
                          comm.get_passthrough_data())
예제 #20
0
def bootload_modules(type, filename, verbose, logger):
    """ Bootload all modules of the given type with the firmware in the given filename.

    :param type: Type of the modules (o, d, i, t, c)
    :type type: chr
    :param filename: The filename for the hex file to load
    :type filename: string
    :param verbose: If true the serial communication is printed.
    :param verbose: boolean
    """
    config = ConfigParser()
    config.read(constants.get_config_file())

    port = config.get('OpenMotics', 'controller_serial')

    master_serial = Serial(port, 115200)
    master_communicator = MasterCommunicator(master_serial, verbose=verbose)
    master_communicator.start()

    addresses = get_module_addresses(master_communicator, type)

    blocks = 922 if type == 'c' else 410
    ihex = intelhex.IntelHex(filename)
    crc = calc_crc(ihex, blocks)

    success = True
    for address in addresses:
        logger("Bootloading module %s" % pretty_address(address))
        try:
            bootload(master_communicator, address, ihex, crc, blocks, logger)
        except Exception as exception:
            success = False
            logger("Bootloading failed")
            traceback.print_exc()

    return success
예제 #21
0
    def test_pulse_counter_status(self):
        action = master_api.pulse_list()

        in_fields = {}
        out_fields = {'pv0': 0, 'pv1': 1, 'pv2': 2, 'pv3': 3, 'pv4': 4, 'pv5': 5, 'pv6': 6, 'pv7': 7,
                      'pv8': 8, 'pv9': 9, 'pv10': 10, 'pv11': 11, 'pv12': 12, 'pv13': 13, 'pv14': 14,
                      'pv15': 15, 'pv16': 16, 'pv17': 17, 'pv18': 18, 'pv19': 19, 'pv20': 20, 'pv21': 21,
                      'pv22': 22, 'pv23': 23, 'crc': [67, 1, 20]}

        serial_mock = SerialMock([sin(action.create_input(1, in_fields)),
                                  sout(action.create_output(1, out_fields))])

        master_communicator = MasterCommunicator(serial_mock, init_master=False)
        master_communicator.start()

        controller = self._get_controller(master_communicator)
        controller.set_pulse_counter_amount(26)
        controller.set_pulse_counter_status(24, 123)
        controller.set_pulse_counter_status(25, 456)

        status = controller.get_pulse_counter_status()
        self.assertEquals(range(0, 24) + [123, 456], status)

        # Set pulse counter for unexisting pulse counter
        try:
            controller.set_pulse_counter_status(26, 789)
            self.fail('Exception should have been thrown')
        except ValueError as e:
            self.assertEquals('Could not find pulse counter 26', str(e))

        # Set pulse counter for physical pulse counter
        try:
            controller.set_pulse_counter_status(23, 789)
            self.fail('Exception should have been thrown')
        except ValueError as e:
            self.assertEquals('Cannot set pulse counter status for 23 (should be > 23)', str(e))
    def test_background_consumer_passthrough(self):
        """ Test the background consumer with passing the data to the passthrough. """
        serial_mock = SerialMock([sout("OL\x00\x01"), sout("\x03\x0c\r\n")])
        comm = MasterCommunicator(serial_mock, init_master=False)
        comm.enable_passthrough()

        got_output = {"passed": False}

        def callback(output):
            """ Callback that check if the correct result was returned for OL. """
            self.assertEquals([(3, int(12 * 10.0 / 6.0))], output["outputs"])
            got_output["passed"] = True

        comm.register_consumer(BackgroundConsumer(master_api.output_list(), 0, callback, True))
        comm.start()

        MasterCommunicatorTest._wait_for_callback(True, got_output, 3)
        self.assertEquals(True, got_output["passed"])
        self.assertEquals("OL\x00\x01\x03\x0c\r\n", comm.get_passthrough_data())
예제 #23
0
    def test_passthrough(self):
        """ Test the passthrough. """
        master_mock = SerialMock([
            sout("data for the passthrough"),
            sin("response"),
            sout("more data"),
            sin("more response")
        ])
        passthrough_mock = SerialMock([
            sin("data for the passthrough"),
            sout("response"),
            sin("more data"),
            sout("more response")
        ])
        SetUpTestInjections(controller_serial=master_mock,
                            passthrough_serial=passthrough_mock)

        master_communicator = MasterCommunicator(init_master=False)
        master_communicator.enable_passthrough()
        master_communicator.start()

        SetUpTestInjections(master_communicator=master_communicator)

        passthrough = PassthroughService()
        passthrough.start()

        time.sleep(1)

        self.assertEquals(
            33,
            master_communicator.get_communication_statistics()['bytes_read'])
        self.assertEquals(
            21,
            master_communicator.get_communication_statistics()
            ['bytes_written'])

        self.assertEquals(33, master_mock.bytes_read)
        self.assertEquals(21, master_mock.bytes_written)

        self.assertEquals(21, passthrough_mock.bytes_read)
        self.assertEquals(33, passthrough_mock.bytes_written)

        passthrough.stop()
예제 #24
0
    def test_do_command_timeout(self):
        """ Test for timeout in MasterCommunicator.do_command. """
        action = master_api.basic_action()
        in_fields = {"action_type": 1, "action_number": 2}

        serial_mock = SerialMock([sin(action.create_input(1, in_fields))])

        comm = MasterCommunicator(serial_mock, init_master=False)
        comm.start()

        try:
            comm.do_command(action, in_fields, timeout=0.1)
            self.assertTrue(False)
        except CommunicationTimedOutException:
            pass
예제 #25
0
    def test_do_command_timeout_test_ongoing(self):
        """ Test if communication resumes after timeout. """
        action = master_api.basic_action()
        in_fields = {"action_type": 1, "action_number": 2}
        out_fields = {"resp": "OK"}

        serial_mock = SerialMock([
            sin(action.create_input(1, in_fields)),
            sin(action.create_input(2, in_fields)),
            sout(action.create_output(2, out_fields))
        ])

        comm = MasterCommunicator(serial_mock, init_master=False)
        comm.start()

        try:
            comm.do_command(action, in_fields, timeout=0.1)
            self.assertTrue(False)
        except CommunicationTimedOutException:
            pass

        output = comm.do_command(action, in_fields)
        self.assertEquals("OK", output["resp"])
    def test_do_command_timeout_test_ongoing(self):
        """ Test if communication resumes after timeout. """
        action = master_api.basic_action()
        in_fields = {"action_type": 1, "action_number": 2}
        out_fields = {"resp": "OK"}

        serial_mock = SerialMock([sin(action.create_input(1, in_fields)),
                                  sin(action.create_input(2, in_fields)),
                                  sout(action.create_output(2, out_fields))])

        comm = MasterCommunicator(serial_mock, init_master=False)
        comm.start()

        try:
            comm.do_command(action, in_fields, timeout=0.1)
            self.assertTrue(False)
        except CommunicationTimedOutException:
            pass

        output = comm.do_command(action, in_fields)
        self.assertEquals("OK", output["resp"])
예제 #27
0
def main():
    """ Main function. """
    config = ConfigParser()
    config.read(constants.get_config_file())

    defaults = {
        'username': config.get('OpenMotics', 'cloud_user'),
        'password': config.get('OpenMotics', 'cloud_pass')
    }

    user_controller = UserController(constants.get_user_database_file(),
                                     defaults, 3600)

    led_service = LedService()

    controller_serial_port = config.get('OpenMotics', 'controller_serial')
    passthrough_serial_port = config.get('OpenMotics', 'passthrough_serial')
    power_serial_port = config.get('OpenMotics', 'power_serial')

    controller_serial = Serial(controller_serial_port, 115200)
    passthrough_serial = Serial(passthrough_serial_port, 115200)
    power_serial = RS485(Serial(power_serial_port, 115200, timeout=None))

    master_communicator = MasterCommunicator(controller_serial)
    master_communicator.start()

    power_controller = PowerController(constants.get_power_database_file())

    power_communicator = PowerCommunicator(power_serial, power_controller)
    power_communicator.start()

    gateway_api = GatewayApi(master_communicator, power_communicator,
                             power_controller)

    maintenance_service = MaintenanceService(
        gateway_api, constants.get_ssl_private_key_file(),
        constants.get_ssl_certificate_file())

    passthrough_service = PassthroughService(master_communicator,
                                             passthrough_serial)
    passthrough_service.start()

    web_interface = WebInterface(user_controller, gateway_api,
                                 constants.get_scheduling_database_file(),
                                 maintenance_service,
                                 led_service.in_authorized_mode)

    plugin_controller = PluginController(web_interface)
    plugin_controller.start_plugins()

    web_interface.set_plugin_controller(plugin_controller)
    gateway_api.set_plugin_controller(plugin_controller)

    web_service = WebService(web_interface)
    web_service.start()

    led_service.set_led('stat2', True)

    led_thread = threading.Thread(target=led_driver,
                                  args=(led_service, master_communicator,
                                        power_communicator))
    led_thread.setName("Serial led driver thread")
    led_thread.daemon = True
    led_thread.start()

    def stop(signum, frame):
        """ This function is called on SIGTERM. """
        sys.stderr.write("Shutting down")
        led_service.set_led('stat2', False)
        web_service.stop()

    signal(SIGTERM, stop)
예제 #28
0
def main():
    """ The main function. """
    parser = argparse.ArgumentParser(description='Tool to control the master.')
    parser.add_argument('--port', dest='port', action='store_true',
                        help='get the serial port device')
    parser.add_argument('--sync', dest='sync', action='store_true',
                        help='sync the serial port')
    parser.add_argument('--reset', dest='reset', action='store_true',
                        help='reset the master')
    parser.add_argument('--hard-reset', dest='hardreset', action='store_true',
                        help='perform a hardware reset on the master')
    parser.add_argument('--version', dest='version', action='store_true',
                        help='get the version of the master')
    parser.add_argument('--wipe', dest='wipe', action='store_true',
                        help='wip the master eeprom')

    args = parser.parse_args()

    config = ConfigParser()
    config.read(constants.get_config_file())

    port = config.get('OpenMotics', 'controller_serial')

    if args.port:
        print port

    elif args.hardreset:
        print 'Performing hard reset...'

        gpio_dir = open('/sys/class/gpio/gpio44/direction', 'w')
        gpio_dir.write('out')
        gpio_dir.close()

        def power(master_on):
            """ Set the power on the master. """
            gpio_file = open('/sys/class/gpio/gpio44/value', 'w')
            gpio_file.write('1' if master_on else '0')
            gpio_file.close()

        power(False)
        time.sleep(5)
        power(True)
        print 'Done performing hard reset'

    elif args.sync or args.version or args.reset or args.wipe:
        master_serial = Serial(port, 115200)
        master_communicator = MasterCommunicator(master_serial)
        master_communicator.start()

        if args.sync:
            print 'Sync...'
            try:
                master_communicator.do_command(master_api.status())
                print 'Done sync'
                sys.exit(0)
            except CommunicationTimedOutException:
                print 'Failed sync'
                sys.exit(1)

        elif args.version:
            status = master_communicator.do_command(master_api.status())
            print '{0}.{1}.{2} H{3}'.format(status['f1'], status['f2'], status['f3'], status['h'])

        elif args.reset:
            print 'Resetting...'
            try:
                master_communicator.do_command(master_api.reset())
                print 'Done resetting'
                sys.exit(0)
            except CommunicationTimedOutException:
                print 'Failed resetting'
                sys.exit(1)

        elif args.wipe:
            (num_banks, bank_size, write_size) = (256, 256, 10)
            print 'Wiping the master...'
            for bank in range(0, num_banks):
                print '-  Wiping bank {0}'.format(bank)
                for addr in range(0, bank_size, write_size):
                    master_communicator.do_command(
                        master_api.write_eeprom(),
                        {'bank': bank, 'address': addr, 'data': '\xff' * write_size}
                    )

            master_communicator.do_command(master_api.activate_eeprom(), {'eep': 0})
            print 'Done wiping the master'

    else:
        parser.print_help()
예제 #29
0
    def test_pulse_counter_status(self):
        action = master_api.pulse_list()

        in_fields = {}
        out_fields = {
            'pv0': 0,
            'pv1': 1,
            'pv2': 2,
            'pv3': 3,
            'pv4': 4,
            'pv5': 5,
            'pv6': 6,
            'pv7': 7,
            'pv8': 8,
            'pv9': 9,
            'pv10': 10,
            'pv11': 11,
            'pv12': 12,
            'pv13': 13,
            'pv14': 14,
            'pv15': 15,
            'pv16': 16,
            'pv17': 17,
            'pv18': 18,
            'pv19': 19,
            'pv20': 20,
            'pv21': 21,
            'pv22': 22,
            'pv23': 23,
            'crc': [67, 1, 20]
        }

        serial_mock = SerialMock([
            sin(action.create_input(1, in_fields)),
            sout(action.create_output(1, out_fields))
        ])
        SetUpTestInjections(controller_serial=serial_mock)

        master_communicator = MasterCommunicator(init_master=False)
        master_communicator.start()

        controller = self._get_controller(master_communicator)
        controller.set_pulse_counter_amount(26)
        controller.set_pulse_counter_status(24, 123)
        controller.set_pulse_counter_status(25, 456)

        status = controller.get_pulse_counter_status()
        self.assertEquals(range(0, 24) + [123, 456], status)

        # Set pulse counter for unexisting pulse counter
        try:
            controller.set_pulse_counter_status(26, 789)
            self.fail('Exception should have been thrown')
        except ValueError as e:
            self.assertEquals('Could not find pulse counter 26', str(e))

        # Set pulse counter for physical pulse counter
        try:
            controller.set_pulse_counter_status(23, 789)
            self.fail('Exception should have been thrown')
        except ValueError as e:
            self.assertEquals(
                'Cannot set pulse counter status for 23 (should be > 23)',
                str(e))
예제 #30
0
def main():
    """ Main function. """
    config = ConfigParser()
    config.read(constants.get_config_file())

    defaults = {
        'username': config.get('OpenMotics', 'cloud_user'),
        'password': config.get('OpenMotics', 'cloud_pass')
    }
    controller_serial_port = config.get('OpenMotics', 'controller_serial')
    passthrough_serial_port = config.get('OpenMotics', 'passthrough_serial')
    power_serial_port = config.get('OpenMotics', 'power_serial')
    gateway_uuid = config.get('OpenMotics', 'uuid')

    config_lock = threading.Lock()
    user_controller = UserController(constants.get_config_database_file(),
                                     config_lock, defaults, 3600)
    config_controller = ConfigurationController(
        constants.get_config_database_file(), config_lock)

    led_service = LedService()

    controller_serial = Serial(controller_serial_port, 115200)
    power_serial = RS485(Serial(power_serial_port, 115200, timeout=None))

    master_communicator = MasterCommunicator(controller_serial)

    if passthrough_serial_port:
        passthrough_serial = Serial(passthrough_serial_port, 115200)
        passthrough_service = PassthroughService(master_communicator,
                                                 passthrough_serial)
        passthrough_service.start()

    master_communicator.start(
    )  # A running master_communicator is required for the startup of services below

    power_controller = PowerController(constants.get_power_database_file())
    power_communicator = PowerCommunicator(power_serial, power_controller)

    gateway_api = GatewayApi(master_communicator, power_communicator,
                             power_controller)

    scheduling_controller = SchedulingController(
        constants.get_scheduling_database_file(), config_lock, gateway_api)

    maintenance_service = MaintenanceService(
        gateway_api, constants.get_ssl_private_key_file(),
        constants.get_ssl_certificate_file())

    web_interface = WebInterface(user_controller, gateway_api,
                                 maintenance_service,
                                 led_service.in_authorized_mode,
                                 config_controller, scheduling_controller)

    scheduling_controller.set_webinterface(web_interface)

    plugin_controller = PluginController(web_interface, config_controller)

    web_interface.set_plugin_controller(plugin_controller)
    gateway_api.set_plugin_controller(plugin_controller)

    # Metrics
    metrics_cache_controller = MetricsCacheController(
        constants.get_metrics_database_file(), threading.Lock())
    metrics_collector = MetricsCollector(gateway_api)
    metrics_controller = MetricsController(plugin_controller,
                                           metrics_collector,
                                           metrics_cache_controller,
                                           config_controller, gateway_uuid)
    metrics_collector.set_controllers(metrics_controller, plugin_controller)
    metrics_collector.set_plugin_intervals(plugin_controller.metric_intervals)
    metrics_controller.add_receiver(metrics_controller.receiver)
    metrics_controller.add_receiver(web_interface.distribute_metric)

    plugin_controller.set_metrics_controller(metrics_controller)
    web_interface.set_metrics_collector(metrics_collector)
    web_interface.set_metrics_controller(metrics_controller)

    web_service = WebService(web_interface, config_controller)

    def _on_output(*args, **kwargs):
        metrics_collector.on_output(*args, **kwargs)
        gateway_api.on_outputs(*args, **kwargs)

    def _on_input(*args, **kwargs):
        metrics_collector.on_input(*args, **kwargs)
        gateway_api.on_inputs(*args, **kwargs)

    master_communicator.register_consumer(
        BackgroundConsumer(master_api.output_list(), 0, _on_output, True))
    master_communicator.register_consumer(
        BackgroundConsumer(master_api.input_list(), 0, _on_input))

    power_communicator.start()
    plugin_controller.start_plugins()
    metrics_controller.start()
    scheduling_controller.start()
    metrics_collector.start()
    web_service.start()

    led_thread = threading.Thread(target=led_driver,
                                  args=(led_service, master_communicator,
                                        power_communicator))
    led_thread.setName("Serial led driver thread")
    led_thread.daemon = True
    led_thread.start()

    def stop(signum, frame):
        """ This function is called on SIGTERM. """
        _ = signum, frame
        sys.stderr.write("Shutting down")
        web_service.stop()
        metrics_collector.stop()
        metrics_controller.stop()
        plugin_controller.stop()

    signal(SIGTERM, stop)
    def test_maintenance_passthrough(self):
        """ Test the behavior of passthrough in maintenance mode. """
        serial_mock = SerialMock([
                        sout("For passthrough"), sin(master_api.to_cli_mode().create_input(0)),
                        sout("OK"), sin("error list\r\n"), sout("the list\n"),
                        sin("exit\r\n"), sout("Passthrough again")])

        comm = MasterCommunicator(serial_mock, init_master=False)
        comm.enable_passthrough()
        comm.start()

        def passthrough_thread():
            """ Background thread that reads the passthrough data. """
            self.assertEquals("For passthrough", comm.get_passthrough_data())
            self.assertEquals("Passthrough again", comm.get_passthrough_data())

        thread = threading.Thread(target=passthrough_thread)
        thread.start()

        comm.start_maintenance_mode()
        self.assertEquals("OK", comm.get_maintenance_data())
        comm.send_maintenance_data("error list\r\n")
        self.assertEquals("the list\n", comm.get_maintenance_data())
        comm.stop_maintenance_mode()

        thread.join()
    def test_maintenance_mode(self):
        """ Test the maintenance mode. """
        serial_mock = SerialMock([sin(master_api.to_cli_mode().create_input(0)),
                                  sout("OK"), sin("error list\r\n"), sout("the list\n"),
                                  sin("exit\r\n")])

        comm = MasterCommunicator(serial_mock, init_master=False)
        comm.start()

        comm.start_maintenance_mode()

        try:
            comm.send_passthrough_data("test")
            self.assertTrue(False)
        except InMaintenanceModeException:
            pass

        try:
            comm.do_command(None, None)
            self.assertTrue(False)
        except InMaintenanceModeException:
            pass

        self.assertEquals("OK", comm.get_maintenance_data())
        comm.send_maintenance_data("error list\r\n")
        self.assertEquals("the list\n", comm.get_maintenance_data())
        comm.stop_maintenance_mode()
예제 #33
0
    def test_maintenance_passthrough(self):
        """ Test the behavior of passthrough in maintenance mode. """
        serial_mock = SerialMock([
            sout("For passthrough"),
            sin(master_api.to_cli_mode().create_input(0)),
            sout("OK"),
            sin("error list\r\n"),
            sout("the list\n"),
            sin("exit\r\n"),
            sout("Passthrough again")
        ])

        comm = MasterCommunicator(serial_mock, init_master=False)
        comm.enable_passthrough()
        comm.start()

        def passthrough_thread():
            """ Background thread that reads the passthrough data. """
            self.assertEquals("For passthrough", comm.get_passthrough_data())
            self.assertEquals("Passthrough again", comm.get_passthrough_data())

        thread = threading.Thread(target=passthrough_thread)
        thread.start()

        comm.start_maintenance_mode()
        self.assertEquals("OK", comm.get_maintenance_data())
        comm.send_maintenance_data("error list\r\n")
        self.assertEquals("the list\n", comm.get_maintenance_data())
        comm.stop_maintenance_mode()

        thread.join()
예제 #34
0
def main():
    """ The main function. """
    parser = argparse.ArgumentParser(description='Tool to control the master.')
    parser.add_argument('--port',
                        dest='port',
                        action='store_true',
                        help='get the serial port device')
    parser.add_argument('--sync',
                        dest='sync',
                        action='store_true',
                        help='sync the serial port')
    parser.add_argument('--reset',
                        dest='reset',
                        action='store_true',
                        help='reset the master')
    parser.add_argument('--hard-reset',
                        dest='hardreset',
                        action='store_true',
                        help='perform a hardware reset on the master')
    parser.add_argument('--version',
                        dest='version',
                        action='store_true',
                        help='get the version of the master')
    parser.add_argument('--wipe',
                        dest='wipe',
                        action='store_true',
                        help='wip the master eeprom')

    args = parser.parse_args()

    config = ConfigParser()
    config.read(constants.get_config_file())

    port = config.get('OpenMotics', 'controller_serial')

    if args.port:
        print port
    elif args.hardreset:
        print "Performing hard reset"

        gpio_dir = open('/sys/class/gpio/gpio44/direction', 'w')
        gpio_dir.write('out')
        gpio_dir.close()

        def power(master_on):
            """ Set the power on the master. """
            gpio_file = open('/sys/class/gpio/gpio44/value', 'w')
            gpio_file.write('1' if master_on else '0')
            gpio_file.close()

        power(False)
        time.sleep(5)
        power(True)

        print "Done"
    elif args.sync or args.version or args.reset or args.wipe:
        master_serial = Serial(port, 115200)
        master_communicator = MasterCommunicator(master_serial)
        master_communicator.start()

        if args.sync:
            try:
                master_communicator.do_command(master_api.status())
            except CommunicationTimedOutException:
                print "Failed"
                sys.exit(1)
            else:
                print "Done"
                sys.exit(0)
        elif args.version:
            status = master_communicator.do_command(master_api.status())
            print "%d.%d.%d H%d" % (status['f1'], status['f2'], status['f3'],
                                    status['h'])
        elif args.reset:
            master_communicator.do_command(master_api.reset())
            print "Reset !"
        elif args.wipe:
            (num_banks, bank_size, write_size) = (256, 256, 10)
            print "Wiping the master"
            for bank in range(0, num_banks):
                print " Wiping bank %d" % bank
                for addr in range(0, bank_size, write_size):
                    master_communicator.do_command(master_api.write_eeprom(), {
                        'bank': bank,
                        'address': addr,
                        'data': '\xff' * write_size
                    })

            master_communicator.do_command(master_api.activate_eeprom(),
                                           {'eep': 0})
            print "Done wiping the master"

    else:
        parser.print_help()
예제 #35
0
    def test_do_command_passthrough(self):
        """ Test for the do_command with passthrough data. """
        action = master_api.basic_action()
        in_fields = {"action_type": 1, "action_number": 2}
        out_fields = {"resp": "OK"}

        serial_mock = SerialMock([
            sin(action.create_input(1, in_fields)),
            sout("hello" + action.create_output(1, out_fields)),
            sin(action.create_input(2, in_fields)),
            sout(action.create_output(2, out_fields) + "world"),
            sin(action.create_input(3, in_fields)),
            sout("hello" + action.create_output(3, out_fields) + " world"),
            sin(action.create_input(4, in_fields)),
            sout("hello"),
            sout(action.create_output(4, out_fields))
        ])

        comm = MasterCommunicator(serial_mock, init_master=False)
        comm.enable_passthrough()
        comm.start()

        self.assertEquals("OK", comm.do_command(action, in_fields)["resp"])
        self.assertEquals("hello", comm.get_passthrough_data())

        self.assertEquals("OK", comm.do_command(action, in_fields)["resp"])
        self.assertEquals("world", comm.get_passthrough_data())

        self.assertEquals("OK", comm.do_command(action, in_fields)["resp"])
        self.assertEquals("hello world", comm.get_passthrough_data())

        self.assertEquals("OK", comm.do_command(action, in_fields)["resp"])
        self.assertEquals("hello", comm.get_passthrough_data())
    def test_do_command_passthrough(self):
        """ Test for the do_command with passthrough data. """
        action = master_api.basic_action()
        in_fields = {"action_type": 1, "action_number": 2}
        out_fields = {"resp": "OK"}

        serial_mock = SerialMock(
                        [sin(action.create_input(1, in_fields)),
                         sout("hello" + action.create_output(1, out_fields)),
                         sin(action.create_input(2, in_fields)),
                         sout(action.create_output(2, out_fields) + "world"),
                         sin(action.create_input(3, in_fields)),
                         sout("hello" + action.create_output(3, out_fields) + " world"),
                         sin(action.create_input(4, in_fields)),
                         sout("hello"), sout(action.create_output(4, out_fields))])

        comm = MasterCommunicator(serial_mock, init_master=False)
        comm.enable_passthrough()
        comm.start()

        self.assertEquals("OK", comm.do_command(action, in_fields)["resp"])
        self.assertEquals("hello", comm.get_passthrough_data())

        self.assertEquals("OK", comm.do_command(action, in_fields)["resp"])
        self.assertEquals("world", comm.get_passthrough_data())

        self.assertEquals("OK", comm.do_command(action, in_fields)["resp"])
        self.assertEquals("hello world", comm.get_passthrough_data())

        self.assertEquals("OK", comm.do_command(action, in_fields)["resp"])
        self.assertEquals("hello", comm.get_passthrough_data())
예제 #37
0
    def test_maintenance_mode(self):
        """ Test the maintenance mode. """
        serial_mock = SerialMock([
            sin(master_api.to_cli_mode().create_input(0)),
            sout("OK"),
            sin("error list\r\n"),
            sout("the list\n"),
            sin("exit\r\n")
        ])

        comm = MasterCommunicator(serial_mock, init_master=False)
        comm.start()

        comm.start_maintenance_mode()

        try:
            comm.send_passthrough_data("test")
            self.assertTrue(False)
        except InMaintenanceModeException:
            pass

        try:
            comm.do_command(None, None)
            self.assertTrue(False)
        except InMaintenanceModeException:
            pass

        self.assertEquals("OK", comm.get_maintenance_data())
        comm.send_maintenance_data("error list\r\n")
        self.assertEquals("the list\n", comm.get_maintenance_data())
        comm.stop_maintenance_mode()
예제 #38
0
def main():
    """ Main function. """
    log('Starting service...')

    config = ConfigParser()
    config.read(constants.get_config_file())

    defaults = {'username': config.get('OpenMotics', 'cloud_user'),
                'password': config.get('OpenMotics', 'cloud_pass')}
    controller_serial_port = config.get('OpenMotics', 'controller_serial')
    passthrough_serial_port = config.get('OpenMotics', 'passthrough_serial')
    power_serial_port = config.get('OpenMotics', 'power_serial')
    gateway_uuid = config.get('OpenMotics', 'uuid')

    config_lock = threading.Lock()
    user_controller = UserController(constants.get_config_database_file(), config_lock, defaults, 3600)
    config_controller = ConfigurationController(constants.get_config_database_file(), config_lock)

    dbus_service = DBusService('openmotics_service')

    controller_serial = Serial(controller_serial_port, 115200)
    power_serial = RS485(Serial(power_serial_port, 115200, timeout=None))

    master_communicator = MasterCommunicator(controller_serial)
    eeprom_controller = EepromController(
        EepromFile(master_communicator),
        EepromExtension(constants.get_eeprom_extension_database_file())
    )

    if passthrough_serial_port:
        passthrough_serial = Serial(passthrough_serial_port, 115200)
        passthrough_service = PassthroughService(master_communicator, passthrough_serial)
        passthrough_service.start()

    power_controller = PowerController(constants.get_power_database_file())
    power_communicator = PowerCommunicator(power_serial, power_controller)

    pulse_controller = PulseCounterController(
        constants.get_pulse_counter_database_file(),
        master_communicator,
        eeprom_controller
    )

    observer = Observer(master_communicator, dbus_service)
    gateway_api = GatewayApi(master_communicator, power_communicator, power_controller, eeprom_controller, pulse_controller, dbus_service, observer, config_controller)

    observer.set_gateway_api(gateway_api)

    scheduling_controller = SchedulingController(constants.get_scheduling_database_file(), config_lock, gateway_api)

    maintenance_service = MaintenanceService(gateway_api, constants.get_ssl_private_key_file(),
                                             constants.get_ssl_certificate_file())

    web_interface = WebInterface(user_controller, gateway_api, maintenance_service, dbus_service,
                                 config_controller, scheduling_controller)

    scheduling_controller.set_webinterface(web_interface)

    # Plugins
    plugin_controller = PluginController(web_interface, config_controller)
    web_interface.set_plugin_controller(plugin_controller)
    gateway_api.set_plugin_controller(plugin_controller)

    # Metrics
    metrics_cache_controller = MetricsCacheController(constants.get_metrics_database_file(), threading.Lock())
    metrics_collector = MetricsCollector(gateway_api, pulse_controller)
    metrics_controller = MetricsController(plugin_controller, metrics_collector, metrics_cache_controller, config_controller, gateway_uuid)
    metrics_collector.set_controllers(metrics_controller, plugin_controller)
    metrics_controller.add_receiver(metrics_controller.receiver)
    metrics_controller.add_receiver(web_interface.distribute_metric)

    plugin_controller.set_metrics_controller(metrics_controller)
    plugin_controller.set_metrics_collector(metrics_collector)
    web_interface.set_metrics_collector(metrics_collector)
    web_interface.set_metrics_controller(metrics_controller)

    web_service = WebService(web_interface, config_controller)
    plugin_controller.set_webservice(web_service)

    observer.subscribe_master(Observer.MasterEvents.INPUT_TRIGGER, metrics_collector.on_input)
    observer.subscribe_master(Observer.MasterEvents.INPUT_TRIGGER, plugin_controller.process_input_status)
    observer.subscribe_master(Observer.MasterEvents.ON_OUTPUTS, metrics_collector.on_output)
    observer.subscribe_master(Observer.MasterEvents.ON_OUTPUTS, plugin_controller.process_output_status)
    observer.subscribe_master(Observer.MasterEvents.ON_SHUTTER_UPDATE, plugin_controller.process_shutter_status)
    observer.subscribe_events(web_interface.process_observer_event)

    led_thread = threading.Thread(target=led_driver, args=(dbus_service, master_communicator, power_communicator))
    led_thread.setName("Serial led driver thread")
    led_thread.daemon = True
    led_thread.start()

    master_communicator.start()
    observer.start()
    power_communicator.start()
    metrics_controller.start()
    scheduling_controller.start()
    metrics_collector.start()
    web_service.start()
    gateway_api.start()
    plugin_controller.start()

    signal_request = {'stop': False}

    def stop(signum, frame):
        """ This function is called on SIGTERM. """
        _ = signum, frame
        log('Stopping service...')
        web_service.stop()
        metrics_collector.stop()
        metrics_controller.stop()
        plugin_controller.stop()
        log('Stopping service... Done')
        signal_request['stop'] = True

    signal(SIGTERM, stop)
    log('Starting service... Done')
    while not signal_request['stop']:
        time.sleep(1)