device: move battery constants common to HID++ 1.0 and 2.0 to common

This commit is contained in:
Peter F. Patel-Schneider 2024-02-21 12:17:58 -05:00
parent 24ae9bacaa
commit 646ef2f596
6 changed files with 45 additions and 41 deletions

View File

@ -550,4 +550,19 @@ FirmwareInfo = namedtuple("FirmwareInfo", ["kind", "name", "version", "extras"])
BATTERY_APPROX = NamedInts(empty=0, critical=5, low=20, good=50, full=90)
BATTERY_STATUS = NamedInts(
discharging=0x00,
recharging=0x01,
almost_full=0x02,
full=0x03,
slow_recharge=0x04,
invalid_battery=0x05,
thermal_error=0x06,
)
def BATTERY_OK(status):
return status not in (BATTERY_STATUS.invalid_battery, BATTERY_STATUS.thermal_error)
del namedtuple

View File

@ -19,12 +19,13 @@
import logging
from .common import BATTERY_APPROX as _BATTERY_APPROX
from .common import BATTERY_STATUS as _BATTERY_STATUS
from .common import FirmwareInfo as _FirmwareInfo
from .common import bytes2int as _bytes2int
from .common import int2bytes as _int2bytes
from .common import strhex as _strhex
from .hidpp10_constants import REGISTERS
from .hidpp20_constants import BATTERY_STATUS, FIRMWARE_KIND
from .hidpp20_constants import FIRMWARE_KIND
logger = logging.getLogger(__name__)
@ -83,11 +84,11 @@ def parse_battery_status(register, reply):
charge = ord(reply[:1])
status_byte = ord(reply[2:3]) & 0xF0
status_text = (
BATTERY_STATUS.discharging
_BATTERY_STATUS.discharging
if status_byte == 0x30
else BATTERY_STATUS.recharging
else _BATTERY_STATUS.recharging
if status_byte == 0x50
else BATTERY_STATUS.full
else _BATTERY_STATUS.full
if status_byte == 0x90
else None
)
@ -110,11 +111,11 @@ def parse_battery_status(register, reply):
charging_byte = ord(reply[1:2])
if charging_byte == 0x00:
status_text = BATTERY_STATUS.discharging
status_text = _BATTERY_STATUS.discharging
elif charging_byte & 0x21 == 0x21:
status_text = BATTERY_STATUS.recharging
status_text = _BATTERY_STATUS.recharging
elif charging_byte & 0x22 == 0x22:
status_text = BATTERY_STATUS.full
status_text = _BATTERY_STATUS.full
else:
logger.warning("could not parse 0x07 battery status: %02X (level %02X)", charging_byte, status_byte)
status_text = None

View File

