Exemplo n.º 1
0
    def initialize(self, **kwargs):
        """Initialize the device and get the fan modes."""

        with self._wake_device_context():
            # Get Firmware
            res = self._send_command(_CMD_GET_FIRMWARE)
            fw_version = (res[3], res[4], res[5])

            status = [('Firmware version', '{}.{}.{}'.format(*fw_version), '')]

            # Get LEDs per fan
            res = self._read_data(_MODE_LED_COUNT, _DATA_TYPE_LED_COUNT)
            num_devices = res[0]
            led_data = res[1:1 + num_devices * 4]
            for i in range(0, num_devices):
                connected = u16le_from(led_data, offset=i * 4) == 2
                num_leds = u16le_from(led_data, offset=i * 4 + 2)
                label = 'AIO LED count' if i == 0 else f'RGB port {i} LED count'
                status += [(label, num_leds if connected else None, '')]

            # Get what fans are connected
            res = self._read_data(_MODE_CONNECTED_SPEEDS, _DATA_TYPE_CONNECTED_SPEEDS)
            num_devices = res[0]
            for i in range(0, num_devices):
                label = 'AIO port connected' if i == 0 else f'Fan port {i} connected'
                status += [(label, res[i + 1] == 0x07, '')]

            # Get what temp sensors are connected
            for i, temp in enumerate(self._get_temps()):
                connected = temp is not None
                label = 'Water temperature sensor' if i == 0 else f'Temperature sensor {i}'
                status += [(label, connected, '')]

        return status
Exemplo n.º 2
0
    def get_status(self, **kwargs):
        """Get a status report.

        Returns a list of `(property, value, unit)` tuples.
        """

        res = self._send_command(_FEATURE_COOLING, _CMD_GET_STATUS)
        assert len(self._fan_names) == 2, f'cannot yet parse with {len(self._fan_names)} fans'
        return [
            ('Liquid temperature', res[8] + res[7] / 255, '°C'),
            ('Fan 1 speed', u16le_from(res, offset=15), 'rpm'),
            ('Fan 2 speed', u16le_from(res, offset=22), 'rpm'),
            ('Pump speed', u16le_from(res, offset=29), 'rpm'),
        ]
Exemplo n.º 3
0
    def get_status(self, **kwargs):
        """Get a status report.

        Returns a list of `(property, value, unit)` tuples.
        """
        res = self._send_command(_FEATURE_COOLING, _CMD_GET_STATUS)
        status = [
            ('Liquid temperature', res[8] + res[7] / 255, '°C'),
            ('Pump speed', u16le_from(res, offset=29), 'rpm'),
        ]
        if len(self._fan_names) == 2:
            status.extend([
                ('Fan 1 speed', u16le_from(res, offset=15), 'rpm'),
                ('Fan 2 speed', u16le_from(res, offset=22), 'rpm'),
            ])
        elif len(self._fan_names) == 1:
            status.append(('Fan speed', u16le_from(res, offset=15), 'rpm'), )
        else:
            assert False, f'unxpected {len(self._fan_names)} fans to parse'
        return status
Exemplo n.º 4
0
    def _get_speeds(self):
        speeds = []

        res = self._read_data(_MODE_GET_SPEEDS, _DATA_TYPE_SPEEDS)

        num_speeds = res[0]
        speeds_data = res[1:1 + num_speeds * 2]
        for i in range(0, num_speeds):
            speeds.append(u16le_from(speeds_data, offset=i * 2))

        return speeds
