Skip to content

3.1. TCP client commands

John edited this page Mar 9, 2024 · 23 revisions

Introduction

This section lists the available commands that ebusd understands on the TCP port it listens to (usually 8888).

In general, a request to ebusd is terminated by a newline and ebusd will answer with one or more lines in return. Since the result may cover more than one line, a response ends with a single empty line.

If the wrong number of arguments was specified, the response starts with "usage:" and explains the command.
If the request was invalid or an error occurred during execution, the response starts with "ERR: " followed by the error message.

On success, the response is "done" unless otherwise noted below.

Access to a message might be limited to an authenticated user with the corresponding access level. The required access level is part of the message definition. If the message access level is empty, access is also granted to non-authorized users. Use the auth command to authorize and gain the necessary access level(s) (see "--aclfile" and "--accesslevel" option).

Read

Read value(s) from a configured message (or an inline defined message, see below). The result can either be returned from the cache (without accessing the eBUS at all) or retrieved directly from the slave by querying it via the eBUS.

Use the following format to read value(s) from a named message:

read [-f] [-m SECONDS] [-s QQ] [-d ZZ] [-c CIRCUIT] [-p PRIO] [-v|-V] [-n|-N] [-i VALUE[;VALUE]*] NAME [FIELD[.N]]
  -f           force reading from the bus (same as '-m 0')
  -m SECONDS   only return cached value if age is less than SECONDS [300]
  -c CIRCUIT   limit to messages of CIRCUIT
  -s QQ        override source address QQ
  -d ZZ        override destination address ZZ
  -p PRIO      set the message poll priority (1-9)
  -v           increase verbosity (include names/units/comments)
  -V           be very verbose (include names, units, and comments)
  -n           use numeric value of value=name pairs
  -N           use numeric and named value of value=name pairs
  -i VALUE     read additional message parameters from VALUE
  NAME         NAME of the message to send
  FIELD        only retrieve the field named FIELD
  N            only retrieve the N'th field named FIELD (0-based)

If the configured message contains more than one field and no particular field was requested, all field values are returned and concatenated with a semicolon character in between, so a successful response in principle looks like this:

FIELD[;FIELD]*

In order to retrieve a single field only, use FIELD (and optionally N) to specify which field you want, for example:
read -c mc Timer.Monday from.0
would only return the first "from" field for the mixing circuit's timer program for Mondays.

In verbose mode, the field names (followed by "="), units (following the value), and comments (in square brackets, if defined) can be included (by adding as many "-v" arguments as desired), e.g. "temp=10.5 °C [temperature]".

For reading a message by a new or changed inline message definition, use this format:

read [-f] [-m SECONDS] [-s QQ] [-d ZZ] [-v|-V] [-n|-N] [-i VALUE[;VALUE]*] -def DEFINITION
  -f           force reading from the bus (same as '-m 0')
  -m SECONDS   only return cached value if age is less than SECONDS [300]
  -s QQ        override source address QQ
  -d ZZ        override destination address ZZ
  -v           increase verbosity (include names/units/comments)
  -V           be very verbose (include names, units, and comments)
  -n           use numeric value of value=name pairs
  -N           use numeric and named value of value=name pairs
  -i VALUE     read additional message parameters from VALUE
  -def         read with explicit message definition:
    DEFINITION message definition to use instead of known definition

The message definition used for the read is specified inline and this is only possible when enabled in the daemon (see "--enabledefine"). The defintion itself has to be complete and independant of any templates, defaults and such, so basically it has to be similar to what "find -f" would return.

For reading a message picked by it's master hex data instead of the message name, use this format:

read [-f] [-m SECONDS] [-s QQ] [-c CIRCUIT] -h ZZPBSBNN[DD]*
  -f           force reading from the bus (same as '-m 0')
  -m SECONDS   only return cached value if age is less than SECONDS [300]
  -c CIRCUIT   limit to messages of CIRCUIT
  -s QQ        override source address QQ
  -h           send hex read message (or answer from cache):
    ZZ         destination address
    PB SB      primary/secondary command byte
    NN         number of following data bytes
    DD         data byte(s) to send

