Skip to content

Use zigpy integer, enum, and bitmap types #225

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Sep 26, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion tests/test_commands.py
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ def test_error_code():

r, rest = t.ErrorCode.deserialize(b"\xaa" + extra)
assert rest == extra
assert r.name == "unknown_0xAA"
assert r.name == "undefined_0xaa"


def _validate_schema(schema):
Expand Down
42 changes: 3 additions & 39 deletions tests/test_types_basic.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,8 @@ class TestList(t.LVList, item_type=t.uint8_t, length_type=t.uint8_t):
assert t.serialize_list([]) == b""


def test_enum_uint():
class TestEnum(t.enum_flag_uint16):
def test_enum():
class TestEnum(t.bitmap16):
ALL = 0xFFFF
CH_1 = 0x0001
CH_2 = 0x0002
Expand All @@ -39,19 +39,6 @@ class TestEnum(t.enum_flag_uint16):
assert TestEnum(0x8012).serialize() == data


def test_abstract_ints():
assert issubclass(t.uint8_t, t.uint_t)
assert not issubclass(t.uint8_t, t.int_t)
assert t.int_t._signed is True
assert t.uint_t._signed is False

with pytest.raises(TypeError):
t.int_t(0)

with pytest.raises(TypeError):
t.FixedIntType(0)


def test_int_too_short():
with pytest.raises(ValueError):
t.uint8_t.deserialize(b"")
Expand Down Expand Up @@ -132,29 +119,6 @@ class TestList(t.LVList, item_type=t.uint8_t, length_type=t.uint8_t):
TestList.deserialize(b"\x04123")


def test_hex_repr():
class NwkAsHex(t.uint16_t, hex_repr=True):
pass

nwk = NwkAsHex(0x123A)
assert str(nwk) == "0x123A"
assert repr(nwk) == "0x123A"

assert str([nwk]) == "[0x123A]"
assert repr([nwk]) == "[0x123A]"

# You can turn it off as well
class NwkWithoutHex(NwkAsHex, hex_repr=False):
pass

nwk = NwkWithoutHex(1234)
assert str(nwk) == "1234"
assert repr(nwk) == "1234"

assert str([nwk]) == "[1234]"
assert repr([nwk]) == "[1234]"


def test_fixed_list():
class TestList(t.FixedList, item_type=t.uint16_t, length=3):
pass
Expand Down Expand Up @@ -187,7 +151,7 @@ class TestList(t.FixedList, length=3, item_type=t.uint16_t):


def test_enum_instance_types():
class TestEnum(t.enum_uint8):
class TestEnum(t.enum8):
Member = 0x00

assert TestEnum._member_type_ is t.uint8_t
Expand Down
2 changes: 1 addition & 1 deletion tests/test_types_cstruct.py
Original file line number Diff line number Diff line change
Expand Up @@ -273,7 +273,7 @@ class TestStruct(t.CStruct):
def test_old_nib_deserialize():
PaddingByte: typing_extensions.TypeAlias = t.uint8_t

class NwkState16(t.enum_uint16):
class NwkState16(t.enum16):
NWK_INIT = 0
NWK_JOINING_ORPHAN = 1
NWK_DISC = 2
Expand Down
29 changes: 1 addition & 28 deletions tests/test_types_named.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ def test_status():
assert rest == extra
assert r == 0x33
assert r.value == 0x33
assert r.name == "unknown_0x33"
assert r.name == "undefined_0x33"


def test_addr_mode_address():
Expand Down Expand Up @@ -99,24 +99,6 @@ def test_addr_mode_address():
assert r3 != r4


def test_missing_status_enum():
class TestEnum(t.MissingEnumMixin, t.enum_uint8):
Member = 0x00

assert 0xFF not in list(TestEnum)
assert isinstance(TestEnum(0xFF), TestEnum)
assert TestEnum(0xFF).value == 0xFF
assert type(TestEnum(0xFF).value) is t.uint8_t

# Missing members that don't fit can't be created
with pytest.raises(ValueError):
TestEnum(0xFF + 1)

# Missing members that aren't integers can't be created
with pytest.raises(ValueError):
TestEnum("0xFF")


def test_zdo_nullable_node_descriptor():
desc1, data = c.zdo.NullableNodeDescriptor.deserialize(b"\x00")

Expand All @@ -131,12 +113,3 @@ def test_zdo_nullable_node_descriptor():

assert not data
assert desc2.serialize() == desc3.serialize()


def test_missing_enum_mixin():
class TestEnum(t.MissingEnumMixin, t.enum_uint8):
FOO = 0x01

