Skip to content

Commit

Permalink
Add support for encoding/decoding irrigation queue messages (#96)
Browse files Browse the repository at this point in the history
Add support for encoding/decoding irrigation queue messages

Issue #40

Using test case examples from
homebridge-plugins/homebridge-rainbird#396
  • Loading branch information
allenporter authored Jan 22, 2023
1 parent e29999b commit d9ed08e
Show file tree
Hide file tree
Showing 3 changed files with 186 additions and 3 deletions.
49 changes: 48 additions & 1 deletion pyrainbird/rainbird.py
Original file line number Diff line number Diff line change
Expand Up @@ -92,11 +92,56 @@ def decode_schedule(data: str, cmd_template: dict[str, Any]) -> dict[str, Any]:
return {"data": data}


def decode_queue(data: str, cmd_template: dict[str, Any]) -> dict[str, Any]:
"""Decode a queue command."""
page = int(data[2:4], 16)
rest = data[4:]
if page == 0:
# Currently running program
return {
"program": {
"program": int(rest[0:2], 16),
"running": bool(int(rest[2:4], 16)),
"zonesRemaining": int(rest[4:6], 16),
}
}

if page == 1:
queue = []
for i in range(0, 8):
base = i * 8
program = int(data[base + 4 : base + 6], 16)
zone = int(data[base + 6 : base + 8], 16)
runtime = int(data[base + 8 : base + 12], 16)
if runtime > 0:
runtime = ((runtime & 0xFF00) >> 8) | ((runtime & 0xFF) << 8)
if zone:
queue.append({"program": program, "zone": zone, "seconds": runtime})
return {"zones": queue}

if len(data) == 100:
_LOGGER.debug("data=%s", data)
queue = []
for i in range(0, 8):
base = i * 12
program = int(data[base + 4 : base + 6], 16)
zone = int(data[base + 6 : base + 8], 16)
runtime = int(data[base + 8 : base + 12], 16)
if runtime > 0:
runtime = ((runtime & 0xFF00) >> 8) | ((runtime & 0xFF) << 8)
if zone:
queue.append({"program": program, "zone": zone, "seconds": runtime})
return {"zones": queue}

return {"data": data}


DEFAULT_DECODER = "decode_template"

DECODERS: dict[str, Callable[[str, dict[str, Any]], dict[str, Any]]] = {
"decode_template": decode_template,
"decode_schedule": decode_schedule,
"decode_queue": decode_queue,
}


Expand Down Expand Up @@ -125,7 +170,9 @@ def encode_command(command_set: dict[str, Any], *args) -> str:
"""Encode a rainbird tunnelSip command request."""
cmd_code = command_set["command"]
if not (length := command_set[LENGTH]):
raise RainbirdCodingException(f"Unable to encode command missing length: {command_set}")
raise RainbirdCodingException(
f"Unable to encode command missing length: {command_set}"
)
if len(args) > length:
raise RainbirdCodingException(
f"Too many parameters. {length} expected: {command_set}"
Expand Down
21 changes: 19 additions & 2 deletions pyrainbird/resources/sipcommands.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,13 @@ ControllerCommands:
parameter: 0
response: '01'
length: 2
# CurrentQueueRequest: 3B
CurrentQueueRequest:
command: 3B
response: 'BB'
length: 2
page:
position: 2
length: 2
CurrentRainSensorStateRequest:
command: 3E
response: BE
Expand Down Expand Up @@ -145,6 +151,15 @@ ControllerCommands:
parameterThree: 0
response: '01'
length: 4
page:
position: 2
length: 2
zone:
position: 4
length: 2
minutes:
position: 6
length: 2
CombinedControllerStateRequest:
command: 4C
response: CC
Expand Down Expand Up @@ -278,7 +293,9 @@ ControllerResponses:
delaySetting:
position: 2
length: 4
# CurrentQueueResponse BB
CurrentQueueResponse:
command: BB
decoder: decode_queue
CurrentRainSensorStateResponse:
command: 'BE'
length: 2
Expand Down
119 changes: 119 additions & 0 deletions tests/testdata/current_queue.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
data:
- 4B000102
- 014B
- 4B000202
- 014B
- 4B000302
- 014B
- 3B00
- BB000401020000
- 3B01
- BB01000176000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
- 3B02
- BB02000278000000000378000000000000000000000000000000000000000000000000000000000000000000000000000000
- 3B01
- BB0100016B000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
- 3B02
- BB02000278000000000378000000000000000000000000000000000000000000000000000000000000000000000000000000
- 3B01
- BB01000161000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
- 3B02
- BB02000278000000000378000000000000000000000000000000000000000000000000000000000000000000000000000000
- 3B01
- BB01000157000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
- 3B02
- BB02000278000000000378000000000000000000000000000000000000000000000000000000000000000000000000000000
decoded_data:
- type: StackManuallyRunStationRequest
page: 0
zone: 1
minutes: 2
- type: AcknowledgeResponse
commandEcho: 75
- type: StackManuallyRunStationRequest
page: 0
zone: 2
minutes: 2
- type: AcknowledgeResponse
commandEcho: 75
- type: StackManuallyRunStationRequest
page: 0
zone: 3
minutes: 2
- type: AcknowledgeResponse
commandEcho: 75
- type: CurrentQueueRequest
page: 0
- type: CurrentQueueResponse
program:
program: 4 # Manual
running: True
zonesRemaining: 2
- type: CurrentQueueRequest
page: 1
- type: CurrentQueueResponse
zones:
- zone: 1
program: 0
seconds: 118
- type: CurrentQueueRequest
page: 2
- type: CurrentQueueResponse
zones:
- zone: 2
program: 0
seconds: 120
- zone: 3
program: 0
seconds: 120
- type: CurrentQueueRequest
page: 1
- type: CurrentQueueResponse
zones:
- zone: 1
program: 0
seconds: 107
- type: CurrentQueueRequest
page: 2
- type: CurrentQueueResponse
zones:
- zone: 2
program: 0
seconds: 120
- zone: 3
program: 0
seconds: 120
- type: CurrentQueueRequest
page: 1
- type: CurrentQueueResponse
zones:
- zone: 1
program: 0
seconds: 97
- type: CurrentQueueRequest
page: 2
- type: CurrentQueueResponse
zones:
- zone: 2
program: 0
seconds: 120
- zone: 3
program: 0
seconds: 120
- type: CurrentQueueRequest
page: 1
- type: CurrentQueueResponse
zones:
- zone: 1
program: 0
seconds: 87
- type: CurrentQueueRequest
page: 2
- type: CurrentQueueResponse
zones:
- zone: 2
program: 0
seconds: 120
- zone: 3
program: 0
seconds: 120

0 comments on commit d9ed08e

Please sign in to comment.