Documentation

User-defined counters

Note: The cFos Charging Manager can read out most solar inverters using SunSpec (device type "SunSpec Solar Inverter / Meter"). In this case, you do not need to create your own meter definition.

The cFos Charging Manager allows you to create your own meter definitions to support meters that are not available in the standard repertoire. There are currently three types: Modbus counters, HTTP/JSON counters and MQTT/JSON counters. The definition files for these counters are very similar. Modbus counters read their data from certain registers via Modbus, while HTTP/JSON counters retrieve their data via HTTP request and read in JSON in response. For MQTT/JSON meters, the cFos Charging Manager subscribes to MQTT topics and reads messages published under the topic as JSON. The cFos Charging Manager uses a small "Query Language" for reading. Here is the documentation of the MQTT capabilities in the cFos Charging Manager.

In addition to a range of predefined variables, such as current and voltage, user-defined counters can also read in unknown, user-defined variables, query inputs and set outputs. Reading in variables and setting outputs allows formulae to be analysed. In combination with the Charging Manager variables and global Charging Manager outputs described below, this is a powerful feature and even allows certain home automation tasks and the control of external devices such as battery storage units. If you realise control tasks with this, please give us feedback. We are very interested in what our customers control with the cFos Charging Manager and it helps us to further develop the Charging Manager according to customer needs.

Here is a simple example definition for Modbus that reads a single register for active power. You can easily modify the register number for your specific application:
Example definition for a single register.

Here is an example definition for Modbus and one for HTTP/JSON:
Download sample definition for Modbus meter
Download sample definition for HTTP/JSON meter

The Charging Manager already comes with a few such files, but you can upload your own files under "System configuration" and also delete them again.
Here you will find most of the meter definitions we provide:
Download supplied counter definitions

If you have created your own counter file and it could be relevant for other users, we would be very grateful if you could make it available to us. Then we will deliver it with future versions of the Charging Manager.

Download meter definitions for additional meters

Structure of a definition file:

Counter definitions are JSON files with a global JSON object that has properties and sub-objects. 'rtype' determines the type of read operation: 0 = Modbus, 1 = HTTP/JSON, 2 = MQTT/JSON. 'mtype' determines the device type: 0 = Other device, 1 = Meter, 2 = Inverter, 4 = Battery storage.

You can specify numbers either in decimal or hex with the prefix '0x'. Single-line comments using '//' are also permitted. We recommend running your definition files through a JSON5 validator, e.g. this JSON5 validator

You should definitely have read the Formulas chapter to understand which values can be used in formulas in the following reference.

Modbus definitions have an object 'rtu' with the following properties:

silence_period, in msec: Determines the pause length before a Modbus RTU access so that the device recognises the start of a message.
silence_same_slave, true: The pause is also maintained for multiple accesses to the same device.
retries: The number of retries if the device does not respond.
rcv_timeout: in msec: The maximum waiting time until the device responds, per access.

These global properties apply to Modbus TCP and RTU:

modbus_read: The function number of the Modbus command for reading, usually 3 or 4.
modbus_read_max_registers: The maximum number of registers that can be read at a time.
modbus_allow_gaps: true = unused register areas may be read in a read operation.

For Modbus TCP and HTTP/JSON there is an object 'tcp' with the following properties:

connect_timeout: is msec: The maximum waiting time for a TCP connection.
delay_after_connect: in msec: Pause after the connection is established before the first command is sent.

Both definition types (Modbus and HTTP/JSON) have the following additional properties:

upd_delay: in msec: Determines the interval at which a device can be read. Some devices are overloaded if they are queried too often.
manufacturer: String, name of the manufacturer. This is displayed in the extended information of the tile.
delay_accumulated: true = Accumulated values (kWh) are only queried every 3 seconds or if there is sufficient power. false = These values are always queried.
ui_addr: URL, if different from the device address for calling the web interface.
reserved: Array with values that are interpreted as 0 (useful if the device supports certain values depending on the model).

If you omit the properties listed above, the cFos Charging Manager uses default values, which work well in most cases.

The next step in the JSON definition is the definition of variables that the meter uses to read or calculate values for current, voltage, etc. The Charging Manager recognises the following variables:
type_designation, version, firmware_version, serial: These form the model designation, as shown in the extended information of the tile. These are queried once when setting up or resetting the meter.
voltage_l1..voltage_l3, current_l1..current_l3, power_w, power_var, power_va, power_w_l1..power_w_l3: The cFos Charging Manager attempts to calculate from these values for voltage_l1..l3, signed current_l1..l3, power_w and power_va. You do not have to specify all variables. The cFos Charging Manager attempts to calculate the values from the existing variables.
import_wh, export_wh: The Charging Manager uses these variables to display import_wh and export_wh. For unidirectional meters (e.g. inverters), you should only ever define import_wh. Only for bidirectional meters (such as storage or grid reference meters) should export_wh be defined.

