Beispiel #1
0
 def test_constructor_valid_values(self):
     self.assertEqual(
         RFAddr('122b65')._bytes, bytearray([0x12, 0x2b, 0x65]))
     self.assertEqual(
         RFAddr(bytearray([0x12, 0x2b, 0x65]))._bytes,
         bytearray([0x12, 0x2b, 0x65]))
     self.assertEqual(
         RFAddr((0x12, 0x2b, 0x65))._bytes, bytearray([0x12, 0x2b, 0x65]))
Beispiel #2
0
    def test_contains(self):
        dl = DeviceList()
        dl.append(
            Device(rf_address=RFAddr('122b65'), serial='123', name='foobar'))

        self.assertTrue('foobar' in dl)
        self.assertTrue(RFAddr('122b65') in dl)
        self.assertTrue(bytearray([0x12, 0x2b, 0x65]) in dl)
        self.assertFalse(True in dl)
        self.assertFalse(1 in dl)
Beispiel #3
0
    def test_equals(self):
        # string: case insensitive
        self.assertEqual(RFAddr('122b65'), '122b65')
        self.assertEqual(RFAddr('122b65'), '122B65')

        # another rf addr instance
        self.assertEqual(RFAddr('122b65'), RFAddr('122b65'))

        # bytearray
        self.assertEqual(RFAddr('122b65'), bytearray([0x12, 0x2b, 0x65]))
Beispiel #4
0
    def test_update_add(self):
        dl = DeviceList()

        dl.update(rf_address=RFAddr('122b65'),
                  serial='123',
                  name='foobar',
                  battery_low=False)
        self.assertEqual(dl, [
            Device(rf_address=RFAddr('122b65'),
                   serial='123',
                   name='foobar',
                   battery_low=False)
        ])
Beispiel #5
0
    def test_equals(self):
        dev1 = Device(foo='bar')
        dev2 = Device(foo='bar')
        self.assertEqual(dev1, dev2)

        self.assertEqual(dev1, {'foo': 'bar'})

        self.assertEqual(Device(rf_address=RFAddr('122b65')),
                         Device(rf_address='122b65'))
        self.assertEqual(Device(rf_address=RFAddr('122b65')),
                         {'rf_address': '122b65'})
        self.assertNotEqual(Device(foo='bar'), Device(baz='bat', blah='blubb'))
        self.assertNotEqual(Device(foo='bar', baz='bat'), Device(blah='blubb'))
        self.assertNotEqual(Device(foo='bar'), {'baz': 'bat', 'blah': 'blubb'})
        self.assertNotEqual(Device(foo='bar'), 1)
Beispiel #6
0
 def _parse(self):
     self.name = self.data[0:8].decode('utf-8')
     self.serial = self.data[8:18].decode('utf-8')
     self.request_id = chr(self.data[18])
     self.request_type = chr(self.data[19])
     self.rf_address = RFAddr(self.data[21:24])
     self.fw_version = ''.join("%02x" % x for x in self.data[24:26])
Beispiel #7
0
    def _parse(self):
        device = self.data[:6].decode('utf-8')

        b64 = self.data[7:]
        data = bytearray(base64.b64decode(b64))
        #self.dump_bytes(data, "device config")

        data_length = data[0]
        logger.debug("Data length for device config: %s", data_length)

        self.device_addr = RFAddr(data[1:4])
        self.device_type, self.room_id, self.firmware_version, self.test_result = struct.unpack(
            'bbbb', data[4:8])
        self.serial_number = data[8:17].decode('utf-8')

        logger.debug(
            "Device config for %s: type: %s, room: %s, firmware: %s, test: %s, serial number: %s",
            self.device_addr, self.device_type, self.room_id,
            self.firmware_version, self.test_result, self.serial_number)

        if self.device_type == DeviceCube:
            self._parse_cube_config(data[18:])
        elif self.device_type == DeviceRadiatorThermostat or self.device_type == DeviceRadiatorThermostatPlus:
            self._parse_thermostat_config(data[18:])
        elif self.device_type == DeviceWallThermostat:
            self._parse_wall_thermostat_config(data[18:])
        else:
            logger.warning(
                "Cannot parse device configuration for type %s (%s)",
                self.device_type, device_type_name(self.device_type))
