Skip to content
bggardner edited this page Apr 8, 2024 · 73 revisions

Related Repositories

Serial Protocol

This section of the wiki is a sounding board for decoding of the serial protocol, and the verified/agreed upon results posted to protocol.md. Text between question marks indicate unknown, uncertain, or unverified items. Please help determine the purpose of each message, and each byte in each message by posting byte streams and their context in the Examples section.

Physical Layer

The internal serial bus is RS-485 at 115200 baud, 8 bits per byte, no parity, 1 stop bit (115200/8-N-1). The plug connector is a Molex 430250400 or TE 794617-4 (or equivalent, see here or here), with the pinout shown below. Wire colors may vary. Connections may be added by connecting to open receptacles on the Main Board, or using Y-splitters. Be sure to keep the wires twisted and/or wrapped to reduce noise injection. It is also recommended to attach pin 3 to the return of the connecting device to reduce common-mode voltage.

Pin Signal Voltage
1 Supply +12 to 15VDC
2 RS-485 B (TX+/RX+/D+) 2 to 3VDC (typically slightly higher than RS-485 A)
3 RS-485 A (TX-/RX-/D-) 2 to 3VDC (typically slightly lower than RS-485 B)
4 Return 0VDC (reference)

Message Structure

Byte Name Description/Values
0 Delimiter 0x7E
1 Length N - 2 (minimum of 5)
2 Channel (see Channels)
3 ?? 0xAF when Byte 2 is 0xFF; 0xBF otherwise
4 Type Code (see Message Types)
5 to N - 2 Arguments Optional, usually the same for each message type
N - 1 Checksum CRC-8 of bytes 1 through N-2, polynomial=0x07, initial=0x02, final XOR=0x02
N Delimiter 0x7E

Channels

The protocol uses an addressing scheme to provide direct traffic between devices. Some messages use multicast (broadcast) channels, while others use unicast (point-to-point) channels. Clients should only listen to multicast channels and their own channel, which is assigned my the Main Board. New channel assignments are incremented by one from the previous assignment, except when the assignment reaches 0x3F, the next assignment is 0x30. In addition, the Main Board does not send CTS messages to channels 0x30-0x3F, so these channels are probably not meant to be used. The only known way to "reset" channel assignment is to perform a power cycle.

Channel(s) Type Description
0x0A Unicast ?Reserved for the WiFi Module?
0x0C ?? ??
0x0F ?? ?Only on newer Main Boards?
0x10-0x2F Unicast Assigned to clients, Main Board provides CTS
0x30-0x3F ?Unicast? Assigned to clients, Main Board does not provide CTS
0x52 ?? ?Only on newer Main Boards?
0x54 ?? ?Only on newer Main Boards?
0x55 ?? ?Only on newer Main Boards?
0xFE Multicast Used by Main Board and clients for channel assignment
0xFF Multicast Used by Main Board for broadcasting to all clients

Message Types

Clients are essentially devices on the RS-485 bus other than the Main Board, such as Top Side Panels or WiFi Modules.

Type Code Name Sender Length
0x00 ?Settings 0x10 Response? Main Board 26
0x00 New Client Clear to Send Main Board @ 10 Hz or 1 Hz 5
0x01 Channel Assignment Request Client 8
0x02 Channel Assignment Response Main Board 8
0x03 Channel Assignment Acknowledgement Client 5
0x04 Existing Client Request Main Board 5
0x05 Existing Client Response Client 8
0x06 Clear to Send Main Board @ 60 Hz 5
0x07 Nothing to Send Client 5
0x11 Toggle Item Request Client 7
0x12 ?? Main Board 22
0x13 Status Update Main Board @ 3.3 Hz 27, 28, or 32
0x14 ?? Main Board 22
0x20 Set Temperature Request Client 6
0x21 Set Time Request Client 7
0x22 Settings Request Client 8
0x23 Filter Cycles Message Client (write)/Main Board (read) 12
0x24 Information Response Main Board 25
0x25 ?Settings 0x04 Response? Main Board 14
0x26 Preferences Response Main Board 23
0x27 Set Preference Request Client 7
0x28 Fault Log Response Main Board 15
0x29 ?Settings 0x40 Response? Main Board 9
0x2A Change Setup Request Client 6
0x2B GFCI Test Response Main Board 6
0x2D Lock Request Client 6
0x2E Configuration Response Main Board 11
0x48 ?? ?? 25
0x82 ?? ?? 7
0x92 Set WiFi Settings Request App 106
0x94 WiFi Module Configuration Response WiFi Module 29
0xE0 Toggle Test Setting Request Client 6
0xE1 ?Error? ?? 12
0xF0 ?Error? ?? 11

New Client Clear to Send

A New Client Clear to Send message is sent by the Main Board at 10 Hz during start up and 1 Hz otherwise. This message is for flow control (prevents collisions on the RS-485 bus), as it indicates it is safe for a client to send a Channel Assignment Request. It is unclear how multiple clients avoid collisions.

Type Code: 0x00

Length: 5

