Skip to content

Commit

Permalink
Merge pull request #13 from wlatanowicz/wl/add-tests
Browse files Browse the repository at this point in the history
Add tests, buffer improvements and fixes
  • Loading branch information
wlatanowicz authored Mar 27, 2023
2 parents 5521f01 + 38d1646 commit 1f6a1a0
Show file tree
Hide file tree
Showing 20 changed files with 558 additions and 47 deletions.
2 changes: 1 addition & 1 deletion indi/client/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -351,7 +351,7 @@ async def start(self):
self.process_message
)
self.blob_connection_handler = await self.blob_connection.connect(
self.process_message
self.process_message, for_blobs=True
)

asyncio.get_running_loop().create_task(
Expand Down
51 changes: 49 additions & 2 deletions indi/device/events.py
Original file line number Diff line number Diff line change
Expand Up @@ -136,13 +136,34 @@ def __init__(
self.vector = vector
self.element = element
self.prevent_default = False
self.propagate = True

def __eq__(self, __value: object) -> bool:
return (
isinstance(__value, self.__class__)
and self.__class__ == __value.__class__
and self.vector == __value.vector
and self.element == __value.element
and self.prevent_default == __value.prevent_default
)


class Write(BaseEvent):
"""Event raised after receiving new value from client.
Can be used to write new value to physical device.
Event is raised after a message with new value is received.
It is not raised after new value is assigned in code.
To raise this event in code you should use element's
`set_value` method.
After the write logic is done you can set `event.prevent_default`
to True in event handler's body to skip setting of element's internal
state if you want to update internal state after the device confirms
the change of state (in a separate callback).
If you don't change `event.prevent_default` (default is False), the state
get's updated according to the new value and `Change` event is raised.
"""

def __init__(self, element: Element, new_value) -> None:
Expand All @@ -151,11 +172,22 @@ def __init__(self, element: Element, new_value) -> None:
)
self.new_value = new_value

def __eq__(self, __value: object) -> bool:
return (
super().__eq__(__value)
and isinstance(__value, self.__class__)
and self.new_value == __value.new_value
)


class Read(BaseEvent):
"""Event raised before sending value to client.
Can be used to read value from physical device.
After the read logic is complete, use `reset_value()` on the element to
synchronize it's internal state with device's state.
Don't assign value directly nor use `set_value()` - this will cause infinite recursion.
"""

def __init__(self, element: Element) -> None:
Expand All @@ -165,11 +197,26 @@ def __init__(self, element: Element) -> None:


class Change(BaseEvent):
"""Event raised on value change."""
"""Event raised on value change.
This event is raised after the internal value of element state changes.
It's raised on both: changes caused by incoming messages and assigns of new values in code.
It is recommended to use `Read` and `Write` events to communicate with
physical device.
"""

def __init__(self, element: Element, old_value, new_value) -> None:
super().__init__(
element=element, vector=element.vector, device=element.vector.device
)
self.new_value = new_value
self.old_value = old_value

def __eq__(self, __value: object) -> bool:
return (
super().__eq__(__value)
and isinstance(__value, self.__class__)
and self.new_value == __value.new_value
and self.old_value == __value.old_value
)
18 changes: 10 additions & 8 deletions indi/message/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ class IndiMessage:
from_device = False
from_client = False

_message_classes: List[Type[IndiMessage]] = []

def __init__(self, device=None, **junk):
self.device = device

Expand All @@ -19,20 +21,20 @@ def tag_name(cls):
return cls.__name__[:1].lower() + cls.__name__[1:]

@classmethod
def __all_subclasses__(cls) -> Tuple[Type[IndiMessage], ...]:
subclasses = []
for subclass in cls.__subclasses__():
subclasses.append(subclass)
for nested_subclass in subclass.__all_subclasses__():
subclasses.append(nested_subclass)
return tuple(subclasses)
def register_message(cls, message_class):
cls._message_classes.append(message_class)
return message_class

@classmethod
def all_message_classes(cls):
return cls._message_classes

@classmethod
def from_xml(cls, xml: ET.Element) -> IndiMessage:
tag = xml.tag
message_class = None

for subclass in cls.__all_subclasses__():
for subclass in cls.all_message_classes():
if subclass.tag_name() == tag:
message_class = subclass

Expand Down
5 changes: 5 additions & 0 deletions indi/message/defs.py
Original file line number Diff line number Diff line change
Expand Up @@ -58,18 +58,22 @@ def __init__(
self.timeout = timeout


@IndiMessage.register_message
class DefBLOBVector(DefWritableVector):
children_class = DefBLOB


@IndiMessage.register_message
class DefLightVector(DefVector):
children_class = DefLight


@IndiMessage.register_message
class DefNumberVector(DefWritableVector):
children_class = DefNumber


@IndiMessage.register_message
class DefSwitchVector(DefWritableVector):
children_class = DefSwitch

Expand All @@ -78,5 +82,6 @@ def __init__(self, *args, rule: const.SwitchRuleType, **kwargs):
self.rule = checks.dictionary(rule, const.SwitchRule)


@IndiMessage.register_message
class DefTextVector(DefWritableVector):
children_class = DefText
1 change: 1 addition & 0 deletions indi/message/del_property.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
from indi.message import TimestampType


@IndiMessage.register_message
class DelProperty(IndiMessage):
from_device = True

Expand Down
1 change: 1 addition & 0 deletions indi/message/enable_blob.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
from indi.message.base import IndiMessage


@IndiMessage.register_message
class EnableBLOB(IndiMessage):
from_client = True

Expand Down
1 change: 1 addition & 0 deletions indi/message/get_properties.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
from indi.message.base import IndiMessage


@IndiMessage.register_message
class GetProperties(IndiMessage):
from_device = True
from_client = True
Expand Down
4 changes: 4 additions & 0 deletions indi/message/news.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,17 +36,21 @@ def __init__(
self.children = checks.children(children, self.children_class)


@IndiMessage.register_message
class NewBLOBVector(NewVector):
children_class = OneBLOB


@IndiMessage.register_message
class NewNumberVector(NewVector):
children_class = OneNumber


@IndiMessage.register_message
class NewSwitchVector(NewVector):
children_class = OneSwitch


@IndiMessage.register_message
class NewTextVector(NewVector):
children_class = OneText
1 change: 1 addition & 0 deletions indi/message/one_light.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
from indi.message.base import IndiMessage


@IndiMessage.register_message
class OneLight(IndiMessage):
from_device = True

Expand Down
2 changes: 2 additions & 0 deletions indi/message/pings.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
from indi.message.base import IndiMessage


@IndiMessage.register_message
class PingReply(IndiMessage):
from_client = True

Expand All @@ -9,6 +10,7 @@ def __init__(self, uid: str, **junk):
self.uid = uid


@IndiMessage.register_message
class PingRequest(IndiMessage):
from_device = True

Expand Down
5 changes: 5 additions & 0 deletions indi/message/sets.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,21 +43,26 @@ def __init__(
self.children = checks.children(children, self.child_class)


@IndiMessage.register_message
class SetBLOBVector(SetVector):
child_class = OneBLOB


@IndiMessage.register_message
class SetLightVector(SetVector):
child_class = OneLight


@IndiMessage.register_message
class SetNumberVector(SetVector):
child_class = OneNumber


@IndiMessage.register_message
class SetSwitchVector(SetVector):
child_class = OneSwitch


@IndiMessage.register_message
class SetTextVector(SetVector):
child_class = OneText
Loading

0 comments on commit 1f6a1a0

Please sign in to comment.