device: add version and device name to profiles

This commit is contained in:
Peter F. Patel-Schneider 2024-02-06 09:25:19 -05:00
parent 88f549f66c
commit 37383442f4
2 changed files with 29 additions and 7 deletions

View File

@ -1416,6 +1416,8 @@ class OnboardProfile:
_yaml.SafeLoader.add_constructor('!OnboardProfile', OnboardProfile.from_yaml) _yaml.SafeLoader.add_constructor('!OnboardProfile', OnboardProfile.from_yaml)
_yaml.add_representer(OnboardProfile, OnboardProfile.to_yaml) _yaml.add_representer(OnboardProfile, OnboardProfile.to_yaml)
OnboardProfilesVersion = 1
# Doesn't handle macros or lighting # Doesn't handle macros or lighting
class OnboardProfiles: class OnboardProfiles:
@ -1452,9 +1454,11 @@ class OnboardProfiles:
@classmethod @classmethod
def from_device(cls, device): def from_device(cls, device):
if not device.online: # wake the device up if necessary
device.ping()
response = device.feature_request(FEATURE.ONBOARD_PROFILES, 0x00) response = device.feature_request(FEATURE.ONBOARD_PROFILES, 0x00)
memory, profile, macro = _unpack('!BBB', response[0:3]) memory, profile, _macro = _unpack('!BBB', response[0:3])
if memory != 0x01 or profile > 0x03 or macro != 0x01: if memory != 0x01 or profile > 0x03:
return return
count, oob, buttons, sectors, size, shift = _unpack('!BBBBHB', response[3:10]) count, oob, buttons, sectors, size, shift = _unpack('!BBBBHB', response[3:10])
gbuttons = buttons if (shift & 0x3 == 0x2) else 0 gbuttons = buttons if (shift & 0x3 == 0x2) else 0
@ -1464,7 +1468,16 @@ class OnboardProfiles:
for sector, enabled in headers: for sector, enabled in headers:
profiles[i + 1] = OnboardProfile.from_dev(device, i, sector, size, enabled, buttons, gbuttons) profiles[i + 1] = OnboardProfile.from_dev(device, i, sector, size, enabled, buttons, gbuttons)
i += 1 i += 1
return cls(count=count, buttons=buttons, gbuttons=gbuttons, sectors=sectors, size=size, profiles=profiles) return cls(
version=OnboardProfilesVersion,
name=device.name,
count=count,
buttons=buttons,
gbuttons=gbuttons,
sectors=sectors,
size=size,
profiles=profiles
)
def to_bytes(self): def to_bytes(self):
bytes = b'' bytes = b''
@ -1477,7 +1490,7 @@ class OnboardProfiles:
return bytes return bytes
@classmethod @classmethod
def read_sector(cls, dev, sector, s): # doesn't check for valid sector or length def read_sector(cls, dev, sector, s): # doesn't check for valid sector or size
bytes = b'' bytes = b''
o = 0 o = 0
while o < s - 15: while o < s - 15:
@ -1489,7 +1502,7 @@ class OnboardProfiles:
return bytes return bytes
@classmethod @classmethod
def write_sector(cls, device, s, bs): # doesn't check for valid sector or length def write_sector(cls, device, s, bs): # doesn't check for valid sector or size
rbs = OnboardProfiles.read_sector(device, s, len(bs)) rbs = OnboardProfiles.read_sector(device, s, len(bs))
if rbs[:-2] == bs[:-2]: if rbs[:-2] == bs[:-2]:
return False return False
@ -1501,7 +1514,7 @@ class OnboardProfiles:
device.feature_request(FEATURE.ONBOARD_PROFILES, 0x80) device.feature_request(FEATURE.ONBOARD_PROFILES, 0x80)
return True return True
def write(self, device): # doesn't check for valid sectors or length def write(self, device):
try: try:
written = 1 if OnboardProfiles.write_sector(device, 0, self.to_bytes()) else 0 written = 1 if OnboardProfiles.write_sector(device, 0, self.to_bytes()) else 0
except Exception as e: except Exception as e:
@ -1509,6 +1522,8 @@ class OnboardProfiles:
raise e raise e
for p in self.profiles.values(): for p in self.profiles.values():
try: try:
if p.sector >= self.sectors:
raise Exception(f'Sector {p.sector} not a writable sector')
written += 1 if OnboardProfiles.write_sector(device, p.sector, p.to_bytes(self.size)) else 0 written += 1 if OnboardProfiles.write_sector(device, p.sector, p.to_bytes(self.size)) else 0
except Exception as e: except Exception as e:
_log.warn(f'Exception writing onboard profile sector {p.sector}') _log.warn(f'Exception writing onboard profile sector {p.sector}')

View File

@ -21,6 +21,7 @@ import traceback as _traceback
import yaml as _yaml import yaml as _yaml
from logitech_receiver.hidpp20 import OnboardProfiles as _OnboardProfiles from logitech_receiver.hidpp20 import OnboardProfiles as _OnboardProfiles
from logitech_receiver.hidpp20 import OnboardProfilesVersion as _OnboardProfilesVersion
def run(receivers, args, find_receiver, find_device): def run(receivers, args, find_receiver, find_device):
@ -50,7 +51,13 @@ def run(receivers, args, find_receiver, find_device):
print(f'Reading profiles from {profiles_file}') print(f'Reading profiles from {profiles_file}')
profiles = _yaml.safe_load(f) profiles = _yaml.safe_load(f)
if not isinstance(profiles, _OnboardProfiles): if not isinstance(profiles, _OnboardProfiles):
print('Profiles file does not contain onboard profiles') print('Profiles file does not contain current onboard profiles')
elif getattr(profiles, 'version', None) != _OnboardProfilesVersion:
version = getattr(profiles, 'version', None)
print(f'Missing or incorrect profile version {version} in loaded profile')
elif getattr(profiles, 'name', None) != dev.name:
name = getattr(profiles, 'name', None)
print(f'Different device name {name} in loaded profile')
else: else:
print(f'Loading profiles into {dev.name}') print(f'Loading profiles into {dev.name}')
written = profiles.write(dev) written = profiles.write(dev)