Channel Assignment Request

A Channel Assignment Request is sent by a (new) client that has not been assigned a channel, immediately after a New Client Clear to Send message is received. It is believed that argument bytes 1-2 are a hash generated by the client, which starts at a unique value and changes based on the time and/or bytes received until a New Client Clear to Send is received.

Type Code: 0x01

Length: 8

Arguments:

Byte Values/Description
0 ?Device Type: 0x02=Top Side Panel?
1-2 ?Client Hash?

Examples:

08 FE BF 01 02 76 57 (SpaTouch1 connected before power-on)
08 FE BF 01 02 F2 47 (TP900 connected before power-on)
08 FE BF 01 02 F1 73 (TP900 connected after power-on)
08 FE BF 01 02 ED E5 (TP900 connected after power-on)
08 FE BF 01 02 ED E6 (TP900 connected after power-on)
08 FE BF 01 02 EE 14 (TP900 connected after power-on)
08 FE BF 01 02 EE 5F (TP900 connected after power-on)

Channel Assignment Response

A Channel Assignment Response is sent by the Main Board after receiving a Channel Assignment Request. Depending on the arguments of the request, the response may include a new channel, or re-use an existing channel, though the details of this are unclear.

Type Code: 0x02

Length: 8

Arguments:

Byte Values/Description
0 Channel
1 ?(Usually the same as request argument byte 1)?
2 ?(Usually the same as request argument byte 2)?

Examples:

08 FE BF 02 10 76 57 (Request arguments are 0x02, 0x76, 0x57)
08 FE BF 02 10 F2 47 (Request arguments are 0x02, 0xF2, 0x47)
08 FE BF 02 11 F1 93 (Request arguments are 0x02, 0xF1, 0x73...not the same!)
08 FE BF 02 13 EE 5F (Request arguments are 0x02, 0xEE, 0x5F)
08 FE BF 02 16 EE 14 (Request arguments are 0x02, 0xEE, 0x14)
08 FE BF 02 17 EE 1D (Request arguments are 0x02, 0xEE, 0x1D)
08 FE BF 02 1D ED E5 (Request arguments are 0x02, 0xED, 0xE5)
08 FE BF 02 1D ED E6 (Request arguments are 0x02, 0xED, 0xE6)

Channel Assignment Acknowledgement

A Channel Assignment Acknowledgement is sent by a client immediately after receiving a Channel Assignment Response. When the Main Board receives this message, it begins sending CTS messages on the assigned channel.

Type Code: 0x03

Length: 5

Existing Client Request

An Existing Client Request is sent by the Main Board to determine if a client exists on the specified channel. It is also sent by the App to request a WiFi Module Configuration Response.

Type Code: 0x04

Length: 5

Existing Client Response

An Existing Client Response is sent by a client after receiving an Existing Client Request.

Type Code: 0x05

Length: 8

Arguments:

Byte Name Values
0 ?? 0x03=??, 0x04=??
1 ?? 0x08=??, 0x37=??
2 ?? 0x00=??

Clear to Send

A Clear to Send message is sent by the Main Board at 60 Hz, unless it is sending another message. This message is for flow control (prevents collisions on the RS-485 bus), as indicates it is safe for a client to send a message. Therefore, a client should only send messages immediately after detecting a Clear to Send message with its assigned channel.

Type Code: 0x06

Length: 5

Nothing to Send

A Nothing to Send message is sent by a client immediately after a Clear to Send message if the client has no messages to send.

Type Code: 0x07

Length: 5

Toggle Item Request

A Toggle Item Request is sent by a client to toggle a device or setting. There is no response from the Main Board.

Type Code: 0x11

Length: 7

Arguments:

Byte Name
0 Item Code
1 0x00
Item Code Item
0x01 Normal Operation (exit Priming Mode, etc.)
0x03 Clear notification (reminders, etc.)
0x04 Pump 1
0x05 Pump 2
0x06 Pump 3
0x07 Pump 4
0x08 Pump 5
0x09 Pump 6
0x0C Blower
0x0E Mister
0x11 Light 1
0x12 Light 2
0x16 Aux 1
0x17 Aux 2
0x1D Soak Mode (All pumps off)
0x3C Hold Mode
0x50 Temperature Range (Low/High)
0x51 Heat Mode (Ready/Rest)

Status Update

The Status Update message is sent by the Main Board three times a second. The length varies based on the SSID version, as additional features have been added in later versions.

Type Code: 0x13

Length:

SSID Length
M100_210 V6.0 28
M100_220 V20.0 29
M100_225 V36.0 29
M100_201 V44.0 32
M100_201 V47.0 32
M100_220 V50.0 32

Arguments:

