def test_read_one_bank_two_addresses(self):
        """ Test read from one bank with two addresses. """
        def read(_data):
            """ Read dummy """
            if _data['bank'] == 1:
                return {
                    'data':
                    bytearray(b'abc') + bytearray([255] * 200) +
                    bytearray(b'def') + bytearray([255] * 48)
                }
            else:
                raise Exception('Wrong page')

        SetUpTestInjections(master_communicator=MasterCommunicator(read))

        eeprom_file = EepromFile()

        address1 = EepromAddress(1, 2, 10)
        address2 = EepromAddress(1, 203, 4)
        data = eeprom_file.read([address1, address2])

        self.assertEqual(2, len(data))

        self.assertEqual(address1, data[address1].address)
        self.assertEqual(
            bytearray(b'c') + bytearray([255] * 9), data[address1].bytes)

        self.assertEqual(address2, data[address2].address)
        self.assertEqual(bytearray(b'def\xff'), data[address2].bytes)
    def test_cache_invalidate(self):
        """ Test the cache invalidation. """
        state = {'count': 0}

        def read(_):
            """ Read dummy. """
            if state['count'] == 0:
                state['count'] = 1
                return {'data': bytearray([255] * 256)}
            elif state['count'] == 1:
                state['count'] = 2
                return {'data': bytearray([255] * 256)}
            else:
                raise Exception('Too many reads !')

        SetUpTestInjections(master_communicator=MasterCommunicator(read))

        eeprom_file = EepromFile()
        address = EepromAddress(1, 0, 256)
        read = eeprom_file.read([address])
        self.assertEqual(bytearray([255] * 256), read[address].bytes)

        # Second read should come from cache.
        address = EepromAddress(1, 0, 256)
        read = eeprom_file.read([address])
        self.assertEqual(bytearray([255] * 256), read[address].bytes)

        eeprom_file.invalidate_cache()
        # Should be read from communicator, since cache is invalid
        address = EepromAddress(1, 0, 256)
        read = eeprom_file.read([address])
        self.assertEqual(bytearray([255] * 256), read[address].bytes)

        self.assertEqual(2, state['count'])
    def test_read_multiple_banks(self):
        """ Test read from multiple banks. """
        def read(_data):
            """ Read dummy. """
            if _data['bank'] == 1:
                return {'data': bytearray(b'abc') + bytearray([255] * 200) + bytearray(b'def') + bytearray([255] * 48)}
            if _data['bank'] == 100:
                return {'data': bytearray(b'hello') + bytearray([0] * 100) + bytearray(b'world') + bytearray([0] * 146)}
            else:
                raise Exception('Wrong page')
        SetUpTestInjections(master_communicator=MasterCommunicator(read))

        eeprom_file = EepromFile()

        address1 = EepromAddress(1, 2, 10)
        address2 = EepromAddress(100, 4, 10)
        address3 = EepromAddress(100, 105, 5)
        data = eeprom_file.read([address1, address2, address3])

        self.assertEqual(3, len(data))

        self.assertEqual(address1, data[address1].address)
        self.assertEqual(bytearray(b'c') + bytearray([255] * 9), data[address1].bytes)

        self.assertEqual(address2, data[address2].address)
        self.assertEqual(bytearray(b'o') + bytearray([0] * 9), data[address2].bytes)

        self.assertEqual(address3, data[address3].address)
        self.assertEqual(bytearray(b'world'), data[address3].bytes)