The hex bytes can also be separated by space.
If successful, the response contains the answer retrieved from the device (or from the cache) in hex digits.

Write

Write value(s) in a configured message (or an inline defined message, see below) or send a message without any fields.

Use the following format to write value(s) in a named message:

write [-s QQ] [-d ZZ] -c CIRCUIT NAME [VALUE[;VALUE]*]
  -s QQ        override source address QQ
  -d ZZ        override destination address ZZ
  -c CIRCUIT   CIRCUIT of the message to send
  NAME         NAME of the message to send
  VALUE        a single field VALUE

If successful, the response contains the answer retrieved from the device or just "done" (if the message does not include an answer, e.g. for a master destination). For a successfully sent broadcast message, the result is "done broadcast".

For writing a message by a new or changed inline message definition, use this format:

write [-s QQ] [-d ZZ] -def DEFINITION [VALUE[;VALUE]*]
  -s QQ        override source address QQ
  -d ZZ        override destination address ZZ
  NAME         NAME of the message to send
  VALUE        a single field VALUE
  -def         write with explicit message definition:
    DEFINITION message definition to use instead of known definition

The message definition used for the write is specified inline and this is only possible when enabled in the daemon (see "--enabledefine"). The defintion itself has to be complete and independant of any templates, defaults and such, so basically it has to be similar to what "find -f" would return.

For writing a message picked by it's master hex data instead of the message name, use this format:

write [-s QQ] [-c CIRCUIT] -h ZZPBSBNN[DD]*
  -s QQ        override source address QQ
  -c CIRCUIT   CIRCUIT of the message to send
  -h           send hex write message:
    ZZ         destination address
    PB SB      primary/secondary command byte
    NN         number of following data bytes
    DD         data byte(s) to send

The hex bytes can also be separated by space.
If successful, the response contains the answer retrieved from the device in hex digits.

Auth

Authenticate to the daemon with user name and secret:

auth USER SECRET
  USER    the user name
  SECRET  the secret string of the user

If successful, the response is "done". Otherwise, the result is "ERR: invalid user name or secret".
After successful authentication, the info command reveals the user's access levels.

Hex

Send arbitrary data in hex (only if enabled, see "--enablehex"):

hex [-s QQ] ZZPBSBNN[DD]*
  -s QQ  override source address QQ
  ZZ     destination address (e.g. "FE" for broadcast)
  PB SB  primary/secondary command byte
  NN     number of following data bytes
  DD     data byte(s) to send

or:

hex [-s QQ] -n ZZPBSB[DD]*
  -s QQ  override source address QQ
  -n     automatically determine the number of data bytes
  ZZ     destination address (e.g. "FE" for broadcast)
  PB SB  primary/secondary command byte
  DD     data byte(s) to send

The hex bytes can also be separated by space.
If successful, the response contains the answer retrieved from the device in hex digits or just "done" (if the message does not include an answer, e.g. for a master destination). For a successfully sent broadcast message, the result is "done broadcast".

Inject

Inject a message in hex (only if enabled, see "--enablehex"):

inject QQZZPBSBNN[DD]*/[NN[DD]*]
  QQ     source address
  ZZ     destination address
  PB SB  primary/secondary command byte
  NN     number of following data bytes
  DD     data byte(s)

This injects a message just as if it was received from the bus directly (e.g. "FF08070400/0AB5454850303003277201")-

Answer

Add an answer to a message from the bus (only if enabled, see "--enablehex" and see "--answer"):

answer [-m] [-s QQ] [-d ZZ] PBSB[ID]* [DD]*
  -m     destination is a master
  -s QQ  source address to limit to
  -d ZZ  override destination address (instead of own address)
  PB SB  primary/secondary command byte
  ID     further ID bytes
  DD     data bytes (only length used with -m)