Beispiel #8
0
    def _parse(self):
        base64_data = self.data.decode('utf-8')
        data = bytearray(base64.b64decode(base64_data))

        self.dump_bytes(data, "MResponse")

        # first two bytes are currently unknown
        self.num_rooms = data[2]
        logger.debug("Number of rooms from MResponse: %s", self.num_rooms)
        self.rooms = []
        pos = 3
        for i in range(0, self.num_rooms):
            logger.debug("Parsing room %s of %s (from pos %s)", i + 1,
                         self.num_rooms, pos)

            room_id, name_length = struct.unpack('bb', data[pos:pos + 2])
            room_name = data[pos + 2:pos + 2 + name_length].decode('utf-8')
            group_rf_address = RFAddr(data[pos + name_length + 2:pos +
                                           name_length + 2 + 3])
            logger.debug("Room ID: %s, Room Name: %s, Group RF address: %s",
                         room_id, room_name, group_rf_address)
            self.rooms.append((room_id, room_name, group_rf_address))
            # set pos to start of next section
            pos += 1 + 1 + name_length + 3

        self.devices = []

        self.num_devices = data[pos]
        pos += 1

        for device_idx in range(0, self.num_devices):
            device_type = data[pos]
            device_rf_address = RFAddr(data[pos + 1:pos + 1 + 3])
            device_serial = data[pos + 4:pos + 14].decode('utf-8')
            device_name_length = data[pos + 14]
            device_name = data[pos + 15:pos + 15 +
                               device_name_length].decode('utf-8')
            room_id = data[pos + 15 + device_name_length]

            logger.debug(
                "Device: %s, Device RF address: %s, Device serial: %s, Device: %s, Room: %s",
                device_idx, device_rf_address, device_serial, device_name,
                room_id)
            self.devices.append((device_idx, device_type, device_rf_address,
                                 device_serial, device_name, room_id))

            pos += 1 + 3 + 10 + device_name_length + 2
Beispiel #9
0
    def test_set_program_with_rfaddr(self):
        c = self._mocked_cube()
        rfaddr = RFAddr('122b56')
        response = c.set_program(1, rfaddr, 1, [])
        setmessage = SetProgramMessage(rfaddr, 1, 1, [])
        c.send_message.assert_called_with(setmessage)

        self.assertIsInstance(response, SetResponse)
Beispiel #10
0
    def test_for_room(self):
        dl = DeviceList()
        self.assertEqual(list(dl.for_room(0)), [])

        dev = Device(rf_address=RFAddr('122b65'),
                     serial='123',
                     name='foobar',
                     room_id=1)
        dl.append(dev)
        self.assertEqual(list(dl.for_room(0)), [])
        self.assertEqual(list(dl.for_room(1)), [dev])
Beispiel #11
0
    def test_update(self):
        for k, v in (
            ('rf_address', '122b65'),
            ('name', 'foobar'),
        ):
            dl = DeviceList([
                Device(rf_address=RFAddr('122b65'),
                       serial='123',
                       name='foobar',
                       room_id=0,
                       battery_low=False)
            ])
            dl.update(room_id=1, **{k: v})

            self.assertEqual(dl, [
                Device(rf_address=RFAddr('122b65'),
                       serial='123',
                       name='foobar',
                       room_id=1,
                       battery_low=False)
            ])
Beispiel #12
0
    def test_get(self):
        dev = Device(rf_address=RFAddr('122b65'), serial='123', name='foobar')
        dl = DeviceList([dev])

        self.assertIsNone(dl.get())

        self.assertEqual(dl.get(rf_address='122b65'), dev)
        self.assertEqual(dl.get(rf_address='122b65', serial='123'), dev)
        self.assertEqual(
            dl.get(rf_address='122b65', serial='123', name='foobar'), dev)
        self.assertIsNone(
            dl.get(rf_address='122b65',
                   serial='123',
                   name='foobar',
                   blah='blubb'))
        self.assertIsNone(dl.get(rf_address='foo'))
