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()
    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_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()
    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_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())
    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_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_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_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"])
예제 #11
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(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"])
예제 #13
0
    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"])
예제 #14
0
    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)
예제 #15
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.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())
예제 #16
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_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())
    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"])
예제 #19
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())
예제 #20
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()
예제 #21
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()