assert TestEnum(0x01) == 0x01 == TestEnum.FOO
assert TestEnum(0x02) == 0x02
assert 0x02 not in TestEnum._value2member_map_
4 changes: 2 additions & 2 deletions zigpy_znp/commands/af.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import zigpy_znp.types as t


class TransmitOptions(t.enum_flag_uint8):
class TransmitOptions(t.bitmap8):
NONE = 0

# Will force the message to use Wildcard ProfileID
Expand All @@ -19,7 +19,7 @@ class TransmitOptions(t.enum_flag_uint8):
SKIP_ROUTING = 0x80


class LatencyReq(t.enum_uint8):
class LatencyReq(t.enum8):
NoLatencyReqs = 0x00
FastBeacons = 0x01
SlowBeacons = 0x02
Expand Down
10 changes: 5 additions & 5 deletions zigpy_znp/commands/app_config.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
import zigpy_znp.types as t


class TimeoutIndex(t.enum_uint8):
class TimeoutIndex(t.enum8):
Seconds_10 = 0x00

Minutes_2 = 0x01
Expand All @@ -22,15 +22,15 @@ class TimeoutIndex(t.enum_uint8):
Minutes_16384 = 0x0E


class CentralizedLinkKeyMode(t.enum_uint8):
class CentralizedLinkKeyMode(t.enum8):
UseDefault = 0x00
UseProvidedInstallCode = 0x01
UseProvidedInstallCodeAndFallbackToDefault = 0x02
UseProvidedAPSLinkKey = 0x03
UseProvidedAPSLinkKeyAndFallbackToDefault = 0x04


class BDBCommissioningStatus(t.enum_uint8):
class BDBCommissioningStatus(t.enum8):
Success = 0x00
InProgress = 0x01
NoNetwork = 0x02
Expand All @@ -48,7 +48,7 @@ class BDBCommissioningStatus(t.enum_uint8):
Failure = 0x0E


class BDBCommissioningMode(t.enum_flag_uint8):
class BDBCommissioningMode(t.bitmap8):
NONE = 0

InitiatorTouchLink = 1 << 0
Expand All @@ -59,7 +59,7 @@ class BDBCommissioningMode(t.enum_flag_uint8):
ParentLost = 1 << 5


class InstallCodeFormat(t.enum_uint8):
class InstallCodeFormat(t.enum8):
InstallCodeAndCRC = 0x01
KeyDerivedFromInstallCode = 0x02

Expand Down
2 changes: 1 addition & 1 deletion zigpy_znp/commands/rpc_error.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import zigpy_znp.types as t


class ErrorCode(t.enum_uint8):
class ErrorCode(t.enum8):
InvalidSubsystem = 0x01
InvalidCommandId = 0x02
InvalidParameter = 0x03
Expand Down
14 changes: 7 additions & 7 deletions zigpy_znp/commands/sys.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,13 @@
import zigpy_znp.types as t


class BootloaderBuildType(t.enum_uint8):
class BootloaderBuildType(t.enum8):
NON_BOOTLOADER_BUILD = 0
BUILT_AS_BIN = 1
BUILT_AS_HEX = 2


class ADCChannel(t.enum_uint8):
class ADCChannel(t.enum8):
"""The ADC channel."""

AIN0 = 0x00
Expand All @@ -26,7 +26,7 @@ class ADCChannel(t.enum_uint8):
Voltage = 0x0F


class ADCResolution(t.enum_uint8):
class ADCResolution(t.enum8):
"""Resolution of the ADC channel."""

bits_8 = 0x00
Expand All @@ -35,7 +35,7 @@ class ADCResolution(t.enum_uint8):
bits_14 = 0x03


class GPIOPinMode(t.enum_flag_uint8):
class GPIOPinMode(t.bitmap8):
"""Pin state. Any pin with an unspecified state bit is pulled up."""

Tristate0 = 0b0000_0001
Expand All @@ -49,7 +49,7 @@ class GPIOPinMode(t.enum_flag_uint8):
PullDown3 = 0b1000_0000


class GPIOPinDirection(t.enum_flag_uint8):
class GPIOPinDirection(t.bitmap8):
"""Pin direction. Any pin with an unspecified direction bit is an input pin."""

Output0 = 0b0000_0001
Expand All @@ -58,7 +58,7 @@ class GPIOPinDirection(t.enum_flag_uint8):
Output3 = 0b0000_1000


