Пример #1
0
def test_reads_status_from_hwmon(mock_smart2, tmp_path):
    mock_smart2._hwmon = HwmonDevice("mock_module", tmp_path)
    (tmp_path / "pwm1_enable").write_text("1\n")
    (tmp_path / "pwm2_enable").write_text("0\n")
    (tmp_path / "pwm3_enable").write_text("0\n")
    (tmp_path / "pwm1_mode").write_text("1\n")
    (tmp_path / "pwm2_mode").write_text("0\n")
    (tmp_path / "pwm3_mode").write_text("0\n")
    (tmp_path / "pwm1_input").write_text("127\n")
    (tmp_path / "pwm2_input").write_text("102\n")
    (tmp_path / "pwm3_input").write_text("102\n")
    (tmp_path / "fan1_input").write_text("1020\n")
    (tmp_path / "fan2_input").write_text("0\n")
    (tmp_path / "fan3_input").write_text("0\n")

    expected = [
        ("Fan 1 speed", 1020, "rpm"),
        ("Fan 1 duty", pytest.approx(50, rel=1.0 / 255), "%"),
        ("Fan 1 control mode", "PWM", ""),
        ("Fan 2 speed", 0, "rpm"),
        ("Fan 2 duty", pytest.approx(40, rel=1.0 / 255), "%"),
        ("Fan 2 control mode", "DC", ""),
        ("Fan 3 speed", 0, "rpm"),
        ("Fan 3 duty", pytest.approx(40, rel=1.0 / 255), "%"),
        ("Fan 3 control mode", "DC", ""),
    ]

    got = mock_smart2.get_status()

    assert sorted(got) == sorted(expected)
Пример #2
0
def test_reads_status_directly(mock_psu, has_hwmon, direct_access):
    if has_hwmon:
        mock_psu._hwmon = HwmonDevice(None, None)

    got = mock_psu.get_status(direct_access=direct_access)

    expected = [
        ('Current uptime', timedelta(seconds=5522), ''),
        ('Total uptime', timedelta(days=13, seconds=9122), ''),
        ('Temperature 1', approx(33.5, rel=1e-3), '°C'),
        ('Temperature 2', approx(26.5, rel=1e-3), '°C'),
        ('Fan control mode', FanControlMode.SOFTWARE, ''),
        ('Fan speed', approx(968, rel=1e-3), 'rpm'),
        ('Input voltage', approx(230, rel=1e-3), 'V'),
        ('Total power output', approx(140, rel=1e-3), 'W'),
        ('+12V OCP mode', OCPMode.MULTI_RAIL, ''),
        ('+12V output voltage', approx(11.98, rel=1e-3), 'V'),
        ('+12V output current', approx(10.75, rel=1e-3), 'A'),
        ('+12V output power', approx(124, rel=1e-3), 'W'),
        ('+5V output voltage', approx(5.016, rel=1e-3), 'V'),
        ('+5V output current', approx(1.688, rel=1e-3), 'A'),
        ('+5V output power', approx(8, rel=1e-3), 'W'),
        ('+3.3V output voltage', approx(3.297, rel=1e-3), 'V'),
        ('+3.3V output current', approx(0.562, rel=1e-3), 'A'),
        ('+3.3V output power', approx(1.5, rel=1e-3), 'W'),
        ('Estimated input power', approx(153, abs=1), 'W'),
        ('Estimated efficiency', approx(92, abs=1), '%'),
    ]

    assert sorted(got) == sorted(expected)
Пример #3
0
def test_smart_device_reads_status_directly(mockSmartDevice, has_hwmon,
                                            direct_access):
    dev = mockSmartDevice
    if has_hwmon:
        dev._hwmon = HwmonDevice(None, None)

    for _, capdata in enumerate(SAMPLE_RESPONSES):
        capdata = bytes.fromhex(capdata)
        dev.device.preload_read(Report(capdata[0], capdata[1:]))

    # skip initialize for now, we're not emulating the behavior precisely
    # enough to require it here

    expected = [
        ('Fan 1 speed', 1461, 'rpm'), ('Fan 1 voltage', 11.91, 'V'),
        ('Fan 1 current', 0.02, 'A'), ('Fan 1 control mode', 'PWM', ''),
        ('Fan 2 speed', 1336, 'rpm'), ('Fan 2 voltage', 11.91, 'V'),
        ('Fan 2 current', 0.02, 'A'), ('Fan 2 control mode', 'PWM', ''),
        ('Fan 3 speed', 1390, 'rpm'), ('Fan 3 voltage', 11.91, 'V'),
        ('Fan 3 current', 0.03, 'A'), ('Fan 3 control mode', None, ''),
        ('Noise level', 63, 'dB')
    ]

    got = dev.get_status(direct_access=direct_access)

    assert expected == got
