Skip to content
This repository has been archived by the owner on Feb 20, 2020. It is now read-only.

Latest commit

 

History

History
124 lines (108 loc) · 5.79 KB

protocol.mdown

File metadata and controls

124 lines (108 loc) · 5.79 KB

SUD Protocol

This is an attempt to describe the SUD protocol based on reading the main.cpp file that Seneye released. Contributions via git pull requests are most welcome.

USB device

USB devices have a hierarchy of interfaces, like so:

  • Device
  • Configuration
  • Interface
  • Alternate setting
  • Endpoint

Transfers

The SUD device seems to have these 2 types of USB transfers available: interrupt and bulk. HID devices only use 2 transfer modes of either control or interrupt. From from https://en.wikipedia.org/wiki/USB_human_interface_device_class HID devices do not use the 'bulk' interface, so only the 'interrupt' interface is used. In any case, we search for the endpoints rather than hard code them.

Endpoints

Max packet size is 64 bytes for all endpoints. From printing the configuration these are the endpoints:

  • ENDPOINT 0x81: Interrupt IN
  • ENDPOINT 0x1: Interrupt OUT
  • ENDPOINT 0x82: Bulk IN
  • ENDPOINT 0x2: Bulk OUT

Protocol

Protocol flow

From what I have been able to determine from the C++ module that Seneye released, the flow goes a little like this: once you have obtained correct access to the device via USB handlers, you start by sending the "HELLOSUD" message and receive a version message in response. You then ask for the sensor values using a message "READING", and get back a return code if the command was accepted. You then read the next message (no command) with a longer timeout and get the sensor values. At the end you then send a "BYESUD" closing message to stop communication and close down the USB handlers as appropriate. The command to switch on or off the LEDs is similar.

I also found after a number of tests that the slide LED would light up, and no more readings could be taken. This seemed to be due to the device filling up some sort of offline memory and preventing any more until it had been loaded to the cloud. This was cleared by using the Windows Seneye Connect app and I noticed that it went through a routine of doing the offline uploads, after which the LED cleared and it could be read again. This feature may limit the usefulness of any foreign program reading the SUD, unless we can either dummy up the upload or utilise some of the control messages to the SUD.

Protocol messages

There are command type messages, and response messages with readings from the device.

  • Command: Communication starts with a message "HELLOSUD".
  • Command: Request sensor parameters with a "READING" message.
  • Command: Turn off or on LEDS with a "LED" message.
  • Command: Communcation ends with a "BYESUD" message
  • Response: from "HELLOSUD"
    • byte 1: eyecatcher value = 0x88
    • byte 2: 0x01
    • byte 3: '1'=success, otherwise=failure
    • byte 4: the type of the device, 0/1=home, 2=pond, 3=reef
    • byte 5: device version byte 1
    • byte 6: device version byte 2, version is x.x.x
  • Response: from "READING"
    • byte 1: eyecatcher value = 0x88
    • byte 2: '0x02'
    • byte 3: '1'=success, otherwise=failure
  • Response: from "LED"
    • byte 1: eyecatcher value = 0x88
    • byte 2: '0x03'
    • byte 3: '1'=success, otherwise=failure
  • Response: from "BYESUD"
    • byte 1: eyecatcher value = 0x77
    • byte 2: '0x01'
    • byte 3: '0x01'
  • Response: subsequent read after "READING" command and response
    • byte 1: eyecatcher value = 0x00
    • byte 2: '0x01'=reading
  • Response: subsequent read after "READING" command and response
    • byte 1: eyecatcher value = 0x00
    • byte 2: '0x02'=lightmeter reading

Protocol table

Outgoing to SUD

Byte 1 Byte 2 Byte 3 Byte 4 Byte 5 Byte 6 Byte 7 Byte 8 Description
H E L L O S U D Start comms
R E A D I N G READING
L E D L1 L2 L3 L4 L5 LEDs 1-5 on/off
B Y E S U D End comms

Incoming from SUD

Byte 1 Byte 2 Byte 3 Byte 4 Byte 5 Byte 6 Byte 7 Byte 8 Description
0x88 0x01 1 type ver.b1 ver.b2 Response from HELLOSUD
0x88 0x02 1 Response from READING
0x88 0x03 1 Response from LED
0x77 0x01 1 Response from BYESUD
0x00 0x01 Reading
0x00 0x02 Lightmeter reading
READING bit string

The message returned from the READING command contains a mixture of bits and byte values. This means a little more work in Python but we can use the Bitstring library. The use of a STRUCT will mean that bit padding will occur so that things like char, int and short are byte-aligned. The ints and shorts are also little-endian.

I have mapped the following values:

C type length in bits Position Name Description
int 32 Ts Unix Timestamp
bit 2 reserved unknown bit[2]
bit 1 36 InWater in or out of water
bit 1 37 SlideNotFitted is there a slide
bit 1 38 SlideExpired has the slide expired
bit 2 StateT unknown
bit 2 StatePh unknown
bit 2 StateNh3 unknown
bit 1 Error unknown
bit 1 IsKelvin valid Kelvin measure is taken
short 16 80 pH pH level (x100)
short 16 96 Nh3 Ammonia level (x1000)
int 32 112 T Temperature (x1000)
char 128 reserved unknown char[16]
char 64 reserved unknown char[8]
int 32 Kelvin light colour temperature in the Kelvin scale (x1000)
int 32 x unknown
int 32 y unknown
int 32 Par PAR light level
int 32 Lux Lux level
char 4 PUR PUR value in percentage
Lightmeter readings

Lightmeter readings are continuosly sent by the device periodically after the "HELLOSUD" message. They can arrive at any time and get mixed with other readings.

The values are a subset of a full reading and include just the lightmeter measurements:

C type length in bits Position Name Description
int 32 IsKelvin valid Kelvin measure is taken
int 32 Kelvin light colour temperature in the Kelvin scale (x1000)
int 32 x unknown
int 32 y unknown
int 32 Par PAR light level
int 32 Lux Lux level
char 4 PUR PUR value in percentage