This makes ebusd automatically answer to a message received from the bus that matches the given criteria. This way, an arbitrary device can be simulated.

For master-master messages, the DD bytes are used for indicating the expected length only (during reception) and the received data to the master destination addess is automatically added as answer to the same message with the corresponding slave destination address.

E.g. when specifying an answer like this: answer -d 03 6789ab 0304, then ebusd will answer to all matching messages (any source here), e.g. qq03676803abxxyy, and store the transferred value (here xxyy) in another automatically answered message, i.e. it behaves as if another answer would have been added like this: answer -d 08 6789ab xxyy (watch the destination address switch to the matching slave address).

Find

Find configured messages by name. This will also print the cached value if requested.

find [-v|-V] [-r] [-w] [-p] [-a] [-d] [-h] [-i ID] [-f] [-F COL[,COL]*] [-e] [-c CIRCUIT] [-l LEVEL] [NAME]
  -v             increase verbosity (include names/units/comments+destination address+update time)
  -V             be very verbose (include everything)
  -r             limit to active read messages (default: read + passive)
  -w             limit to active write messages (default: read + passive)
  -p             limit to passive messages (default: read + passive)
  -a             include all message types (read, passive, and write) and all conditional
  -d             only include messages with actual data
  -h             show hex data instead of decoded values
  -i ID          limit to messages with ID (in hex, PB, SB and further ID bytes)
  -f             list messages in CSV configuration file format (including conditions with '-a')
  -F COL[,COL]*  list messages in the specified format (including conditions with '-a')
                 (COL: type|circuit|level|name|comment|qq|zz|pbsb|id|fields or custom fields)
  -e             match NAME and optional CIRCUIT exactly (ignoring case)
  -c CIRCUIT     limit to messages of CIRCUIT (or a part thereof without '-e')
  -l LEVEL       limit to messages with access LEVEL ("*" for any, default: current level)
  NAME           NAME of the messages to find (or a part thereof without '-e')

If successful, the response lists all matching messages in the following format (one line per message):

CIRCUIT NAME = FIELD[;FIELD]*

In verbose mode, the field names, units, and comments can be included (by adding as many "-v" arguments as desired) and in most verbose mode, each line is suffixed with the hex destination address, the last update time (if available), and the message type in square brackets, e.g. "[ZZ=15, lastup=2015-02-14 08:10:45, active read]". Alternatively, in hex mode the master and slave data bytes are shown in hex (separated by slash) instead of the fields.

When using one of the "-f" or "-F" options, the response will list the matching messages in CSV format, either in the complete configuration file format with all the columns when using "-f", or just the columns requested with "-F COL[,COL]", where all templates have been resolved to the final value. For example:
find -f -c broadcast outsidetemp
would result in this response:
u,broadcast,outsidetemp,Außentemperatur,,fe,b516,01,temp2,m,D2B,,°C,Temperatur

This format may be useful when configuring other daemons that need a list of available messages and the fields.

If only the message names and comments are desired, one could use:
find -F name,comment -c broadcast outsidetemp
This would result in this response:
outsidetemp,Außentemperatur

Listen

Start or stop printing changed values, optionally including/limited to unkown messages.

listen [-v|-V] [-n|-N] [-u|-U] [stop]
  -v  increase verbosity (include names/units/comments)
  -V  be very verbose (include names, units, and comments)
  -n  use numeric value of value=name pairs
  -N  use numeric and named value of value=name pairs
  -u  include unknown messages
  -U  only show unknown messages

To start listening:

listen

To stop listening:

listen stop

If successful, the response is either "listen started", "listen continued", or "listen stopped".

While the client is listening for changes, ebusd will automatically feed it with each message that changed a previously cached value like this (or with further verbosity similar to the read command):

CIRCUIT NAME = FIELD[;FIELD]*

If unknown messages are included, each unknown message is also added in hex, e.g. like this:

1052b5040131 020000

Direct

Start the direct mode, in which all valid messages received are directly forwarded to the client without the CRC byte.

To enter the direct mode:

direct

To exit from the direct mode:

stop

On success, the response is "direct mode started" when entering and "direct mode stopped" when exiting the direct mode.

While the client is in direct mode, received messages are forwarded to it in hex like this:

QQZZPBSBNN[DD]*[ OO[EE]*]

With the following meaning:

  • QQ: source master address
  • ZZ: destination slave, master, or broadcast address
  • PBSB: primary/secondary command
  • NN: number of following master data bytes
  • DD: master data bytes
  • OO: number of following slave data bytes (only for master-slave messages)
  • EE: slave data bytes (only for master-slave messages)

In addition to listening to the bus traffic, in direct mode the client can also send hex messages (only if enabled, see "--enablehex") like this:

[-s QQ] ZZPBSBNN[DD]*

as well as with "-n" for automatically determining the length bytes:

-n [-s QQ] ZZPBSB[DD]*

The meaning of the parts is the same as above. Note the special handling of the source master address QQ, as the address is set to the ebusd master address by default.

ebusd repeats the request followed by a colon and the result. On error, the result starts with "ERR:" and the error message. For broadcast messages, the result is "done broadcast", whereas for master-master messages, the result is simply "done". For master-slave messages, the slave answer is returned, so the list of possible responses including the request is this (with the meaning of the parts as above):

ZZPBSBNN[DD]*:ERR: <error message>
ZZPBSBNN[DD]*:done
ZZPBSBNN[DD]*:done broadcast
ZZPBSBNN[DD]*:OO[EE]*

Note that on success the complete message will additionally appear as a regular message without colon as stated above.

State

Report the bus state (signal acquisition).

state

The response is either "no signal", or starts with "signal acquired" followed by the current number of received symbols per second, the maximum number of symbols per second, and the number of masters, e.g.:

signal acquired, 45 symbols/sec (197 max), 5 masters

The maximum possible symbol rate is around 220 symbols/sec.

Info

Report information about the daemon, configuration, seen participants, and the device:

info [verbose]

The response lists the ebusd version, some device infos, the signal state including measured arbitration delay and send-receive latency, the number of masters, the message count, as well as a list of seen addresses together with their scan state and the configuration file, e.g.:

version: ebusd 23.3.23.3
update check: OK
device: 192.168.178.100:9999, TCP, enhanced
access: *
signal: acquired
symbol rate: 21
max symbol rate: 184
min arbitration micros: 2
max arbitration micros: 177
min symbol latency: 6
max symbol latency: 15
scan: finished
reconnects: 0
masters: 3
messages: 871
conditional: 213
poll: 3
update: 60
address 03: master #11
address 08: slave #11, scanned "MF=Vaillant;ID=EHP00;SW=0327;HW=7201", loaded "vaillant/08.ehp.csv"
address 10: master #2
address 15: slave #2, scanned "MF=Vaillant;ID=UIH00;SW=0374;HW=6901", loaded "vaillant/15.uih.csv"
address 23: slave, scanned "MF=Vaillant;ID=EHP00;SW=0327;HW=7201", loaded "vaillant/23.ehp.cc.csv"
address 25: slave, scanned "MF=Vaillant;ID=EHP00;SW=0327;HW=7201", loaded "vaillant/25.ehp.hwc.csv"
address 31: master #8, ebusd
address 36: slave #8, ebusd
address 50: slave, scanned "MF=Vaillant;ID=EHP00;SW=0327;HW=7201", loaded "vaillant/50.ehp.mc.csv"

The "scanned" and "loaded" parts of each seen slave address are available with enabled "--scanconfig". After a successful "scan" command, the "scanned" part is available as well (regardless of the configuration options).

The master number between 1 and 25 is shown behind master addresses as well as slave addresses with an associated master.