Пример #4
0
def test_smart_device_initializes(mockSmartDevice, has_hwmon, direct_access,
                                  tmp_path):
    dev = mockSmartDevice
    if has_hwmon:
        dev._hwmon = HwmonDevice('mock_module', tmp_path)

    for _, capdata in enumerate(SAMPLE_RESPONSES):
        capdata = bytes.fromhex(capdata)
        dev.device.preload_read(Report(capdata[0], capdata[1:]))

    expected = [
        ('Firmware version', '1.0.7', ''),
        ('LED accessories', 2, ''),
        ('LED accessory type', 'HUE+ Strip', ''),
        ('LED count (total)', 20, ''),
    ]

    got = dev.initialize(direct_access=direct_access)

    assert expected == got

    writes = len(dev.device.sent)
    if not has_hwmon or direct_access:
        assert writes == 2
    else:
        assert writes == 0
Пример #5
0
def test_krakenx3_warns_on_faulty_temperature(mock_krakenx3, has_hwmon, direct_access, caplog):
    if has_hwmon:
        mock_krakenx3._hwmon = HwmonDevice(None, None)

    mock_krakenx3.device.preload_read(Report(0, FAULTY_STATUS))

    _ = mock_krakenx3.get_status(direct_access=direct_access)
    assert "unexpected temperature reading" in caplog.text
Пример #6
0
def mock_hwmon(tmp_path):
    hwmon = tmp_path / "hwmon7"
    hwmon.mkdir()

    (hwmon / "fan1_input").write_text("1499\n")
    (hwmon / "fan1_label").write_text("Pump Speed\n")

    return HwmonDevice("mock_module", hwmon)
Пример #7
0
def test_krakenx3_reads_status_from_hwmon(mock_krakenx3, tmp_path):
    mock_krakenx3._hwmon = HwmonDevice("mock_module", tmp_path)
    (tmp_path / "temp1_input").write_text("33100\n")
    (tmp_path / "fan1_input").write_text("1704\n")
    (tmp_path / "pwm1_input").write_text("135\n")

    temperature, pump_speed, pump_duty = mock_krakenx3.get_status()

    assert temperature == ("Liquid temperature", 33.1, "°C")
    assert pump_speed == ("Pump speed", 1704, "rpm")
    assert pump_duty == ("Pump duty", pytest.approx(53, rel=1.0 / 255), "%")
Пример #8
0
def test_krakenx3_reads_status_directly(mock_krakenx3, has_hwmon, direct_access):
    if has_hwmon:
        mock_krakenx3._hwmon = HwmonDevice(None, None)

    mock_krakenx3.device.preload_read(Report(0, SAMPLE_STATUS))

    temperature, pump_speed, pump_duty = mock_krakenx3.get_status(direct_access=direct_access)

    assert temperature == ("Liquid temperature", 33.1, "°C")
    assert pump_speed == ("Pump speed", 1704, "rpm")
    assert pump_duty == ("Pump duty", 53, "%")
Пример #9
0
def test_krakenx3_initializes(mock_krakenx3, has_hwmon, direct_access, tmp_path):
    if has_hwmon:
        mock_krakenx3._hwmon = HwmonDevice("mock_module", tmp_path)

    # TODO check the result
    _ = mock_krakenx3.initialize(direct_access=direct_access)

    writes = len(mock_krakenx3.device.sent)
    if not has_hwmon or direct_access:
        assert writes == 4
    else:
        assert writes == 2
Пример #10
0
def test_initializes(mock_psu, has_hwmon, direct_access, tmp_path):
    if has_hwmon:
        mock_psu._hwmon = HwmonDevice('mock_module', tmp_path)

    # TODO check the result
    _ = mock_psu.initialize(direct_access=direct_access)

    writes = len(mock_psu.device.sent)
    if not has_hwmon or direct_access:
        assert writes > 0
    else:
        assert writes == 0
Пример #11
0
def test_kraken_get_status_directly(mockKrakenXDevice, has_hwmon, direct_access):
    if has_hwmon:
        mockKrakenXDevice._hwmon = HwmonDevice(None, None)

    got = mockKrakenXDevice.get_status(direct_access=direct_access)

    expected = [
        ('Liquid temperature', pytest.approx(30.9), '°C'),
        ('Fan speed', 1499, 'rpm'),
        ('Pump speed', 2702, 'rpm'),
        ('Firmware version', (6, 0, 2), ''),
    ]

    assert sorted(got) == sorted(expected)