Beispiel #4
0
def get_module_addresses(module_type):
    # type: (str) -> List[str]
    """
    Get the addresses for the modules of the given type.

    :param module_type: the type of the module (O, R, D, I, T, C)
    :returns: A list containing the addresses of the modules (strings of length 4).
    """
    eeprom_file = EepromFile()
    base_address = EepromAddress(0, 1, 2)
    no_modules = eeprom_file.read([base_address])
    modules = []

    no_input_modules = no_modules[base_address].bytes[0]
    for i in range(no_input_modules):
        address = EepromAddress(2 + i, 252, 1)
        is_can = chr(eeprom_file.read([address])[address].bytes[0]) == 'C'
        address = EepromAddress(2 + i, 0, 4)
        module = eeprom_file.read([address])[address].bytes
        if not is_can or chr(module[0]) == 'C':
            modules.append(module)

    no_output_modules = no_modules[base_address].bytes[1]
    for i in range(no_output_modules):
        address = EepromAddress(33 + i, 0, 4)
        modules.append(eeprom_file.read([address])[address].bytes)

    return [module for module in modules if chr(module[0]) == module_type]
    def test_write_multiple_fields(self):
        """ Test writing multiple fields to the eeprom file. """
        done = {}

        def read(data):
            """ Read dummy. """
            if data['bank'] == 1:
                done['read1'] = True
                return {'data': bytearray([255] * 256)}
            elif data['bank'] == 2:
                done['read2'] = True
                return {'data': bytearray([0] * 256)}
            else:
                raise Exception('Wrong page')

        def write(data):
            """ Write dummy. """
            if 'write1' not in done:
                done['write1'] = True
                self.assertEqual(1, data['bank'])
                self.assertEqual(2, data['address'])
                self.assertEqual(bytearray(b'abc'), data['data'])
            elif 'write2' not in done:
                done['write2'] = True
                self.assertEqual(2, data['bank'])
                self.assertEqual(123, data['address'])
                self.assertEqual(bytearray(b'More bytes'), data['data'])
            elif 'write3' not in done:
                done['write3'] = True
                self.assertEqual(2, data['bank'])
                self.assertEqual(133, data['address'])
                self.assertEqual(bytearray(b' than 10'), data['data'])
            else:
                raise Exception('Too many writes')

        SetUpTestInjections(
            master_communicator=MasterCommunicator(read, write))

        eeprom_file = EepromFile()
        eeprom_file.write([
            EepromData(EepromAddress(1, 2, 3), bytearray(b'abc')),
            EepromData(EepromAddress(2, 123, 18),
                       bytearray(b'More bytes than 10'))
        ])

        self.assertTrue('read1' in done)
        self.assertTrue('read2' in done)
        self.assertTrue('write1' in done)
        self.assertTrue('write2' in done)
        self.assertTrue('write3' in done)
    def test_write_single_field(self):
        """ Write a single field to the eeprom file. """
        done = {}

        def read(data):
            """ Read dummy. """
            if data['bank'] == 1:
                done['read1'] = True
                return {'data': bytearray([255] * 256)}
            else:
                raise Exception('Wrong page')

        def write(data):
            """ Write dummy. """
            self.assertEqual(1, data['bank'])
            self.assertEqual(2, data['address'])
            self.assertEqual(bytearray(b'abc'), data['data'])
            done['write'] = True

        SetUpTestInjections(master_communicator=MasterCommunicator(read, write))

        eeprom_file = EepromFile()
        eeprom_file.write([EepromData(EepromAddress(1, 2, 3), bytearray(b'abc'))])

        self.assertTrue('read1' in done)
        self.assertTrue('write' in done)
    def test_write_end_of_page(self):
        """ Test writing an address that is close (< BATCH_SIZE) to the end of the page. """
        done = {}

        def read(_):
            """ Read dummy. """
            return {'data': bytearray([0] * 256)}

        def write(data):
            """ Write dummy. """
            self.assertEqual(117, data['bank'])
            self.assertEqual(248, data['address'])
            self.assertEqual(
                bytearray(b'test') + bytearray([255] * 4), data['data'])
            done['done'] = True

        SetUpTestInjections(
            master_communicator=MasterCommunicator(read, write))

        eeprom_file = EepromFile()
        eeprom_file.write([
            EepromData(EepromAddress(117, 248, 8),
                       bytearray(b'test') + bytearray([255] * 4))
        ])
        self.assertTrue(done['done'])