Exemplo n.º 5
0
    def get_status(self, **kwargs):
        """Get a status report.

        Returns a list of `(property, value, unit)` tuples.
        """
        dataPackages =  list()
        dataPackages.append(self._build_data_package(_COMMAND_TEMP_READ, _OP_CODE_READ_TWO_BYTES))
        dataPackages.append(self._build_data_package(_COMMAND_FAN_SELECT, _OP_CODE_WRITE_ONE_BYTE, params=bytes([0])))
        dataPackages.append(self._build_data_package(_COMMAND_FAN_READ_RPM, _OP_CODE_READ_TWO_BYTES))
        dataPackages.append(self._build_data_package(_COMMAND_FAN_SELECT, _OP_CODE_WRITE_ONE_BYTE, params=bytes([1])))
        dataPackages.append(self._build_data_package(_COMMAND_FAN_READ_RPM, _OP_CODE_READ_TWO_BYTES))
        dataPackages.append(self._build_data_package(_COMMAND_FAN_SELECT, _OP_CODE_WRITE_ONE_BYTE, params=bytes([2])))
        dataPackages.append(self._build_data_package(_COMMAND_FAN_READ_RPM, _OP_CODE_READ_TWO_BYTES))

        res = self._send_command(dataPackages)

        temp = res[3] + res[2] / 255

        return [
            ('Liquid temperature', temp, '°C'),
            ('Fan 1 speed', u16le_from(res, offset=8), 'rpm'),
            ('Fan 2 speed', u16le_from(res, offset=14), 'rpm'),
            ('Pump speed', u16le_from(res, offset=20), 'rpm'),
        ]
Exemplo n.º 6
0
    def _get_temps(self):
        temps = []

        res = self._read_data(_MODE_GET_TEMPS, _DATA_TYPE_TEMPS)

        num_temps = res[0]
        temp_data = res[1:1 + num_temps * 3]
        for i in range(0, num_temps):
            connected = temp_data[i * 3] == 0x00
            if connected:
                temps.append(u16le_from(temp_data, offset=i * 3 + 1) / 10)
            else:
                temps.append(None)

        return temps
Exemplo n.º 7
0
    def write(self, data):
        data = bytes(data)  # ensure data is convertible to bytes
        self._last_write = data
        if data[0] != 0x00 or data[1] != 0x08:
            raise ValueError('Start of packets going out should be 00:08')

        if data[2] == 0x0d:
            channel = data[3]
            if self._modes[channel] is None:
                self._modes[channel] = data[4:6]
        elif data[2] == 0x05 and data[3] == 0x01:
            self._modes[data[4]] = None
        elif data[2] == 0x01 and data[3] == 0x03 and data[4] == 0x00:
            self._awake = data[5] == 0x02
        elif self._awake:
            if data[2] == 0x06:  # Write command
                channel = data[3]
                mode = self._modes[channel]
                length = u16le_from(data[4:6])
                data_type = data[8:10]
                written_data = data[10:8 + length]
                if mode[1] == 0x6d:
                    if mode[0] == 0x60 and list(data_type) == [0x03, 0x00]:
                        self.speeds_mode = tuple(
                            written_data[i + 1]
                            for i in range(0, written_data[0]))
                    elif mode[0] == 0x61 and list(data_type) == [0x04, 0x00]:
                        self.fixed_speeds = tuple(
                            u16le_from(written_data[i * 2 + 1:i * 2 + 3])
                            for i in range(0, written_data[0]))
                    else:
                        raise NotImplementedError('Invalid Write command')
                else:
                    raise NotImplementedError('Invalid Write command')

        return len(data)
Exemplo n.º 8
0
    def get_status(self, **kwargs):
        """Get a status report.

        Returns a list of `(property, value, unit)` tuples.
        """

        res = self._send_command(_FEATURE_COOLING, _CMD_GET_STATUS)

        info = [
            ('Liquid temperature', res[8] + res[7] / 255, '°C'),
        ]

        channels = [('Fan 1', 14), ('Fan 2', 21), ('Fan 3', 42)][:len(self._fan_names)]
        channels.append(('Pump', 28))

        for name, base in channels:
            info.append((f'{name} speed', u16le_from(res, offset=base + 1), 'rpm'))
            info.append((f'{name} duty', round(res[base] / 255 * 100), '%'))

        return info