@ -31,6 +31,7 @@ import yaml as _yaml
from . import exceptions, special_keys
from . import hidpp10_constants as _hidpp10_constants
from .common import BATTERY_APPROX as _BATTERY_APPROX
from .common import BATTERY_STATUS as _BATTERY_STATUS
from .common import FirmwareInfo as _FirmwareInfo
from .common import NamedInt as _NamedInt
from .common import NamedInts as _NamedInts
@ -38,7 +39,7 @@ from .common import UnsortedNamedInts as _UnsortedNamedInts
from .common import bytes2int as _bytes2int
from .common import crc16 as _crc16
from .common import int2bytes as _int2bytes
from .hidpp20_constants import BATTERY_STATUS, CHARGE_LEVEL, CHARGE_STATUS, CHARGE_TYPE, DEVICE_KIND, ERROR, FEATURE, FIRMWARE_KIND, GESTURE
from .hidpp20_constants import CHARGE_LEVEL, CHARGE_STATUS, CHARGE_TYPE, DEVICE_KIND, ERROR, FEATURE, FIRMWARE_KIND, GESTURE
from .i18n import _
logger = logging.getLogger(__name__)
@ -1400,7 +1401,6 @@ def get_ids(device):
KIND_MAP = {kind: _hidpp10_constants.DEVICE_KIND[str(kind)] for kind in DEVICE_KIND}
print(KIND_MAP)
def get_kind(device):
@ -1472,7 +1472,7 @@ def get_battery_status(device):
def decipher_battery_status(report):
discharge, next, status = _unpack("!BBB", report[:3])
discharge = None if discharge == 0 else discharge
status = BATTERY_STATUS[status]
status = _BATTERY_STATUS[status]
if logger.isEnabledFor(logging.DEBUG):
logger.debug("battery status %s%% charged, next %s%%, status %s", discharge, next, status)
return FEATURE.BATTERY_STATUS, discharge, next, status, None
@ -1486,7 +1486,7 @@ def get_battery_unified(device):
def decipher_battery_unified(report):
discharge, level, status, _ignore = _unpack("!BBBB", report[:4])
status = BATTERY_STATUS[status]
status = _BATTERY_STATUS[status]
if logger.isEnabledFor(logging.DEBUG):
logger.debug("battery unified %s%% charged, level %s, charging %s", discharge, level, status)
level = (
@ -1530,23 +1530,23 @@ def get_battery_voltage(device):
def decipher_battery_voltage(report):
voltage, flags = _unpack(">HB", report[:3])
status = BATTERY_STATUS.discharging
status = _BATTERY_STATUS.discharging
charge_sts = ERROR.unknown
charge_lvl = CHARGE_LEVEL.average
charge_type = CHARGE_TYPE.standard
if flags & (1 << 7):
status = BATTERY_STATUS.recharging
status = _BATTERY_STATUS.recharging
charge_sts = CHARGE_STATUS[flags & 0x03]
if charge_sts is None:
charge_sts = ERROR.unknown
elif charge_sts == CHARGE_STATUS.full:
charge_lvl = CHARGE_LEVEL.full
status = BATTERY_STATUS.full
status = _BATTERY_STATUS.full
if flags & (1 << 3):
charge_type = CHARGE_TYPE.fast
elif flags & (1 << 4):
charge_type = CHARGE_TYPE.slow
status = BATTERY_STATUS.slow_recharge
status = _BATTERY_STATUS.slow_recharge
elif flags & (1 << 5):
charge_lvl = CHARGE_LEVEL.critical
for level in battery_voltage_remaining:
@ -1583,7 +1583,7 @@ def decipher_adc_measurement(report):
charge_level = level[1]
break
if flags & 0x01:
status = BATTERY_STATUS.recharging if flags & 0x02 else BATTERY_STATUS.discharging
status = _BATTERY_STATUS.recharging if flags & 0x02 else _BATTERY_STATUS.discharging
return FEATURE.ADC_MEASUREMENT, charge_level, None, status, adc

View File

@ -138,21 +138,6 @@ DEVICE_KIND = NamedInts(
FIRMWARE_KIND = NamedInts(Firmware=0x00, Bootloader=0x01, Hardware=0x02, Other=0x03)
def BATTERY_OK(status):
return status not in (BATTERY_STATUS.invalid_battery, BATTERY_STATUS.thermal_error)
BATTERY_STATUS = NamedInts(
discharging=0x00,
recharging=0x01,
almost_full=0x02,
full=0x03,
slow_recharge=0x04,
invalid_battery=0x05,
thermal_error=0x06,
)
ONBOARD_MODES = NamedInts(MODE_NO_CHANGE=0x00, MODE_ONBOARD=0x01, MODE_HOST=0x02)
CHARGE_STATUS = NamedInts(charging=0x00, full=0x01, not_charging=0x02, error=0x07)

View File

@ -28,6 +28,7 @@ from . import hidpp20 as _hidpp20
from . import hidpp20_constants as _hidpp20_constants
from . import settings_templates as _st
from .base import DJ_MESSAGE_ID as _DJ_MESSAGE_ID
from .common import BATTERY_STATUS as _BATTERY_STATUS
from .common import strhex as _strhex
from .i18n import _
from .status import ALERT as _ALERT
@ -357,14 +358,14 @@ def _process_feature_notification(device, status, n, feature):
charge, lux, adc = _unpack("!BHH", n.data[:5])
# guesstimate the battery voltage, emphasis on 'guess'
# status_text = '%1.2fV' % (adc * 2.67793237653 / 0x0672)
status_text = _hidpp20_constants.BATTERY_STATUS.discharging
status_text = _BATTERY_STATUS.discharging
if n.address == 0x00:
status[_K.LIGHT_LEVEL] = None
status.set_battery_info(charge, None, status_text, None)
elif n.address == 0x10:
status[_K.LIGHT_LEVEL] = lux
if lux > 200:
status_text = _hidpp20_constants.BATTERY_STATUS.recharging
status_text = _BATTERY_STATUS.recharging
status.set_battery_info(charge, None, status_text, None)
elif n.address == 0x20:
if logger.isEnabledFor(logging.DEBUG):

View File

@ -23,6 +23,8 @@ from . import hidpp10_constants as _hidpp10_constants
from . import hidpp20_constants as _hidpp20_constants
from . import settings as _settings
from .common import BATTERY_APPROX as _BATTERY_APPROX
from .common import BATTERY_OK as _BATTERY_OK
from .common import BATTERY_STATUS as _BATTERY_STATUS
from .common import NamedInt as _NamedInt
from .common import NamedInts as _NamedInts
from .i18n import _, ngettext
@ -156,11 +158,11 @@ class DeviceStatus(dict):
# Some notifications may come with no battery level info, just
# charging state info, so do our best to infer a level (even if it is just the last level)
# It is not always possible to do this well
if status == _hidpp20_constants.BATTERY_STATUS.full:
if status == _BATTERY_STATUS.full:
level = _BATTERY_APPROX.full
elif status in (_hidpp20_constants.BATTERY_STATUS.almost_full, _hidpp20_constants.BATTERY_STATUS.recharging):
elif status in (_BATTERY_STATUS.almost_full, _BATTERY_STATUS.recharging):
level = _BATTERY_APPROX.good
elif status == _hidpp20_constants.BATTERY_STATUS.slow_recharge:
elif status == _BATTERY_STATUS.slow_recharge:
level = _BATTERY_APPROX.low
else:
level = self.get(KEYS.BATTERY_LEVEL)
@ -174,17 +176,17 @@ class DeviceStatus(dict):
old_voltage, self[KEYS.BATTERY_VOLTAGE] = self.get(KEYS.BATTERY_VOLTAGE), voltage
charging = status in (
_hidpp20_constants.BATTERY_STATUS.recharging,
_hidpp20_constants.BATTERY_STATUS.almost_full,
_hidpp20_constants.BATTERY_STATUS.full,
_hidpp20_constants.BATTERY_STATUS.slow_recharge,
_BATTERY_STATUS.recharging,
_BATTERY_STATUS.almost_full,
_BATTERY_STATUS.full,
_BATTERY_STATUS.slow_recharge,
)
old_charging, self[KEYS.BATTERY_CHARGING] = self.get(KEYS.BATTERY_CHARGING), charging
changed = old_level != level or old_status != status or old_charging != charging or old_voltage != voltage
alert, reason = ALERT.NONE, None
if _hidpp20_constants.BATTERY_OK(status) and (level is None or level > _BATTERY_ATTENTION_LEVEL):
if _BATTERY_OK(status) and (level is None or level > _BATTERY_ATTENTION_LEVEL):
self[KEYS.ERROR] = None
else:
logger.warning("%s: battery %d%%, ALERT %s", self._device, level, status)