Пример #12
0
def test_kraken_get_status_from_hwmon(mockKrakenXDevice, tmp_path):
    mockKrakenXDevice._hwmon = HwmonDevice('mock_module', tmp_path)
    (tmp_path / 'temp1_input').write_text('20900\n')
    (tmp_path / 'fan1_input').write_text('2499\n')
    (tmp_path / 'fan2_input').write_text('1702\n')

    got = mockKrakenXDevice.get_status()

    expected = [
        ('Liquid temperature', pytest.approx(20.9), '°C'),
        ('Fan speed', 2499, 'rpm'),
        ('Pump speed', 1702, 'rpm'),
        ('Firmware version', (6, 0, 2), ''),
    ]

    assert sorted(got) == sorted(expected)
Пример #13
0
def test_reads_status_from_hwmon(mock_psu, tmp_path):
    mock_psu.device.write = None  # make sure we aren't writing to the mock device

    mock_psu._hwmon = HwmonDevice('mock_module', tmp_path)
    (tmp_path / 'temp1_input').write_text('33500\n')
    (tmp_path / 'temp2_input').write_text('26500\n')
    (tmp_path / 'fan1_input').write_text('968\n')
    (tmp_path / 'in0_input').write_text('230000\n')
    (tmp_path / 'power1_input').write_text('140000000\n')
    (tmp_path / 'in1_input').write_text('11980\n')
    (tmp_path / 'curr2_input').write_text('10750\n')
    (tmp_path / 'power2_input').write_text('124000000\n')
    (tmp_path / 'in2_input').write_text('5016\n')
    (tmp_path / 'curr3_input').write_text('1688\n')
    (tmp_path / 'power3_input').write_text('8000000\n')
    (tmp_path / 'in3_input').write_text('3297\n')
    (tmp_path / 'curr4_input').write_text('562\n')
    (tmp_path / 'power4_input').write_text('1500000\n')

    got = mock_psu.get_status()

    expected = [
        ('Temperature 1', approx(33.5, rel=1e-3), '°C'),
        ('Temperature 2', approx(26.5, rel=1e-3), '°C'),
        ('Fan speed', approx(968, rel=1e-3), 'rpm'),
        ('Input voltage', approx(230, rel=1e-3), 'V'),
        ('Total power output', approx(140, rel=1e-3), 'W'),
        ('+12V output voltage', approx(11.98, rel=1e-3), 'V'),
        ('+12V output current', approx(10.75, rel=1e-3), 'A'),
        ('+12V output power', approx(124, rel=1e-3), 'W'),
        ('+5V output voltage', approx(5.016, rel=1e-3), 'V'),
        ('+5V output current', approx(1.688, rel=1e-3), 'A'),
        ('+5V output power', approx(8, rel=1e-3), 'W'),
        ('+3.3V output voltage', approx(3.297, rel=1e-3), 'V'),
        ('+3.3V output current', approx(0.562, rel=1e-3), 'A'),
        ('+3.3V output power', approx(1.5, rel=1e-3), 'W'),
        ('Estimated input power', approx(153, abs=1), 'W'),
        ('Estimated efficiency', approx(92, abs=1), '%'),
    ]

    assert sorted(got) == sorted(expected)
Пример #14
0
 def __init__(self, device, description, **kwargs):
     # compatibility with v1.1.0 drivers, which could be directly
     # instantiated with a usb.core.Device
     if isinstance(device, usb.core.Device):
         clname = self.__class__.__name__
         _LOGGER.warning(
             'constructing a %s instance from a usb.core.Device has been deprecated, '
             'use %s.find_supported_devices() or pass a HidapiDevice handle',
             clname, clname)
         usbdev = device
         hidinfo = next(
             info
             for info in hid.enumerate(usbdev.idVendor, usbdev.idProduct)
             if info['serial_number'] == usbdev.serial_number)
         assert hidinfo, 'Could not find device in HID bus'
         device = HidapiDevice(hid, hidinfo)
     super().__init__(device, description, **kwargs)
     self._hwmon = HwmonDevice.from_hidraw(device.path)
     if self._hwmon:
         _LOGGER.debug('has kernel driver: %s (%s)', self._hwmon.module,
                       self._hwmon.path)
