busylight
busylight copied to clipboard
Device based models / information
It would improve the developer experience to have specific models for each device instead of generic ones. Using info['serial_number']
for example could throw a warning via the mypy type checker. I suggest to ban a key if there is no value present.
At this point I have to buy each device to make sure the code that I write is actual working. Wouldn't it be great the API tells me what the device supports.
Having a printed list of each device info in the docs would be a great addition too.
I don't understand what you are asking for, could you be more specific please?
Let me try to explain it with some pseudo code (be aware I wrote this as a prove of concept). There should be one LightInfoKey
literal for each device.
from pydantic import BaseModel
from typing import Dict, Tuple, Union, Literal
LightInfoKey = Literal['vendor_id', 'product_id', 'serial_number']
LightInfo = Dict[LightInfoKey, Union[bytes, int, str, Tuple[int, int]]]
class LightDescription(BaseModel, LightInfo):
light_id: int
name: str
info: LightInfo
is_on: bool
color: str
rgb: Tuple[int, int, int]
#this should throw an typing error as path is not defined
#in case path does exist but is empty, I suggest to skip it in LightInfoKey
light.info['path']
#this is a valid access to the dict
light.info['vendor_id']
How would you use this information?
It helps me to integrate devices that I actual don't own.
I don't mean to be obtuse, but isn't that the point of using a library like busylight
? I've already done the work but you are unwilling or unable to use it? As far the the model you posted, that already exists to some degree in busylight.api.models
(but will go away when I move busyserve
out of the busylight-for-humans
package, which is imminent).
I am still confused about how this information would be made available and how you would use it to "integrate" devices.
I've already done the work but you are unwilling or unable to use it.
That is not the case, I properly use it in a way you never thought of. It's not fair to accuse me in that manner.
Example
Chroma Feedback provides filtering of it's consumer via ARGS.
program.add_argument('--compulab-fit-statusb-light-serial', action = 'append')
Each consumer provides a filtering method similar to this:
def filter_lights(lights : Any, light_serials : List[str]) -> Any:
if light_serials:
for light in copy.copy(lights):
if light.info['serial_number'] not in light_serials:
lights.remove(light)
return lights
Not every device actual contains a info['serial_number']
, so I usually fallback to it's .path
.
def filter_lights(lights : Any, light_ids : List[str]) -> Any:
if light_ids:
for light in copy.copy(lights):
if light.path not in light_ids:
lights.remove(light)
return lights
Developer are forced to own a device to integrate it properly. Like I said, a section in the docs for each device containing all information and properties would a helpfull addition or alternative.
Perhaps that was unfair, but it motivated you to provide more useful information.
I have never guaranteed the contents of busylight.lights.Light.info
, it's the bucket of data I receive from either hid.enumerate()
or serial.tools.list_ports()
and the only information I regularly consume out of that is vendor_id
, product_id
, and path
. Yes, there are some exceptions to the rule: BlinkStick and Luxafor devices for instance. Unfortunately, the USB specification does not require vendors to populate all those fields with useful information (or even consistent information) so trying to provide a consistent API to that data is a losing battle.
I suppose I still don't understand the motivation behind the light filtering functions you've shared here and I don't understand yet how your LightDescription
would be delivered to the developer other than "docs" and how they would help improve your filter functions.
Not sure what to add to this conversation as you don't understand my intention to have a typesafe info. I close the issue.
Asking questions is usually how I learn things. You have yet to clearly express your actual problem and what I could provide that would fix it. You've come closer with "type safe info" but does that mean a dictionary you can access without fear of a missing key or is this just to satisfy mypy
?
It's not to satisfy mypy - it's to prevent potential KeyValue exceptions and know what keys actual return a value without owning the device. Typing does improve the developer experience and can prevent falsy usage.
Example
from typing import Dict, Literal
LightInfoKey = Literal['vendor_id', 'product_id', 'serial_number']
LightInfo = Dict[LightInfoKey, str]
info: LightInfo
print(info['does-not-exist'])
print(info['serial_number'])
IDE

Ok, can you speak to your motivation for digging thru the info
dictionary looking for values? It will be difficult to provide these sorts of assurances since different devices populate different fields without any consistency. It appears you are looking for unique identifiers for each light ( serial_number
and path
so far in the examples you've given ). Not all lights have a serial number, in fact most do not. The path is an operating system artifact and device paths generally have a one to one relationship with devices.
I see the value of what you are asking but I'm not convinced that it solves the underlying problem, which you have not expressed.
Could you at least provide dumped output for the light.info
dict, light.path
string and other unique properties for each device inside it's docs?
Again, the question and answer dynamic is how I learn best when I don't understand something. What problem are you trying to solve that you need to use the inconsistent data in the Light.info
dictionary property?