Files
EMS-ESP32/docs/How-the-EMS-bus-works.md
2020-01-09 23:04:27 +01:00

5.3 KiB

Packages are streamed to the EMS "bus" from any other compatible connected device via serial TTL transmission using protocol 9600 baud, 8N1 (8 bytes, no parity, 1 stop bit). Each package is terminated with a break signal <BRK>, a 11-bit long low signal of zeros.

A package can be a single byte (see Polling below) or a string of 6 or more bytes making up an actual data telegram. A telegram for the EMS 1.0 is always in the format:

[src] [dest] [type] [offset] [data] [crc] <BRK>

The first 4 bytes is referenced as the header in this document.

EMS IDs

Each device has a unique ID.

In this example a UBA boiler has an ID of 0x08 (such as a MC10) and also referred to as the Bus Master.

The circuit acts as a service key and thus uses an ID 0x0B. This ID is reserved for special devices intended for service engineers.

EMS Polling

The bus master (boiler) sends out a poll request every second by sending out a sequential list of all possible IDs as a single byte followed by the break signal. The ID always has its high 8th bit (MSB) set so in the code we're looking for 1 byte messages matching the format [dest|0x80] <BRK>.

Any connected device can respond to a Polling request with an acknowledgement by sending back a single byte with its own ID. In our case we would listen for a [0x8B] <BRK> (meaning us) and then send back [0x0B] <BRK> to say we're alive and ready.

Polling is also the trigger to start transmitting any packages queued for sending. It must be done within 200ms or the bus master will time out.

EMS Broadcasting

When a device is broadcasting to everyone there is no specific destination needed. [dest] is always 0x00.

The tables below shows which types are broadcasted regularly by the boiler (in this case ID 0x08) and thermostat (ID 0x17). The data length is excluding the 4 byte header and CRC and the Name references those in the German ems wiki.

Source (ID) Type ID Name Description Data length Frequency
Boiler (0x08) 0x34 UBAMonitorWWMessage warm water temperature 19 bytes 10 seconds
Boiler (0x08) 0x18 UBAMonitorFast boiler temps, power, gas/pump switches 25 bytes 10 seconds
Boiler (0x08) 0x19 UBAMonitorSlow boiler temp and timings 22 bytes 60 seconds
Boiler (0x08) 0x1C UBAWartungsmelding maintenance messages 27 bytes 60 seconds
Boiler (0x08) 0x2A n/a status, specific to boiler type 21 bytes 10 seconds
Boiler (0x08) 0x07 n/a ? 21 bytes 30 seconds
Source (ID) Type ID Name Description Frequency
Thermostat (0x17) 0x06 RCTime returns time and date on the thermostat 60 seconds
Thermostat (0x17) 0x91 RC30StatusMessage returns current and set temperatures 60 seconds
Thermostat (0x17) 0xA3 RCTempMessage returns temp values from external (outdoor) sensors 60 seconds

Refer to the code in ems.cpp for further explanation on how to parse these message types and also reference the EMS Wiki.

EMS Reading and Writing

Telegrams can only be sent after the Master (boiler) sends a poll to the receiving device. The response can be a read command to request data or a write command to send data. At the end of the transmission a poll response is sent from the client (<ID> <BRK>) to say we're all done and free up the bus for other clients.

When executing a request to read data the [src] is our device (0x0B) and the [dest] must have has it's MSB (8th bit) set. Say we were requesting data from the thermostat we would use [dest] = 0x97 since RC20 has an ID of 0x17.

Following a write request, the [dest] doesn't have the 8th bit set and after this write request the destination device will send either a single byte 0x01 for success or 0x04 for failure.

Every telegram sent is echo'd back to Rx, along the same Bus used for all Rx/Tx transmissions.

Special EMS Types

ems.cpp defines callback functions that handle all the broadcast types listed above (e.g. 0x34, 0x18, 0x19 etc) plus these extra types:

Source (ID) Type ID Name Description
Boiler (0x08) 0x33 UBAParameterWW reads selected & desired warm water temp
Boiler (0x08) 0x14 UBATotalUptimeMessage
Boiler (0x08) 0x15 UBAMaintenanceSettingsMessage
Boiler (0x08) 0x16 UBAParametersMessage

In ems.cpp you can add scheduled calls to specific EMS types in the functions ems_getThermostatValues() and ems_getBoilerValues().