Пример #15
0
def test_reads_status_directly(mock_smart2, has_hwmon, direct_access):
    if has_hwmon:
        mock_smart2._hwmon = HwmonDevice(None, None)

    mock_smart2.device.preload_read(Report(0, SAMPLE_STATUS))

    expected = [
        ("Fan 1 speed", 1020, "rpm"),
        ("Fan 1 duty", 50, "%"),
        ("Fan 1 control mode", "PWM", ""),
        ("Fan 2 speed", 0, "rpm"),
        ("Fan 2 duty", 40, "%"),
        ("Fan 2 control mode", None, ""),
        ("Fan 3 speed", 0, "rpm"),
        ("Fan 3 duty", 40, "%"),
        ("Fan 3 control mode", None, ""),
        ("Noise level", 48, "dB"),
    ]

    got = mock_smart2.get_status(direct_access=direct_access)

    assert sorted(got) == sorted(expected)
Пример #16
0
def test_smart_device_reads_status_from_hwmon(mockSmartDevice, tmp_path):
    dev = mockSmartDevice

    dev._hwmon = HwmonDevice('mock_module', tmp_path)
    (tmp_path / 'fan1_input').write_text('1461\n')
    (tmp_path / 'in0_input').write_text('11910\n')
    (tmp_path / 'curr1_input').write_text('20\n')
    (tmp_path / 'pwm1_mode').write_text('1\n')
    (tmp_path / 'fan2_input').write_text('1336\n')
    (tmp_path / 'in1_input').write_text('11910\n')
    (tmp_path / 'curr2_input').write_text('20\n')
    (tmp_path / 'pwm2_mode').write_text('0\n')
    (tmp_path / 'fan3_input').write_text('1390\n')
    (tmp_path / 'in2_input').write_text('11910\n')
    (tmp_path / 'curr3_input').write_text('30\n')
    (tmp_path / 'pwm3_mode').write_text('1\n')

    # skip initialize for now, we're not emulating the behavior precisely
    # enough to require it here

    expected = [
        ('Fan 1 speed', 1461, 'rpm'),
        ('Fan 1 voltage', 11.91, 'V'),
        ('Fan 1 current', 0.02, 'A'),
        ('Fan 1 control mode', 'PWM', ''),
        ('Fan 2 speed', 1336, 'rpm'),
        ('Fan 2 voltage', 11.91, 'V'),
        ('Fan 2 current', 0.02, 'A'),
        ('Fan 2 control mode', 'DC', ''),
        ('Fan 3 speed', 1390, 'rpm'),
        ('Fan 3 voltage', 11.91, 'V'),
        ('Fan 3 current', 0.03, 'A'),
        ('Fan 3 control mode', 'PWM', ''),
    ]

    got = dev.get_status()

    assert expected == got
Пример #17
0
def test_get_status_commander_pro(commanderProDevice, has_hwmon, direct_access,
                                  tmp_path):
    if has_hwmon and not direct_access:
        commanderProDevice._hwmon = HwmonDevice('mock_module', tmp_path)
        (tmp_path / 'temp1_input').write_text('26910\n')
        (tmp_path / 'temp2_input').write_text('29220\n')
        (tmp_path / 'temp4_input').write_text('25740\n')
        (tmp_path / 'fan1_input').write_text('940\n')
        (tmp_path / 'fan1_label').write_text('fan1 3pin\n')
        (tmp_path / 'fan2_input').write_text('939\n')
        (tmp_path / 'fan2_label').write_text('fan1 3pin\n')
        (tmp_path / 'fan3_input').write_text('987\n')
        (tmp_path / 'fan3_label').write_text('fan1 4pin\n')
        (tmp_path / 'in0_input').write_text('12066\n')
        (tmp_path / 'in1_input').write_text('4965\n')
        (tmp_path / 'in2_input').write_text('3359\n')
    else:
        if has_hwmon:
            commanderProDevice._hwmon = HwmonDevice('invalid_module', None)
        responses = [
            '000a8300000000000000000000000000',  # temp sensor 1
            '000b6a00000000000000000000000000',  # temp sensor 2
            '000a0e00000000000000000000000000',  # temp sensor 4
            '0003ac00000000000000000000000000',  # fan speed 1
            '0003ab00000000000000000000000000',  # fan speed 2
            '0003db00000000000000000000000000',  # fan speed 3
            '002f2200000000000000000000000000',  # get 12v
            '00136500000000000000000000000000',  # get 5v
            '000d1f00000000000000000000000000',  # get 3.3v
        ]
        for d in responses:
            commanderProDevice.device.preload_read(Report(0, bytes.fromhex(d)))

    commanderProDevice._data.store('fan_modes',
                                   [0x01, 0x01, 0x02, 0x00, 0x00, 0x00])
    commanderProDevice._data.store('temp_sensors_connected',
                                   [0x01, 0x01, 0x00, 0x01])

    res = commanderProDevice.get_status(direct_access=direct_access)
    print(res)

    assert len(res) == 9

    # temp probes
    assert res[0] == ('Temperature 1', pytest.approx(26.91, abs=1e-3), '°C')
    assert res[1] == ('Temperature 2', pytest.approx(29.22, abs=1e-3), '°C')
    assert res[2] == ('Temperature 4', pytest.approx(25.74, abs=1e-3), '°C')

    # fans rpm
    assert res[3] == ('Fan 1 speed', 940, 'rpm')
    assert res[4] == ('Fan 2 speed', 939, 'rpm')
    assert res[5] == ('Fan 3 speed', 987, 'rpm')

    # voltages
    assert res[6] == ('+12V rail', pytest.approx(12.066, abs=1e-3), 'V')
    assert res[7] == ('+5V rail', pytest.approx(4.965, abs=1e-3), 'V')
    assert res[8] == ('+3.3V rail', pytest.approx(3.359, abs=1e-3), 'V')

    if not has_hwmon or direct_access:
        # check the commands sent
        sent = commanderProDevice.device.sent
        assert len(sent) == 9

        assert sent[0].data[0] == 0x11
        assert sent[1].data[0] == 0x11
        assert sent[2].data[0] == 0x11

        assert sent[3].data[0] == 0x21
        assert sent[4].data[0] == 0x21
        assert sent[5].data[0] == 0x21

        assert sent[6].data[0] == 0x12
        assert sent[7].data[0] == 0x12
        assert sent[8].data[0] == 0x12