class GPIOOperation(t.enum_uint8):
class GPIOOperation(t.enum8):
"""Specifies the type of operation to perform on the GPIO pins."""

SetDirection = 0x00
Expand All @@ -70,7 +70,7 @@ class GPIOOperation(t.enum_uint8):
HiD = 0x12 # ???


class StackTuneOperation(t.enum_uint8):
class StackTuneOperation(t.enum8):
"""The tuning operation to be executed."""

# XXX: [Value] should correspond to the valid values specified by the
Expand Down
6 changes: 3 additions & 3 deletions zigpy_znp/commands/ubl.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
FLASH_WORD_SIZE = 4


class BootloaderStatus(t.enum_uint8):
class BootloaderStatus(t.enum8):
SUCCESS = 0
FAILURE = 1
INVALID_FCS = 2
Expand All @@ -23,12 +23,12 @@ class BootloaderStatus(t.enum_uint8):
CANCELED = 8


class BootloaderDeviceType(t.enum_uint8):
class BootloaderDeviceType(t.enum8):
CC2538 = 1
CC2530 = 2


class BootloaderRunMode(t.enum_uint8):
class BootloaderRunMode(t.enum8):
# Read the code, not the spec
FORCE_BOOT = 0x10
FORCE_RUN = FORCE_BOOT ^ 0xFF
Expand Down
4 changes: 2 additions & 2 deletions zigpy_znp/commands/util.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
import zigpy_znp.types as t


class NodeRelation(t.enum_uint8):
class NodeRelation(t.enum8):
PARENT = 0
CHILD_RFD = 1
CHILD_RFD_RX_IDLE = 2
Expand Down Expand Up @@ -62,7 +62,7 @@ class RandomNumbers(t.FixedList, item_type=t.uint8_t, length=100):
pass


class LEDMode(t.enum_uint8):
class LEDMode(t.enum8):
OFF = 0
ON = 1
BLINK = 2
Expand Down
16 changes: 8 additions & 8 deletions zigpy_znp/commands/zdo.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,27 +17,27 @@ class SecurityEntry(t.FixedList, item_type=t.uint8_t, length=5):
pass


class StartupState(t.enum_uint8):
class StartupState(t.enum8):
RestoredNetworkState = 0x00
NewNetworkState = 0x01
NotStarted = 0x02


class RouteDiscoveryOptions(t.enum_flag_uint8):
class RouteDiscoveryOptions(t.bitmap8):
UNICAST = 0x00
MTO_WITH_ROUTE_CACHE = 0x01
MTO_WITHOUT_ROUTE_CACHE = 0x03


class RouteStatus(t.enum_uint8):
class RouteStatus(t.enum8):
INIT = 0
ACTIVE = 1
DISC = 2
LINK_FAIL = 3
REPAIR = 4


class RouteOptions(t.enum_flag_uint8):
class RouteOptions(t.bitmap8):
# Used in option of NLME_RouteDiscoveryRequest() and rtgTable[]
MTO_ROUTE = 0x01

Expand All @@ -60,7 +60,7 @@ class RouteOptions(t.enum_flag_uint8):
MULTICAST_ROUTE = 0x40


class RoutingStatus(t.enum_uint8):
class RoutingStatus(t.enum8):
SUCCESS = 0
FAIL = 1
TBL_FULL = 2
Expand All @@ -71,7 +71,7 @@ class RoutingStatus(t.enum_uint8):
SRC_TBL_FULL = 7


class MACCapabilities(t.enum_flag_uint8):
class MACCapabilities(t.bitmap8):
PANCoordinator = 1 << 0
Router = 1 << 1
MainsPowered = 1 << 2
Expand All @@ -82,7 +82,7 @@ class MACCapabilities(t.enum_flag_uint8):
AllocateShortAddrDuringAssocNeeded = 1 << 7


class LeaveOptions(t.enum_flag_uint8):
class LeaveOptions(t.bitmap8):
NONE = 0
Rejoin = 1 << 0
RemoveChildren = 1 << 1
Expand Down Expand Up @@ -136,7 +136,7 @@ def serialize(self) -> bytes:
return super().serialize()


class AddrRequestType(t.enum_uint8):
class AddrRequestType(t.enum8):
SINGLE = 0x00
EXTENDED = 0x01

Expand Down
2 changes: 1 addition & 1 deletion zigpy_znp/commands/znp.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import zigpy_znp.types as t


class DiscreteCommand(t.enum_flag_uint8):
class DiscreteCommand(t.bitmap8):
ZDOStart = 0x40
ResetNwk = 0x80

Expand Down
Loading