Byte Name Description/Values
0 ?Spa State? 0x00=Running, 0x01=Initializing, 0x05=Hold Mode, ?0x14=A/B Temps ON?, 0x17=Test Mode
1 ?Initialization Mode? 0x00=Idle, 0x01=Priming Mode, 0x02=?Fault?, 0x03=Reminder, 0x04=?Stage 1?, 0x05=?Stage 3?, 0x42=?Stage 2?
2 Current Temperature Temperature (scaled by Temperature Scale), 0xFF if unknown
3 Time: Hour 0-23
4 Time: Minute 0-59
5 Heating Mode 0=Ready, 1=Rest, 3=Ready-in-Rest
6 Reminder Type 0x00=None, 0x04=Clean filter, 0x0A=Check the pH, 0x09=Check the sanitizer, 0x1E=?Fault?
7 Sensor A Temperature / Hold Timer Minutes if Hold Mode else Temperature (scaled by Temperature Scale) if A/B Temps else 0x01 if Test Mode else 0x00
8 Sensor B Temperature Temperature (scaled by Temperature Scale) if A/B Temps else 0x00
9 Flags Byte 9 Temperature Scale, Clock Mode, Filter Mode (see below)
10 Flags Byte 10 Heating, Temperature Range (see below)
11 Flags Byte 11 Pumps 1-4 Status (see below)
12 Flags Byte 12 Pumps 5-6 Status (see below)
13 Flags Byte 13 Circulation Pump Status, Blower Status (see below)
14 Flags Byte 14 Lights 1-2 Status (see below)
15 Mister 0=OFF, 1=ON
16 ?? 0
17 ?? 0
18 Flags Byte 18 Notification Type (see below)
19 Flags Byte 19 Circulation Cycle, Notification (see below)
20 Set Temperature Temperature (scaled by Temperature Scale)
21 Flags Byte 21 (see below)
22-23 ?? 0
24 M8 Cycle Time 0=OFF; 30, 60, 90, or 120 (in minutes)
25-26 ?? 0

Flags Byte 9

Bits Flag Values
0 Temperature Scale 0=1°F, 1=0.5°C
1 Clock Mode 0=12-hour, 1=24-hour
2 ??
3-4 Filter Mode 0=OFF, 1=Cycle 1, 2=Cycle 2, 3=Cycle 1 and 2
5 Panel Locked 0=No, 1=Yes
6 ?? 0
7 ?? 0

Flags Byte 10

Bits Flag Values
0-1 ?? 0
2 Temperature Range 0=Low, 1=High
3 ?Needs Heat? ?0=No, 1=Yes?
4-5 Heating State 0=OFF, 1=Heating, 2=Heat Waiting
6-7 ?? 0

Flags Byte 11

Bits Flag Values
0-1 Pump 1 Status 0=OFF, 1=Low, 2=High
2-3 Pump 2 Status 0=OFF, 1=Low, 2=High
4-5 Pump 3 Status 0=OFF, 1=Low, 2=High
6-7 Pump 4 Status 0=OFF, 1=Low, 2=High

Flags Byte 12

Bits Flag Values
0-1 Pump 5 Status 0=OFF, 1=Low, 2=High
2-3 Pump 6 Status 0=OFF, 1=Low, 2=High
4-7 ?? 0

Flags Byte 13

Bits Flag Values
0 ?? 0
1 Circulation Pump Status 0=OFF, 1=ON
2-3 Blower Status 0=OFF, 3=ON
4-7 ?? 0

Flags Byte 14

Bits Flag Values
0-1 Light 1 Status 0=OFF, 3=ON
2-3 Light 2 Status 0=OFF, 3=ON
4-7 ?? 0

Flags Byte 18

Bit(s) Flag Values
0 Reminder
1 ??
2 ?Fault/Warning ("The settings have been reset")?
3-7 ??

Flags Byte 19

Bit(s)s Flag Values
0-3 Cleanup Cycle ?0x00=N/A, 0x02=??, 0x04=OFF, 0x0C=ON?
4 ?? 0
5 Notification 0=No, 1=Yes
6-7 ?? 0

Flags Byte 21

Bit(s) Flag Values
0 ?? 0
1 Sensor A/B Temperatures 0=No, 1=Yes
2 Timeouts 0=Normal, 1=8 HR
3 Settings Locked / Test Mode: Temp Limits 0=No, 1=Yes
4-7 ?? 0

Set Temperature Request

A Set Temperature Request is sent by the client. There is no response from the Main Board.

Type Code: 0x20

Length: 6

Arguments: Temperature (scaled by Temperature Scale)

Set Time Request

A Set Time Request is sent by the client. There is no response from the Main Board.

Type Code: 0x21

Length: 7

Arguments:

Byte Name Values
0 Hour 0-23
1 Minute 0-59

Settings Request

A Settings Request is sent by a client and the Main Board responds with the corresponding message.

Type Code: 0x22

Length: 8

Arguments:

Byte Name
0 Settings Code
1-2 ?Subsequent Arguments?

Settings Codes

Settings Code Name Subsequent Arguments Response
0x00 Configuration 0x00, 0x01 Configuration Response
0x01 Filter Cycles 0x00, 0x00 Filter Cycles Message
0x02 Information 0x00, 0x00 Information Response
0x04 ?? 0x00, 0x00 Settings 0x04 Response
0x08 Preferences 0x00, 0x00 Preferences Response
0x10 ?? 0x00,0x00 (None)
0x20 Fault Log Entry Number (0-23, 0xFF is last fault), 0x00 Fault Log Response
0x40 ?? 0x00, 0x00 Settings 0x40 Response
0x80 GFCI Test 0x00, 0x00 GFCI Test Response