Пример #18
0
def test_initialize_commander_pro(commanderProDevice, has_hwmon, direct_access,
                                  tmp_path):
    if has_hwmon and not direct_access:
        commanderProDevice._hwmon = HwmonDevice('mock_module', tmp_path)
        (tmp_path / 'temp1_input').write_text('10000\n')
        (tmp_path / 'temp2_input').write_text('20000\n')
        (tmp_path / 'temp4_input').write_text('40000\n')
        (tmp_path / 'fan1_input').write_text('1100\n')
        (tmp_path / 'fan1_label').write_text('fan1 3pin\n')
        (tmp_path / 'fan2_input').write_text('1200\n')
        (tmp_path / 'fan2_label').write_text('fan1 3pin\n')
        (tmp_path / 'fan3_input').write_text('1300\n')
        (tmp_path / 'fan3_label').write_text('fan1 4pin\n')
    else:
        if has_hwmon:
            commanderProDevice._hwmon = HwmonDevice('invalid_module', None)
        responses = [
            '000009d4000000000000000000000000',  # firmware
            '00000500000000000000000000000000',  # bootloader
            '00010100010000000000000000000000',  # temp probes
            '00010102000000000000000000000000'  # fan probes
        ]
        for d in responses:
            commanderProDevice.device.preload_read(Report(0, bytes.fromhex(d)))

    res = commanderProDevice.initialize(direct_access=direct_access)

    if has_hwmon and not direct_access:
        assert len(res) == 10
        i = 0
    else:
        assert len(res) == 12
        assert res[0] == ('Firmware version', '0.9.212', '')
        assert res[1] == ('Bootloader version', '0.5', '')
        i = 2

    assert res[i + 0] == ('Temperature probe 1', True, '')
    assert res[i + 1] == ('Temperature probe 2', True, '')
    assert res[i + 2] == ('Temperature probe 3', False, '')
    assert res[i + 3] == ('Temperature probe 4', True, '')

    assert res[i + 4] == ('Fan 1 control mode', 'DC', '')
    assert res[i + 5] == ('Fan 2 control mode', 'DC', '')
    assert res[i + 6] == ('Fan 3 control mode', 'PWM', '')
    assert res[i + 7] == ('Fan 4 control mode', None, '')
    assert res[i + 8] == ('Fan 5 control mode', None, '')
    assert res[i + 9] == ('Fan 6 control mode', None, '')

    data = commanderProDevice._data.load('fan_modes', None)
    assert data is not None
    assert len(data) == 6
    assert data[0] == 0x01
    assert data[1] == 0x01
    assert data[2] == 0x02
    assert data[3] == 0x00
    assert data[4] == 0x00
    assert data[5] == 0x00

    data = commanderProDevice._data.load('temp_sensors_connected', None)
    assert data is not None
    assert len(data) == 4
    assert data[0] == 0x01
    assert data[1] == 0x01
    assert data[2] == 0x00
    assert data[3] == 0x01