soc: If available, the state of charge of a battery storage is displayed here in % in the tile.
You can also define other variables with different names, which are read out with each update or calculated using formulas. If you define variables that begin with 'CM.', e.g. CM._set_price, the assigned values are stored in the global Charging Manager variables (see below) and can be queried accordingly.
Variables with *: If you define variables that begin with '*', these are displayed in the UI in the meter tile under extended information, e.g. the temperature of a battery storage unit.
Note: Only numbers and the letters a-z and A-Z may be used as variable names.

Definition of a variable:

The object is named after the name of the variable listed above and has the following properties:
fixed: String with a fixed value. Useful if, for example, no value can be determined, e.g. for type_designation or voltage.
expr: String. The variable is not read out, but evaluated as a formula.
type: If not fixed or expr, the type of the variable: int16, uint16, int32, uint32, float, int64, string. This is important for Modbus in order to read the registers in the correct format. uint16 and uint32 are types that can only accept positive numbers. With JSON/HTTP, you can usually use float.
resolution: float. The read value is multiplied by 'resolution'. Values for voltage must be in volts, currents in milliamperes, power in watts, energy in watt-hours (Wh). With negative 'resolution' you can invert a value if it has the opposite sign.
once: bool (true or false). If true, the value is only read once when the device is initialised, otherwise it is read periodically.
address: number (Modbus) or string (HTTP/JSON). The Modbus register number or the HTTP URL of the value to be read.
query: String. For HTTP JSON, the specification in the query language of the Charging Manager with which it finds the value to be read in the JSON response.
order: String. For Modbus, the byte order, either "hl" or "lh", in which the value is present. length: number. For Modbus, the length of a string in registers; for the variables 'version' and 'firmware_version', 'length' is used to turn numerical versions into strings with dots. Values of 2 or 4 are permitted for 'length', which then result in the version formats a.b, and a.b.c.d. With 'length' 2 and type 'int16' or 'uint16', the Charging Manager separates low and high byte with a dot, with 'int32' or 'uint32' low and high word, with 'int64' low and high dword. For 'lenth' 4 and 'int32' or 'uint32', the Charging Manager splits the value into 4 bytes separated by a dot. For 'int64' the 4 words accordingly.
regex: String. If a regular expression is specified, the counter response does not need to be in JSON. Either the entire match of the regular expression or the first group is evaluated as the result. Please only use if the device does not return JSON. Here is the list of features of our regular expressions:
any char: .
named classes: \d \s \w \D \S \W
anonymous classes: [a-z0-9_], [^0-9], [^\d]
groups with alternatives: (ab|cd|ef)
non-captured groups: (?:ab|cd)
(greedy) once or none: a?, a???
(greedy) many or none: a*, a*?
(greedy) once or more: a+, a+?
begin of string: ^
end of string: $

Definition of inputs:

The Charging Manager can request up to 32 input values per device from various registers or JSON elements. The "Inputs" property is a JSON array. You must define the following properties for each input:
address: Address (Modbus register or URL).
count: Number of input bits that are read with this request.
query: For HTTP/JSON, query language to find the value in the response.

The cFos Charging Manager reads all inputs defined in this way with each update and stores the bits internally in an array, which can then be queried in formulae, Input1..InputN.

Definition of outputs:

The Charging Manager can switch up to 32 outputs per device. Outputs are defined in "outputs" as a JSON array of output objects. All outputs are switched at the end of each update cycle if the status of the respective output has changed.
You must define the following properties in the output object for each output:
address: HTTP URL with optional HTTP method, e.g. GET http://www.example.com?output1=${var1}. To set Modbus registers, you can use the HTTP API of the cFos Charging Manager. The Charging Manager recognises suitable accesses on localhost and redirects the request to the internal handler so that you do not need authorisation as with external HTTP API accesses. If the URL is empty after all replacements, no output is set. For example, you can only switch outputs if certain variables exist (see formulas: exists() function). You can also specify ${address} and ${id} in the address. This is the current device address and Modbus ID as defined in the settings. 'address' and 'id' are mainly used for using the Modbus API (see below).
body: Optional HTTP body for POST or PUT.
In the URL and the body, you can use ${expr} to use formulas that reference global charging manager variables or from the respective counter. The formula 'expr' is evaluated when the output is set and replaced in the text of the URL or the body. If, in the example above, http://www.example.com?output1=1 sets the output and http://www.example.com?output1=0 deletes it, you can define a variable 'var1' and set it to 1 or 0 as required. In this way, you can also write numerical values to control memory performance in Modbus registers, which you have previously stored in a variable using a formula.
If, instead of passing a numerical value, you need to replace one text in the URL with another depending on the formula, e.g. for Shelly WLAN sockets, you can write this as follows: ${if expr`text1`text2}. The "apostrophe" is a backtick (ASCII code 96). If the 'expr' != 0, text1 is used, otherwise text2. For the Shelly WLAN socket, the URL then looks like this, for example: http://<ip-addr>/relay/0?turn=${if expr`on`off}, i.e. if expr != 0, the Charging Manager then calls http://<ip-addr>/relay/0?turn=on, otherwise http://<ip-addr>/relay/0?turn=off.