Beispiel #8
0
class OutputConfiguration(EepromModel):
    """
    Models an output. The maximum number of inputs is 240 (30 modules), the actual number of
    outputs is 8 times the number of output modules (eeprom address 0, 2).
    """
    id = EepromId(240, address=EepromAddress(0, 2, 1), multiplier=8)
    module_type = EepromString(1,
                               lambda mid: (33 + mid / 8, 0),
                               read_only=True,
                               shared=True)
    name = EepromString(16, page_per_module(8, 33, 20, 16))
    timer = EepromWord(page_per_module(8, 33, 4, 2))
    floor = EepromByte(page_per_module(8, 33, 157, 1))
    type = EepromByte(page_per_module(8, 33, 149, 1))
    lock_bit_id = EepromByte(lambda mid: (231, mid))
    can_led_1_id = EepromByte(gen_address(221, 32, 0))
    can_led_1_function = EepromEnum(gen_address(221, 32, 1),
                                    get_led_functions())
    can_led_2_id = EepromByte(gen_address(221, 32, 2))
    can_led_2_function = EepromEnum(gen_address(221, 32, 3),
                                    get_led_functions())
    can_led_3_id = EepromByte(gen_address(221, 32, 4))
    can_led_3_function = EepromEnum(gen_address(221, 32, 5),
                                    get_led_functions())
    can_led_4_id = EepromByte(gen_address(221, 32, 6))
    can_led_4_function = EepromEnum(gen_address(221, 32, 7),
                                    get_led_functions())
    def test_cache_write(self):
        """ Test the eeprom cache on writing. """
        state = {'read': 0, 'write': 0}

        def read(_):
            """ Read dummy. """
            if state['read'] == 0:
                state['read'] = 1
                return {'data': bytearray([255] * 256)}
            else:
                raise Exception('Too many reads !')

        def write(data):
            """ Write dummy. """
            if state['write'] == 0:
                self.assertEqual(1, data['bank'])
                self.assertEqual(100, data['address'])
                self.assertEqual(bytearray([0] * 10), data['data'])
                state['write'] = 1
            elif state['write'] == 1:
                self.assertEqual(1, data['bank'])
                self.assertEqual(110, data['address'])
                self.assertEqual(bytearray([0] * 10), data['data'])
                state['write'] = 2
            else:
                raise Exception('Too many writes !')

        SetUpTestInjections(
            master_communicator=MasterCommunicator(read, write))

        eeprom_file = EepromFile()

        address = EepromAddress(1, 0, 256)
        read = eeprom_file.read([address])
        self.assertEqual(bytearray([255] * 256), read[address].bytes)

        eeprom_file.write(
            [EepromData(EepromAddress(1, 100, 20), bytearray([0] * 20))])

        address = EepromAddress(1, 0, 256)
        read = eeprom_file.read([address])
        self.assertEqual(bytearray([255] * 100 + [0] * 20 + [255] * 136),
                         read[address].bytes)

        self.assertEqual(1, state['read'])
        self.assertEqual(2, state['write'])
    def test_cache_write_exception(self):
        """ The cache should be invalidated if a write fails. """
        state = {'read': 0, 'write': 0}

        def read(_):
            """ Read dummy. """
            if state['read'] == 0:
                state['read'] = 1
                return {'data': bytearray([255] * 256)}
            elif state['read'] == 1:
                state['read'] = 2
                return {'data': bytearray([255] * 256)}
            else:
                raise Exception('Too many reads !')

        def write(_):
            """ Write dummy. """
            state['write'] += 1
            raise Exception('write fails...')

        SetUpTestInjections(
            master_communicator=MasterCommunicator(read, write))

        eeprom_file = EepromFile()

        address = EepromAddress(1, 0, 256)
        read = eeprom_file.read([address])
        self.assertEqual(bytearray([255] * 256), read[address].bytes)

        try:
            eeprom_file.write(
                [EepromData(EepromAddress(1, 100, 20), bytearray([0] * 20))])
            self.fail('Should not get here !')
        except Exception:
            pass

        address = EepromAddress(1, 0, 256)
        read = eeprom_file.read([address])
        self.assertEqual(bytearray([255] * 256), read[address].bytes)

        self.assertEqual(2, state['read'])
        self.assertEqual(1, state['write'])