If authenticated, the result also includes the username after "user:" and access level after "access:". The access level is also included when the default access level was changed by the "--accesslevel" option.

Grab

Grab messages, stop grabbing, or report/decode unknown or all grabbed messages.

grab [stop]
  or:  grab result [all|decode]*
 Start or stop grabbing, or report/decode unknown or all grabbed messages.

When grabbing messages, ebusd will keep the last one of each message depending on the message key. This key is built from the QQZZPBSBNN header plus up to 4 master data bytes that are normally used for building the message ID. ebusd automatically grabs all messages when starting up since version 2.1.0.

To start grabbing messages:

grab

To stop grabbing:

grab stop

To report the grabbed unknown messages:

grab result

To report all grabbed messages:

grab result all

The response will then list the last seen message for each unique message key, the number of times the message was grabbed, as well as the configured message circuit and name (if all messages were requested), e.g.:

1025b5040101 / 09350300000003000100 = 10: hwc Mode
1025b504010d / 050000550135 = 9: hwc Status
1025b505072b000100000000 / 00 = 2
1025b50903290000 / 050000940300 = 1
1025b509040ef40000 / 00 = 2
1050b5040100 / 0a03565511240407167006 = 5: mc DateTime
1050b5040101 / 09140100000081000100 = 5: mc Mode
1050b504010d / 051800840114 = 5: mc Status
1050b505072b000100000000 / 00 = 1

This can then be used to analyze the message format and create new message definitions.
For master-slave messages only, the slave part is added behind the "/". If the result for all messages was requested, the circuit name and message name are added behind the ":" after the message count for known messages.

To get hints for decoding unknown messages:

grab result decode

The response will be extended by a list of base data types and the decoded values for each valid position in the master or slave data, e.g.:

10c0b509050e150000c8 / 00 = 503
 BCD   15=15, 00=0, 00=0
 BDY   00=Mon, 00=Mon
 BTI   150000="00:00:15"
 BTM   1500="00:15", 0000="00:00"
 D1B   0e=14, 15=21, 00=0, 00=0, c8=-56
 D1C   0e=7.0, 15=10.5, 00=0.0, 00=0.0, c8=100.0
 D2B   0e15=21.055, 1500=0.082, 0000=0.000, 00c8=-56.000
 D2C   0e15=336.88, 1500=1.31, 0000=0.00, 00c8=-896.00
 DAY   0e15="05.10.1914", 1500="24.01.1900", 0000="03.01.1900", 00c8="07.03.2040"
 EXP   0e150000=7.553e-42, 150000c8=-131072
 EXR   0e150000=1.83657e-30, 150000c8=2.585e-26
 FLR   0e15=3.605, 1500=5.376, 0000=0.000, 00c8=0.200
 FLT   0e15=5.390, 1500=0.021, 0000=0.000, 00c8=-14.336
 HCD:4 0e150000=2114
 HDY   00=Tue, 00=Tue
 HEX:5 0e150000c8="0e 15 00 00 c8"
...

Define

Add or replace a message definition, which will vanish once the daemon is restarted:

define [-r] DEFINITION
  -r          replace an already existing definition
  DEFINITION  message definition to add

This command is only available when enabled in the daemon (see "--enabledefine").

Decode

Decode field(s) by definition and hex data. This helps to find out what value corresponds to a particular byte sequence of a certain data type:

decode [-v|-V] [-n|-N] DEFINITION DD[DD]*
  -v          increase verbosity (include names/units/comments)
  -V          be very verbose (include names, units, and comments)
  -n          use numeric value of value=name pairs
  -N          use numeric and named value of value=name pairs
  DEFINITION  field definition (type,divisor/values,unit,comment,...)
  DD          data byte(s) to decode

Encode

Encode field(s) by definition and decoded value(s). This helps to find out what byte sequence corresponds to a particular value of a certain data type:

encode DEFINITION VALUE[;VALUE]*
  DEFINITION  field definition (type,divisor/values,unit,comment,...)
  VALUE       single field VALUE to encode

