This page is supposed to describe "how stuff should work" in the New Hexabus Protocol.
If you want to make a new Hexabus device, for basic compatibility the functionality described herein should be implemented.
Note that this document is only an overview and not a complete guide to the Hexabus protocol. For an exact definition of what the different packet types on the Hexabus network do and how to react to them, please refer to New Hexabus Packet Format. The Hexabus Device software is work in progress, so this document may be out of sync with the code.
A Hexabus device offers several functions called endpoints. They consist of a pair (EID (Endpoint ID); Value). Everything the device is able to do (Hexabus-wise) is represented as an endpoint.
The endpoint with the EID 0 is a special endpoint containing the device descriptor. From the device descriptor, we can see which endpoints exist on a device. (For a description on how this works, please refer to New Hexabus Packet Format)
Other endpoints may offer access to the device's functionality, for example, the endpoint 1 on a Hexabus Socket is the state of the relay. It can be switched on or off using WRITE packets, or read with a QUERY packet. Endpoint 2 is the power meter reading which can be queried, but not written.
Each value can be directly set by sending a WRITE packet to the device. The device shall then react accordingly: Either by executing some command, or by sending an error packet if the value is nonexistent or can not be written.
If a QUERY or WRITE packet is received by
endpoint_access is used to read or write the endpoint. Depending on whether it's a QUERY or a WRITE packet,
endpoint_write is called with the appropriate endpoint ID and a pointer to a
hxb_value is a just wrapper for the different datatypes Hexabus packets can contain, so we do not have to care about the datatype too much on higher levels. It's defined in
hexabus_packet.h, and basically it has a field defining which of the internal values is the one that's relevant.
endpoint_read function is used to query the current value of the endpoint in question, and puts this value into the
hxb_value struct. On the hexabus Socket, for Endpoint 0, it puts the 32 bit long device descriptor into the struct. for Endpoint 1,
relay_get_state() is used to determine whether the power is switched on or off, which is then put into the struct as a
HXB_DTYPE_BOOL (this means the datatype is set to
HXB_DTYPE_BOOL, and the
int8 value is set to either
HXB_FALSE). For Endpoint 2 we use
metering_get_power() to read the current power consumption.
endpoint_read was used, the
udp_handler puts the data into a Hexabus Info packet (as defined in New Hexabus Packet Format and
hexabus_packet.h), which is then sent by the
send_packet() function back to the host that sent the QUERY.
If you want to make your Hexabus device cooler and have added some hardware to it, say a temperature sensor or more relays, you need to make them accessible to the Hexabus layer by defining endpoints for them. For now, please refert to the comment at the beginning of
endpoint_access.c on how to do this.
For now, each device should broadcast those of its values that may be of interest for other devices. The Hexabus Socket broadcasts its power measurement every 60+(rand()%60) seconds (30+(rand()%30) for the Plugs given out at Electrocamp 2012.05). This is done by the
value_broadcast process. The main part of the process just handles the timers. A function named
send_packet is called by the timer. This function uses
metering_get_power() to get the current power consumption of the socket, and sends out a HXB_INFO packet to the link-local multicast address.
udp_handler receives a HXB_INFO packet, it posts a
hxb_broadcast_received_event. The event comes with a pointer to a
hxb_data_... structure. This structure is defined in
hexabus_packet.h and contains the IP adress of the broadcast sender, the datatype, Endpoint ID and value of the data received.
This event is caught by
hxb_broadcast_handler. The software which handles the reaction to events, rule-based switching etc. is yet to be implemented.