Beispiel #11
0
class ShutterConfiguration(EepromModel):
    """
    Models a shutter. The maximum number of shutters is 120 (30 modules), the actual number of
    shutters is 4 times the number of shutter modules (eeprom address 0, 3).
    """
    id = EepromId(120, address=EepromAddress(0, 3, 1), multiplier=4)
    timer_up = EepromByte(page_per_module(4, 33, 177, 2))
    timer_down = EepromByte(page_per_module(4, 33, 178, 2))
    up_down_config = EepromByte(page_per_module(4, 33, 185, 1))
    name = EepromString(16, page_per_module(4, 33, 189, 16))
    group_1 = EepromByte(lambda mid: (63, (mid * 2) + 0))
    group_2 = EepromByte(lambda mid: (63, (mid * 2) + 1))
    steps = EextWord()
    def test_cache(self):
        """ Test the caching of banks. """
        state = {'count': 0}

        def read(_):
            """ Read dummy. """
            if state['count'] == 0:
                state['count'] = 1
                return {'data': bytearray([255] * 256)}
            else:
                raise Exception('Too many reads !')
        SetUpTestInjections(master_communicator=MasterCommunicator(read))

        eeprom_file = EepromFile()
        address = EepromAddress(1, 0, 256)
        read = eeprom_file.read([address])
        self.assertEqual(bytearray([255] * 256), read[address].bytes)

        # Second read should come from cache, if read is called
        # an exception will be thrown.
        address = EepromAddress(1, 0, 256)
        read = eeprom_file.read([address])
        self.assertEqual(bytearray([255] * 256), read[address].bytes)
    def test_read_one_bank_one_address(self):
        """ Test read from one bank with one address """
        def read(_data):
            """ Read dummy. """
            if _data['bank'] == 1:
                return {'data': bytearray(b'abc') + bytearray([255] * 200) + bytearray(b'def') + bytearray([255] * 48)}
            else:
                raise Exception('Wrong page')
        SetUpTestInjections(master_communicator=MasterCommunicator(read))

        eeprom_file = EepromFile()
        address = EepromAddress(1, 0, 3)
        data = eeprom_file.read([address])

        self.assertEqual(1, len(data))
        self.assertEqual(address, data[address].address)
        self.assertEqual(bytearray(b'abc'), data[address].bytes)
Beispiel #14
0
class InputConfiguration(EepromModel):
    """
    Models an input. The maximum number of inputs is 240 (30 modules), the actual number of
    inputs is 8 times the number of input modules (eeprom address 0, 1).
    """
    id = EepromId(240, address=EepromAddress(0, 1, 1), multiplier=8)
    module_type = EepromString(1,
                               lambda mid: (2 + mid / 8, 0),
                               read_only=True,
                               shared=True)
    name = EepromString(
        8,
        per_module(
            8, lambda mid, iid: (115 + (mid / 4), 64 * (mid % 4) + 8 * iid)))
    action = EepromByte(page_per_module(8, 2, 4, 1))
    basic_actions = EepromActions(15, page_per_module(8, 2, 12, 30))
    invert = EepromByte(lambda mid: (32, mid))
    can = EepromString(1,
                       lambda mid: (2 + mid / 8, 252),
                       read_only=True,
                       shared=True)
class Model4(EepromModel):
    """ Dummy model with a dynamic maximum id. """
    id = EepromId(10, address=EepromAddress(0, 0, 1), multiplier=2)
    name = EepromString(10, lambda id: (1, 2 + id * 10))