Beispiel #13
0
    def _parse(self):
        submessage_len, rf1, rf2, rf3, unknown, flags1, flags2 = struct.unpack(
            'B3BBBB', self.data[:7])
        #        for row_num in range(0, len(self.data), 10):
        #            row_bytes = self.data[row_num:row_num+10]
        #            print("%s  %s" % (str(row_num).ljust(2), ' '.join(["%02x" % x for x in row_bytes])))
        #            print("     %s" % '  '.join([chr(x) if 32 < x < 128 else ' ' for x in row_bytes]))

        self.rf_addr = RFAddr((rf1, rf2, rf3))

        self.weekly_program = not (flags2 & 0x01 or flags2 & 0x02)
        self.manual_program = bool(flags2 & 0x01 and not flags2 & 0x02)
        self.vacation_program = bool(flags2 & 0x02 and not flags2 & 0x01)
        self.boost_program = bool(flags2 & 0x01 and flags2 & 0x02)
        self.dst_active = flags2 & 0x08

        self.gateway_known = bool(flags2 & 0x05)
        self.panel_locked = bool(flags2 & 0x06)
        self.link_ok = bool(flags2 & 0x07)
        self.battery_low = bool(not (flags2 & 0x08))

        self.status_initialized = bool(flags1 & 0x02)
        self.is_answer = bool(not (flags1 & 0x03))
        self.is_error = bool(flags1 & 0x04)
        self.is_valid = bool(flags1 & 0x05)

        self.description = "%s: RF addr: %s, program: (weekly: %s, manual: %s, vacation: %s, boost_program: %s)" % (
            self.__class__.__name__, self.rf_addr, self.weekly_program,
            self.manual_program, self.vacation_program, self.boost_program)

        self.description += ", gateway_known: %s, panel_locked: %s, link_ok: %s, battery_low: %s " % (
            self.gateway_known, self.panel_locked, self.link_ok,
            self.battery_low)

        self.description += ", status_initialized: %s, is_answer: %s, is_error: %s, is_valid: %s " % (
            self.status_initialized, self.is_answer, self.is_error,
            self.is_valid)

        # differ the devices, windowshutter is special.
        # state is coded in mode field:
        # open = auto/weekly program (00)
        # closed = vacation (10)
        if submessage_len == 12:
            self._parse_wall_mounted_thermostat(self.data)
        elif submessage_len == 11:
            self._parse_heater_thermostat(self.data)
Beispiel #14
0
    def test_set_program_same_payload(self):
        c = self._mocked_cube()
        rfaddr = RFAddr('122b56')

        response1 = c.set_program(1, rfaddr, 1, [])
        setmessage1 = SetProgramMessage(rfaddr, 1, 1, [])
        payload1 = setmessage1.get_payload()
        c.send_message.assert_called_with(setmessage1)
        self.assertIsInstance(response1, SetResponse)

        response2 = c.set_program(1, '122b56', 1, [])
        setmessage2 = SetProgramMessage('122b56', 1, 1, [])
        payload2 = setmessage1.get_payload()
        c.send_message.assert_called_with(setmessage2)
        self.assertIsInstance(response2, SetResponse)

        self.assertEqual(payload1, payload2)
Beispiel #15
0
    def _parse(self):
        parts = tuple(self.data.split(b','))
        self.serial = parts[0].decode('utf-8')
        self.rf_address = RFAddr(parts[1].decode('utf-8'))
        self.fw_version = parts[2].decode('utf-8')
        # unknown = parts[3]
        self.http_connection_id = parts[4]
        self.duty_cycle = parts[5]
        self.free_mem_slots = parts[6]
        date = parts[7]
        time = parts[8]
        self.state_cube_time = parts[9]
        self.ntp_counter = parts[10]

        # 0f0c0c -> 2015-12-12
        self.datetime = datetime.datetime(
            int(date[0:2].decode('utf-8'), 16) + 2000,
            int(date[2:4].decode('utf-8'), 16),
            int(date[4:6].decode('utf-8'), 16),
            int(time[0:2].decode('utf-8'), 16),
            int(time[2:4].decode('utf-8'), 16))
Beispiel #16
0
 def test_repr(self):
     addr = RFAddr('122b65')
     self.assertEqual(str(addr), repr(addr))