Filter Cycles Message

The Main Board sends a Filter Cycles Message when a client sends the appropriate Settings Request. The client sends a Filter Cycles Message to save/write filter cycle settings to the Main Board, which does not send a response.

Type Code: 0x23

Length: 12

Arguments:

Byte Name Values
0 Filter 1 Start: Hour 0-23
1 Filter 1 Start: Minute 0-59
2 Filter 1 Duration: Hours 0-23
3 Filter 1 Duration: Minutes 0-59
4 Filter 2 Enable/Start: Hour Bits 0-6: Hour (0-23), Bit 7: Enable (0=OFF, 1=ON)
5 Filter 2 Start: Minute 0-59
6 Filter 2 Duration: Hours 0-23
7 Filter 2 Duration: Minutes 0-59

Information Response

The Main Board sends a Filter Cycles Message when a client sends the appropriate Settings Request.

Type Code: 0x24

Length: 25

Arguments:

Byte(s) Name Description/Values
0-3 Software ID (SSID) Displayed (in decimal) as "M<byte 0>_<byte 1> V<byte 2>[.<byte 3>]"
4-11 System Model Number ASCII-encoded string
12 Current Configuration Setup Number Refer to controller Tech Sheets
13-16 Configuration Signature Checksum of the system configuration file
17 ?Heater Voltage? ?0x01=240?
18 ?Heater Type? ?0x06,0x0A=Standard?
19-20 DIP Switch Settings LSB-first (bit 0 of Byte 19 is position 1)

Examples:

25 10 BF 24 64 D2 06 00 43 53 54 42 50 33 55 4C 02 57 07 21 08 01 0A 02 00 (M100_210 V6,  CSTBP3UL, 2, 57072108, 240V, Standard, 0100000000)
25 10 BF 24 64 C9 2C 00 4D 42 50 35 30 31 55 58 03 A8 2F 63 83 01 06 05 00 (M100_201 V44, MBP501UX, 3, A82F6383, 240V, Standard, 101000)

Settings 0x04 Response

A Settings 0x04 Response is sent by the Main Board after a client sends the appropriate Settings Request.

Type Code: 0x25

Length:

SSID Length
M100_210 V6.0 14
M100_225 V36.0 14
M100_201 V44.0 15

Arguments: ??

Examples:

0E 10 BF 25 02 02 32 63 50 68 20 07 01
0E 0A BF 25 05 01 32 63 50 68 61 07 41
0F 10 BF 25 09 03 32 63 50 68 49 03 41 02

Preferences Response

A Preferences Response is sent by the Main Board after a client sends the appropriate Settings Request (using the same Channel as the request) or when a client sends a Set Preference Request (using the broadcast Channel).

Type Code: 0x26

Length: 23

Arguments:

Byte(s) Name Description/Values
0 ?? 0
1 Reminders 0=OFF, 1=OFF
2 ?? 0
3 Temperature Scale 0=1°F, 1=0.5°C
4 Clock Mode 0=12-hour, 1=24-hour
5 Cleanup Cycle 0=OFF, 1-8 (30 minute increments)
6 Dolphin Address 0=none, 1-7=address
7 ?? 0
8 M8 Artificial Intelligence 0=OFF, 1=ON
9-17 ?? 0

Set Preference Request

A Set Preference Request is sent by a client and the Main Board responds with a Preferences Response.

Type Code: 0x27

Length: 7

Arguments:

Byte Name
0 Preference Code
1 Preference Value

Preference Codes

Preference Code Name Preference Values
0x00 Reminders 0=OFF, 1=ON
0x01 Temperature Scale 0=1°F, 1=0.5°C
0x02 Clock Mode 0=12-hour, 1=24-hour
0x03 Cleanup Cycle 0=OFF, 1-8 (30 minute increments)
0x04 Dolphin Address 0=none, 1-7=address
0x05 ?? ??
0x06 M8 Artificial Intelligence 0=OFF, 1=ON

Fault Log Response

A Fault Log Response is sent by the Main Board after a client sends the appropriate Settings Request.

Type Code: 0x28

Length: 15

Arguments:

Byte Name Values
0 Total Entries 0-24
1 Entry Number 0-23 (0=Entry #1)
2 Message Code (see below)
3 Days Ago ?0-255?
4 Time: Hour 0-23
5 Time: Minute 0-59
6 Flags TODO
7 Set Temperature Temperature (scaled by Temperature Scale)
8 Sensor A Temperature Temperature (scaled by Temperature Scale)
9 Sensor B Temperature Temperature (scaled by Temperature Scale)

Fault Message Codes

Code Message
15 Sensors are out of sync
16 The water flow is low
17 The water flow has failed
18 The settings have been reset
19 Priming Mode
20 The clock has failed
21 The settings have been reset
22 Program memory failure
26 Sensors are out of sync -- Call for service
27 The heater is dry
28 The heater may be dry
29 The water is too hot
30 The heater is too hot
31 Sensor A Fault
32 Sensor B Fault
34 A pump may be stuck on
35 Hot fault
36 The GFCI test failed
37 Standby Mode (Hold Mode)

Change Setup Request

A Change Setup Request is sent by a Client, after which the Main board performs a reset.

Type Code: 0x2A

Length: 6

Arguments: Setup Number

GFCI Test Response

A GFCI Test Response is sent by the Main Board during initialization and after a client sends the appropriate Settings Request.

Type Code: 0x2B

Length: 6

Arguments:

Byte 0 Description
0x00 N/A ? or FAIL?
0x01 PASS

Lock Request

A Lock Request is sent by a Client.

Type Code: 0x2D

Length: 6

Arguments:

Byte 0 Description
0x01 Lock Settings
0x02 Lock Panel
0x03 Unlock Settings
0x04 Unlock Panel

Configuration Response

A Configuration Response is sent by the Main Board after a client sends the appropriate Settings Request.

Type Code: 0x2E

Length: 11

Arguments:

Byte Name Values
0 Pumps 1-4 Bits N to N+1: Pump N/2+1 (0=None, 1=1-speed, 2=2-speed)
1 Pumps 5-6 Bits 0-1: Pump 5, Bits 6-7: Pump 6 (0=None, 1=1-speed, 2=2-speed)
2 Lights Bits 0-1: Light 1, Bits 6-7: Light 2 (0=None, 1=Present)
3 Flags Byte 3 ?Bits 0-1: Blower, Bit 7: Circulation Pump?
4 Flags Byte 4 ?Bit 0: Aux 1, Bit 1: Aux 2, Bits 4-5: Mister?
5 ?? 0x00=??, 0x68=??

Examples:

0B 10 BF 2E 05 00 01 90 00 68 (Configuration Response: 2 1-speed pumps, 1 light, circ. pump)
0B 0A BF 2E 0A 00 01 50 00 00 (Configuration Response: 2 2-speed pumps, 1 light, no circ/blower)
0B 0A BF 2E 1A 00 01 90 00 68 (Configuration Response: 2 2-speed pumps, 1 1-speed pump, 1 light, circ. pump)
0B 10 BF 2E 2A 00 01 50 00 00 (Configuration Response: 3 2-speed pumps, 1 light, no circ/blower)

WiFi Module Configuration Response

A WiFi Module Configuration Response is sent by the WiFi Module when the App sends an Existing Client Request.

Type Code: 0x94

Length: 29

Arguments:

Byte(s) Name Values
0-2 ?? ??
3-8 Full MAC address Varies
9-16 ?? 0
17-19 MAC address: OUI 00:15:27 (Balboa Instruments)
20-21 ?? 0xFF
22-24 MAC address: NIC-specific Varies

Examples:

1D 0A BF 94 02 02 80 00 15 27 10 AB D2 00 00 00 00 00 00 00 00 00 15 27 FF FF 10 AB D2
1D 0A BF 94 02 14 80 00 15 27 3F 9B 95 00 00 00 00 00 00 00 00 00 15 27 FF FF 3F 9B 95

Toggle Test Setting Request

Type Code: 0xE0

Length: 6

Arguments:

Byte 0 Description
0x03 Sensor A/B Temperatures
0x04 Timeouts
0x05 Temp Limits

Sequences

The section defines the order of messages.

Startup

TODO

Examples

Please use this section to post examples with the context in which they were collected. It is easier to decode with more data! Please try following the same format, with the delimiters and checksums removed for clarity.


HARDWARE
========
Spa: Coast Spas Cascade III/Phantom
Spa Pack: CSTBP1C3 (56117-04)
Main Board: CSTBP1C (56118-03)
Expansion Board: 2RELAYS (55865)
Tech Sheet: 55963-02
Top Side Panel: TP900
Connection: Raspberry Pi with JBtek RS-485 USB Adapter

INFORMATION
===========
SSID: M100_210 V6
System Model: CSTBP3UL
Current Setup: 2
Configuration Signature: 57072108
Heater Voltage: 240
Heater Type: Standard
DIP Switches (1-10): 0100000000
Panel Version: BWG 4.8
25 10 BF 24 64 D2 06 00 43 53 54 42 50 33 55 4C 02 57 07 21 08 01 0A 02 00

MESSAGES
========
1C FF AF 13 00 00 49 09 25 00 00 00 00 01 00 01 00 00 00 00 00 00 00 00 49 00 00 (27-byte Status Message)
08 10 BF 05 04 08 00 (Existing Client Response from TP900)
0E 10 BF 25 02 02 32 63 50 68 20 07 01 (Settings 0x04 Response)
09 10 BF 29 15 00 00 0F (Settings 0x40 Response)
0B 10 BF 2E 2A 00 01 50 00 00 (Configuration Response: 3 2-speed pumps, 1 light, no circ/blower)

In Test Mode (only saw once):
07 10 BF 82 FE 00 (TP900 channel)
07 0C BF 82 FE 00 (~12ms later, channel 0x0C?)

Main Board power-on with TP900:
05 0A BF 04
05 0C BF 04 (~3 ms later)
05 10 BF 04 (~3 ms later)
05 11 BF 04 (~3 ms later)
... (channel increments by one) ...
05 3E BF 04 (~3 ms later)
05 3F BF 04 (~3 ms later)
06 FF AF 2B 00 (~7 ms later)
16 FF AF 12 02 00 04 05 06 11 1B 00 00 00 00 00 00 04 05 11 06 (~50 ms later)
16 FF AF 14 02 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 (~15 ms later)
16 FF AF 12 01 04 05 06 01 91 02 00 00 00 00 00 00 00 00 00 00 (~217 ms later)
16 FF AF 14 01 04 05 11 28 00 00 00 00 00 00 00 00 00 00 00 00 (~15 ms later)
05 FE BF 00 (~716 ms later)
08 FE BF 01 02 F2 47 (~1 ms later)
08 FE BF 02 10 F2 47 (~15 ms later)
05 10 BF 03 (~1 ms later)
05 10 BF 06 (~15 ms later)
05 10 BF 07 (~1 ms later)
... (Clear to Send/Nothing to Send messages at 30 Hz) ...
1C FF AF 13 01 04 00 00 00 00 00 64 4D 00 02 00 00 00 00 00 00 00 00 00 62 00 00 (~120 ms later, first Status Update)
... (New Client CTS @ 10 Hz, CTS/Nothing to Send at 30 Hz, Status Updates at 3 Hz) ...
16 10 BF 12 02 00 04 05 06 11 1B 00 00 00 00 00 00 04 05 11 06 (~235 ms later)
... (New Client CTS @ 10 Hz, CTS/Nothing to Send at 30 Hz, Status Updates at 3 Hz) ...
08 10 BF 22 04 00 00 (~365 ms later)
0E 10 BF 25 02 02 32 63 50 68 20 07 01 (~5 ms later)
... (New Client CTS @ 10 Hz, CTS/Nothing to Send at 30 Hz, Status Updates at 3 Hz) ...
1C FF AF 13 01 00 00 00 00 00 00 64 4D 00 02 00 00 00 00 00 00 00 00 00 62 00 00 (~1.736 s later, argument byte 1 changed)
... (New Client CTS @ 10 Hz, CTS/Nothing to Send at 30 Hz, Status Updates at 3 Hz) ...
1C FF AF 13 01 04 00 00 00 00 00 D2 5F 00 02 00 00 00 00 00 00 00 00 00 62 00 00 (~600 ms later, argument bytes 1, 7, and 8 changed)
... (New Client CTS @ 10 Hz, CTS/Nothing to Send at 30 Hz, Status Updates at 3 Hz) ...
1C FF AF 13 01 00 00 00 00 00 00 D2 5F 00 02 00 00 00 00 00 00 00 00 00 62 00 00 (~2.4 s later, argument byte 1 changed)
... (New Client CTS @ 10 Hz, CTS/Nothing to Send at 30 Hz, Status Updates at 3 Hz) ...
1C FF AF 13 01 42 00 00 00 00 00 06 00 00 02 00 00 00 00 00 00 00 00 00 62 00 00 (~300 ms later, argument bytes 1, 7, and 8 changed)
... (New Client CTS @ 10 Hz, CTS/Nothing to Send at 30 Hz, Status Updates at 3 Hz) ...
1C FF AF 13 01 00 00 00 00 00 00 06 00 00 02 00 00 00 00 00 00 00 00 00 62 00 00 (~2.7 s later, argument byte 1 changed)
... (New Client CTS @ 10 Hz, CTS/Nothing to Send at 30 Hz, Status Updates at 3 Hz) ...
1C FF AF 13 01 05 00 00 00 00 00 01 00 00 02 00 00 00 00 00 00 00 00 00 62 00 00 (~900 ms later, argument bytes 1 and 7 changed)
... (New Client CTS @ 10 Hz, CTS/Nothing to Send at 30 Hz, Status Updates at 3 Hz) ...
... (New Client CTS @ 1 Hz, CTS/Nothing to Send at 30 Hz, Status Updates at 3 Hz) ... (~2.5 s later, New Client CTS changes from 10 Hz to 1 Hz)
1C FF AF 13 00 01 FF 10 0B 00 13 01 00 00 06 00 00 00 00 00 00 00 00 00 62 00 00 (~200 ms later, many argument bytes changed)
... (New Client CTS @ 1 Hz, CTS/Nothing to Send at 30 Hz, Status Updates at 3 Hz) ...
1C FF AF 13 00 01 FF 10 0C 00 13 01 00 00 06 00 00 00 00 00 00 00 00 00 62 00 00 (~26 s later, argument byte 4 changed)
... (New Client CTS @ 1 Hz, CTS/Nothing to Send at 30 Hz, Status Updates at 3 Hz) ...
... (I expect Priming Mode will timeout) ...

Main Board power-on without TP900:
05 0A BF 04
05 0C BF 04 (~3 ms later)
05 10 BF 04 (~3 ms later)
05 11 BF 04 (~3 ms later)
... (channel increments by one) ...
05 3E BF 04 (~3 ms later)
05 3F BF 04 (~3 ms later)
06 FF AF 2B 00 (~8 ms later)
16 FF AF 12 02 00 04 05 06 11 1B 00 00 00 00 00 00 04 05 11 06 (~54 ms later)
16 FF AF 14 02 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 (~15 ms later)
16 FF AF 12 01 04 05 06 01 91 02 00 00 00 00 00 00 00 00 00 00 (~218 ms later)
16 FF AF 14 01 04 05 11 28 00 00 00 00 00 00 00 00 00 00 00 00 (~15 ms later)
05 FE BF 00 (~715 ms later)
1C FF AF 13 01 04 00 00 00 00 00 64 4D 00 02 00 00 00 00 00 00 00 00 00 62 00 00 (~103 ms later, first Status Update)
... (New Client Clear to Send @ 10 Hz and Status Updates @ 3 Hz continue) ...
1C FF AF 13 01 00 00 00 00 00 00 64 4D 00 02 00 00 00 00 00 00 00 00 00 62 00 00 (~2.4 s later, argument byte 1 changed)
... (New Client Clear to Send @ 10 Hz and Status Updates @ 3 Hz continue) ...
1C FF AF 13 01 04 00 00 00 00 00 D2 5F 00 02 00 00 00 00 00 00 00 00 00 62 00 00 (~600 ms later, argument bytes 1, 7, and 8 changed)
... (New Client Clear to Send @ 10 Hz and Status Updates @ 3 Hz continue) ...
1C FF AF 13 01 00 00 00 00 00 00 D2 5F 00 02 00 00 00 00 00 00 00 00 00 62 00 00 (~2.4 s later, argument byte 1 changed)
... (New Client Clear to Send @ 10 Hz and Status Updates @ 3 Hz continue) ...
1C FF AF 13 01 42 00 00 00 00 00 06 00 00 02 00 00 00 00 00 00 00 00 00 62 00 00 (~900 ms later, argument bytes 1 and 7 changed)
... (New Client Clear to Send @ 10 Hz and Status Updates @ 3 Hz continue) ...
1C FF AF 13 01 00 00 00 00 00 00 06 00 00 02 00 00 00 00 00 00 00 00 00 62 00 00 (~2.4 s later, argument byte 1 changed)
... (New Client Clear to Send @ 10 Hz and Status Updates @ 3 Hz continue) ...
1C FF AF 13 01 05 00 00 00 00 00 01 00 00 02 00 00 00 00 00 00 00 00 00 62 00 00 (~900 ms later, argument bytes 1 and 7 changed)
... (New Client Clear to Send @ 10 Hz and Status Updates @ 3 Hz continue) ...
1C FF AF 13 00 01 FF 0F 00 00 13 01 00 00 06 00 00 00 00 00 00 00 00 00 62 00 00 (~2.7 s later, many argument bytes changed)
... (New Client Clear to Send @ 1 Hz and Status Updates @ 3 Hz continue) ... (New Client Clear to Send changes from 10 Hz to 1 Hz)

When TP900 plugged in after Main Board already on: (normal traffic interleaved, but now shown)
05 FE BF 00 (Main Board: "any new clients?")
08 FE BF 01 02 F1 73 (~8 ms later, TP900: "I'm new")
08 FE BF 02 11 F1 93 (~50 ms later, new channel is 11)
05 11 BF 03          (~1 ms later)
16 11 BF 12 02 00 04 05 06 11 1B 00 00 00 00 00 00 04 05 11 06 (~33 ms later)
05 11 BF 07          (~1 ms later, and ~1ms after every Clear To Send on channel 11)
08 11 BF 22 04 00 00 (~3 s later, Settings 0x04 Request)
0E 11 BF 25 02 02 32 63 50 68 20 07 01 (~16 ms later, Settings 0x04 Response)

HARDWARE
========
Spa Pack: MBP501UX (56931-03)
Top Side Panel: SpaTouch1 (50586-03)
Connection: Raspberry Pi with BOB-10124 RS-485 Transceiver Breakout

INFORMATION
===========
Panel Version: BWG 3.55
Image File: 14
Panel Type: ST1i
SSID: M100_201 V44
System Model: MBP501UX
Configuration Signature: A82F6383
Current Setup: 3
DIP Switch Settings: 101000
Heater Voltage: 240V
Heater Type: Standard
25 10 BF 24 64 C9 2C 00 4D 42 50 35 30 31 55 58 03 A8 2F 63 83 01 06 05 00

MESSAGES
========
08 10 BF 05 03 37 00 (Existing Client Response from SpaTouch1)
0E 10 BF 25 09 03 32 63 50 68 49 03 41 02 (Settings 0x04 Response)
0B 10 BF 2E 05 00 01 90 00 68 (Configuration Response: 2 1-speed pumps, 1 light, ??)

Main Board power-on:
06 FF AF 2B 01
16 FF AF 12 04 00 04 05 11 1B 3D 00 00 00 00 00 00 04 05 00 11
16 FF AF 14 04 04 05 00 11 00 00 00 00 00 00 00 00 00 00 00 00
16 FF AF 12 01 04 05 1B 01 91 02 00 00 00 00 00 00 00 00 00 00
16 FF AF 14 01 04 05 11 28 00 00 00 00 00 00 00 00 00 00 00 00
05 FE BF 00
08 FE BF 01 02 76 57
08 FE BF 02 10 76 57
05 10 BF 03
05 10 BF 06
05 10 BF 07

Main Board after sending some invalid messages:
0B FF AF F0 52 55 4E 4C D3 00 (Module: RUNL, Code 211)

Top Side Panel while Main Board sending type_code=0xF0 on pressing back button:
07 10 BF 11 01 00 (Toggle Item)

INFORMATION
===========
SSID: M100_220 V20.0
System Model: BP2000G1
Current Setup: 4
Configuration Signature: 51800C6B
Heater Voltage: 240
Heater Type: Standard
DIP Switches (1-10): 0100000000
25 0A BF 24 64 DC 14 00 42 50 32 30 30 30 47 31 04 51 80 0C 6B 01 0A 02 00

MESSAGES
========
0B 0A BF 2E 0A 00 01 50 00 00 (Configuration Response: 2 2-speed pumps, 1 light, no circ/blower)

HARDWARE
========
Model: MasterSpa MP7
Connection: Wifi Module

INFORMATION
===========
Panel Version: BWG 3.42PLi
Image File: 11
System Model: MS40E
SSID: M100_225 V36
Current Setup: 1
Configuration Signature: C3479636
Heater Wattage: 3-6 kW
Heater Type: Standard
DIP Switch Settings: 0010001000
25 0A BF 24 64 E1 24 00 4D 53 34 30 45 20 20 20 01 C3 47 96 36 03 0A 44 00

MESSAGES
========
0E 10 BF 25 05 01 32 63 50 68 61 07 41 (Settings 0x04 Response)
0B 0A BF 2E 1A 00 01 90 00 68 (Configuration Response: 2 2-speed pumps, 1 1-speed pump, 1 light, circ. pump)

Main Board power-on:
1D FF AF 13 01 04 00 00 00 00 00 64 4D 00 02 00 00 00 00 00 00 00 00 00 4C 00 20 00
0E 0A BF 25 05 01 32 63 50 68 61 07 41
0B 0A BF 2E 1A 00 01 90 00 68
25 0A BF 24 64 E1 24 00 4D 53 34 30 45 20 20 20 01 C3 47 96 36 03 0A 44 00
1D FF AF 13 01 00 00 00 00 00 00 64 4D 00 02 00 00 00 00 00 00 00 00 00 4C 00 20 00
1D FF AF 13 01 04 00 00 00 00 00 E1 5F 00 02 00 00 00 00 00 00 00 00 00 4C 00 20 00
1D FF AF 13 01 00 00 00 00 00 00 E1 5F 00 02 00 00 00 00 00 00 00 00 00 4C 00 20 00
1D FF AF 13 01 42 00 00 00 00 00 24 00 00 02 00 00 00 00 00 00 00 00 00 4C 00 20 00
1D FF AF 13 01 00 00 00 00 00 00 24 00 00 02 00 00 00 00 00 00 00 00 00 4C 00 20 00
1D FF AF 13 01 05 00 00 00 00 00 03 06 00 02 00 00 00 00 00 00 00 00 00 4C 00 20 00
1D FF AF 13 00 01 FF 0B 2B 00 13 03 06 03 06 00 00 00 00 00 00 00 00 00 4C 00 30 00
1D FF AF 13 00 00 FF 0B 2F 00 00 03 06 03 0C 00 00 02 00 00 00 00 00 00 4C 00 00 00
1D FF AF 13 00 00 4C 0B 30 00 00 03 06 03 0C 00 00 02 00 00 00 00 00 00 4C 00 00 00

IP Protocol

The WiFi Module provides connectivity to the RS-485 serial bus via IP.

Discovery Protocol

The WiFi Module can be discovered on an network by sending a UDP broadcast packet (no data) on port 30303. The WiFi Module will respond with two ASCII-encoded lines of text, separated by CRLF. The first line is the hostname (BWGSPA, e.g.), and the second line is its MAC address. The OUI for Balboa Instruments is 00:15:27. The IP address of the returned packet is the IP address of the WiFi module.

TCP Connection

The WiFi module allows connections on TCP port 4257. It forwards messages (bidirectionally) byte-for-byte between the RS-485 bus and the TCP port, but filters out much of the internal RS-485 traffic. Only messages sent on the broadcast (0xFF) and WiFi Module (0x0A) channels are forwarded to the TCP port.