Scan

Scan for seen slaves, all possible slaves (full), a single slave (address ZZ), or report scan result.

To initiate a scan over seen slave adresses:

scan

To initiate a full scan over all possible slave adresses:

scan full

The scanning takes a little time depending on the number of queried slaves and the scan configuration (see Scanning).

To show the result of the last scan request:

scan result

If successful, the response lists all devices that answered to the "identification" message, each in one separate line, e.g.:

08;Vaillant;EHP00;0327;7201;21;07;45;0010002779;0006;......;N8
15;Vaillant;UIH00;0374;6901;21;17;24;0020093224;0907;......;N0
23;Vaillant;EHP00;0327;7201;21;07;45;0010002779;0006;......;N8
25;Vaillant;EHP00;0327;7201;21;07;45;0010002779;0006;......;N8
50;Vaillant;EHP00;0327;7201;21;07;45;0010002779;0006;......;N8

The columns of each response line are:

  • slave address
  • manufacturer name (or code)
  • identification string
  • software version
  • hardware version
  • further columns depending on the scan configuration (see Scanning)

Alternatively, a synchronous scan for a single slave adresses can be initiated like this:

scan ZZ

This will then respond with a single line containing the (simple) scan result for that slave or the error message.

If another scan is still running, initiating a new scan will result in "ERR: scan already running".

Logging

Adjust the log level for certain area(s) or get the current settings.

Set the log level for the specified area(s):

log AREA[,AREA]* LEVEL

The possible AREA values are:

  • main: primary system messages
  • network: networking subsystem messages
  • bus: bus related messages
  • update: updates of message values found by listening to the eBUS
  • other: other subsystems (e.g. further data sources/sinks like MQTT)
  • all: wildcard for all areas

The possible LEVEL values are (similar to syslog):

  • error: only error messages
  • notice: error and noticeable messages
  • info: error, noticeable and informational messages
  • debug: all messages including debug (not recommended)

Get the current log settings:

log

This will return a list of log levels per area, e.g.:

main: notice
network: none
bus: notice
update: none
other: debug

Raw logging

Toggle logging of messages:

raw

This will produce an entry in the log file (or alternatively in the file set in the parameters, see --lograwdatafile) for each completed message transfer on the bus (i.e. everything between two SYN bytes). The entry also reveals the direction of each sequence of bytes, i.e. "<" when the following bytes were received and ">" when sent by ebusd. If ebusd successfully sent a byte to the eBUS, the identical echoed byte is skipped unless it differs from the sent byte.

Examples:

  • When ebusd just listened to a message on the eBUS:
    2017-04-23 12:28:26.144 [bus notice] <1025b50903290000e4000500009203008900
    The whole sequence was received from the eBUS, i.e. another master sent something and the slave answered it.
  • When ebusd actively sent a message on the eBUS:
    2017-04-23 12:30:59.957 [bus notice] >3115b509030d8700ff<00041545000002>00
    The part 3115b509030d8700ff was sent by ebusd, where 00041545000002 was received from the slave and ebusd acknowledged that with the final 00.

In contrast to logging bytes (see below) this command avoids logging the SYN symbols themselves.

Toggle logging of each received and sent byte:

raw bytes

This will produce a lot of entries in the log file (or alternatively in the file set in the parameters, see --lograwdatafile). Each received byte is placed in a log entry after a "<" and each sent byte after a ">".

Binary dump

Toggle binary dump of received bytes to dump file (see --dumpfile):

dump

Other

Reload the message configration files:

reload

Close the client connection:

quit

Print help:

help [COMMAND]

For help on a particular command, add the name of the COMMAND or run the COMMAND with the argument "?".

Shortcuts

The main commands are also available using a single letter:

r for read
w for write
a for auth
f for find
l for listen
s for state
i for info
g for grab
d for decode
e for encode
q for quit
? or h for help