If you enter a relative path as the URL, the Charging Manager will use the address configured for the respective device. If you enter 'localhost' as the domain, the Charging Manager takes the address of the device on which it is running. If it recognises access to its own API, it uses the internal handler instead of executing a full HTTP access so that you do not have to enter a user name and password in the counter definition. A URL that begins with an '*' causes the Charging Manager to always execute a full HTTP access.

Reset outputs: In addition to an "outputs" array, you can also define an array named "resets" that is structured like the "outputs" array. This allows outputs to be reset to their initial values when the device is deactivated. This can be used in combination with user-defined variables and "once": true to reset the device to its initial state.
Write outputs periodically: For some devices, the outputs must be written periodically, otherwise the device will reset the values to "default". For example, the Kostal memory reverts to its default rules if the memory control has not been actively written for a while. To set outputs periodically, you can prefix the address with #xxx#, where xxx indicates how many seconds the output is rewritten, even if the value to be written has remained the same. For example, if the address is /cnf?cmd=set_cm_vars&name=test&val=42, you can use #30#/cnf?cmd=set_cm_vars&name=test&val=42 to ensure that this value is written every 30 seconds.

Definition of the Query Language:

Currently, member names and the operators "." and "[]" can be used in the "query" search expressions, examples:

testElement named "test"
name1.name2Element named "name2" in child object "name1"
name[idx]Element "idx" of the object element "name". "idx" can be a number, e.g. for arrays or a string
name["u2"]Element "u2" of the object element "name", corresponds to "name.u2"
name[{"el1": "v1", "el2": 3}].valueSelect the array element that fulfils the condition of the object notation and evaluate the element named 'value'. Here, for example, in the array 'name', the element is selected that has as object elements 'el1' with value 'v1' and 'el2' with value 3 and then the value of the element 'value' is returned from this object.

Global Charging Manager variables:

You can create variables in the Charging Manager configuration. You can use a fixed value or a formula as the value. At the end of each update cycle, the Charging Manager recalculates the value of these variables if necessary. You can then use these in (certain) Charging Manager parameters, charging rules or to control outputs. You can also write Ex.member or Mx.member as a variable. In this case, Exand Mxare the device ID of a wallbox or meter set up in the Charging Manager. 'member' is a "user-defined" variable that is saved in the corresponding device. Some of the variables can have a special meaning: For KEBA, 'out1' is a switching output, for ABB B23 meters, 'out1' and 'out2' are switching outputs (for models that support this). A 1 switches the output, a 0 switches it off again.

If you have appliances that have to be switched on under certain conditions but then run for a while (e.g. washing machine, dishwasher), you can also define the variable as a "trigger". Then the formula of the variable is the condition with which the variable is set to 1. After an adjustable time, it is then set to 0 again. A "retrigger condition" allows the time until switching off (i.e. setting the variable to 0) to be extended again and again as long as the condition is fulfilled.

Note: Only numbers and the letters a-z and A-Z may be used as variable names.

For test purposes, you can display charging manager and meter variables, e.g. the current Awattar prices:


                        Screenshot display of counter variables

Global Charging Manager Outputs:

In the Charging Manager configuration, you can configure global outputs as described above in the counter definition under 'Outputs'. These are set at the end of each update cycle if their status has changed. If you want to control switching outputs in user-defined devices, the above convention is recommended (see Charging Manager variables): You set variables with the names "out1", "out2", etc. in the user-defined counter and set up outputs in the user-defined counter that switch the output depending on the value of these variables.

Global Modbus API of the Charging Manager:

The Modbus API of the Charging Manager is used to control Modbus devices that have any Modbus RTU or TCP address (accessible from the Charging Manager). As in the configuration of the individual devices, enter COMx,bd,8,p,s as the address for Modbus RTU, where x is the COM port number, bd the baud rate, p the parity ('N', 'E' or 'O') and s the number of stop bits (1 or 2). For Modbus TCP, the addresse is the IP address of the device in the Charging Manager network, including the port number.
The URL (for HTTP GET) of the Modbus API is:
/cnf?cmd=modbus_get or /cnf?cmd=modbus_set
The cFos Charging Manager supports the following additional query parameters:
addr: The Modbus RTU or TCP device address mentioned above.
func: Modbus function number, e.g. for reading 3 or 4, for writing 6 or 16.
id: Device ID of the Modbus device.
reg: The Modbus register number. The value can be specified in decimal or hex (with prefix 0x).
val: number: Value to be written to the register. Omit when reading.
type: 'w' 16bit (default), d = 32bit, f = float, q = 64bit, s = string.
cnt: number: The maximum length of the string in registers, omit for other types or set to 1.
order: String: The byte order, either "hl" or "lh".

Note: If your 'counter' primarily has control tasks, you can tick the option 'Hide device' in the settings of this tile so that this device does not appear on the start page.

Note: Some meters that are read via HTTP require a user name/password as authorisation. You can specify this in the address for HTTP access, e.g. with http://username:password@192.168.2.111. If your user name or password contains an "@", you must replace it with "%40".