Skip to content

Example Profiles ​

The following profiles each show one technique using a real device: HTTP, TCP (Modbus), UDP, MQTT and KNX. They are shortened so that the essentials remain visible, and the Profile Editor has checked them without findings. You can find the complete profiles of these devices in the Online Library. Profile Format and CommandServer explain the structure.

To try out an example: save the JSON text as a file with the extension .json, upload it under Skills → Add-ons → Profiles with Manual Upload, and create a device with Create device.

HTTP: go-eCharger ​

The go-eCharger wallbox has an HTTP interface that delivers JSON (API v2, to be enabled locally in the go-e app). The profile queries the status every 30 seconds and can force or block charging and set the charging current.

json
{
	"version": "1.0",
	"author": "Muster Integration GmbH",
	"description": "go-eCharger (HTTP-API v2)",
	"manufacturer": "go-e",
	"model": "go-eCharger",
	"platform": "go-e",
	"category": "Energy",
	"type": "EV Charger",
	"nomosCertified": false,
	"compatibility": 50,
	"className": "GOE_CHARGER",
	"engineType": "",
	"structure": {
		"config": {
			"ACTIVE": {"value": "YES", "editable": false},
			"DEBUG": {"value": "NO", "editable": false},
			"SERVERIP": {"value": "", "editable": {"type": "host", "default": ""}},
			"SERVERPORT": {"value": "80", "editable": false},
			"SERVERPROTOCOL": {"value": "HTTP", "editable": false},
			"SERVERMODE": {"value": "ASCII", "editable": false},
			"SERVERTIMEOUT_IN_MS": {"value": "8000", "editable": false},
			"CMDPREFIX": {"value": "/api/", "editable": false},
			"STARTUPCMD": {"value": "STATUS", "editable": false},
			"MATCHING": {"value": "FULL", "editable": false},
			"CONNECTEVENT": {"value": "REACHABLE=1", "editable": false},
			"DISCONNECTEVENT": {"value": "REACHABLE=0", "editable": false}
		},
		"commands": {
			"STATUS": {"sequence": "status?filter=rbt,frc,car,lmo,wh,tpa,eto,tma,alw,ama,cbl,cus,fup,awe,ust,cdi,rssi,modelStatus,error", "parameterCount": 0},
			"SETFRC": {"sequence": "set?frc=\\#", "parameterCount": 1},
			"SETAMA": {"sequence": "set?ama=\\#", "parameterCount": 1}
		},
		"mappings": {
			"FRC": {"match": "\"frc\":\\*,", "onChange": true},
			"CAR": {"match": "\"car\":\\*,", "onChange": true},
			"CHARGING": {"match": "", "onChange": true, "condition": "{$CAR$,%in2}"},
			"AMA": {"match": "\"ama\":\\*,", "onChange": true},
			"TPA": {"match": "\"tpa\":\\*,", "onChange": true, "condition": "{%*1.0}"},
			"WH": {"match": "\"wh\":\\*,", "onChange": true, "condition": "{%/1000.00}"}
		}
	},
	"polling": {
		"Status": {"interval": 30, "editableInterval": true, "command": "STATUS"}
	},
	"properties": {
		"powerstate": {"method": "set", "property": "FRC", "datatype": "int", "valueList": [{"text": "Neutral", "value": "0"}, {"text": "Off", "value": "1"}, {"text": "On", "value": "2"}]},
		"amperelimit": {"method": "set", "property": "AMA", "datatype": "int", "unit": "A", "min": 6, "max": 32, "internalMin": 6, "internalMax": 32, "stepValue": 1}
	},
	"propertiesMeta": {
		"powerstate": {"text": "State", "properties": ["powerstate"]},
		"amperelimit": {"text": "Charging current", "properties": ["amperelimit"]}
	},
	"mappings": {
		"powerstate": {"method": "get", "property": "FRC", "datatype": "int", "valueList": [{"text": "Neutral", "value": "0"}, {"text": "Off", "value": "1"}, {"text": "On", "value": "2"}]},
		"status": {"method": "get", "property": "CAR", "datatype": "int", "valueList": [{"text": "Unknown", "value": "0"}, {"text": "Idle", "value": "1"}, {"text": "Charging", "value": "2"}, {"text": "Waiting", "value": "3"}, {"text": "Completed", "value": "4"}, {"text": "Error", "value": "5"}]},
		"charging": {"method": "get", "property": "CHARGING", "datatype": "bool", "defaultValue": false},
		"amperelimit": {"method": "get", "property": "AMA", "datatype": "int", "unit": "A", "min": 6, "max": 32, "internalMin": 6, "internalMax": 32},
		"power": {"method": "get", "property": "TPA", "datatype": "float", "unit": "W", "customFormat": {"format": {"Math.round": {"var": "value"}}}},
		"e_connected": {"method": "get", "property": "WH", "datatype": "float", "unit": "kWh"},
		"reachable": {"method": "get", "property": "REACHABLE", "datatype": "bool", "defaultValue": false}
	},
	"mappingsMeta": {
		"powerstate": {"text": "State", "properties": ["powerstate"]},
		"status": {"text": "Status", "properties": ["status"]},
		"charging": {"text": "Charging", "properties": ["charging"]},
		"amperelimit": {"text": "Charging current", "properties": ["amperelimit"]},
		"power": {"text": "Power", "properties": ["power"]},
		"e_connected": {"text": "Energy", "properties": ["e_connected"]},
		"reachable": {"text": "Reachable", "properties": ["reachable"]}
	},
	"actionTemplates": [
		{"templateid": "powerstate", "mapping": "powerstate", "text": "State", "icon": "toggle-on", "valueList": [{"text": "Neutral", "value": "0"}, {"text": "Off", "value": "1"}, {"text": "On", "value": "2"}]},
		{"templateid": "amperelimit", "mapping": "amperelimit", "text": "Charging current", "icon": "adjust"}
	],
	"triggerTemplates": [
		{"templateid": "status", "mapping": "status", "text": "Status", "icon": "info-circle", "valueList": [{"text": "Unknown", "value": "0"}, {"text": "Idle", "value": "1"}, {"text": "Charging", "value": "2"}, {"text": "Waiting", "value": "3"}, {"text": "Completed", "value": "4"}, {"text": "Error", "value": "5"}]},
		{"templateid": "charging", "mapping": "charging", "text": "Charging", "icon": "bolt"},
		{"templateid": "power", "mapping": "power", "text": "Power", "icon": "bolt"}
	],
	"hideProperties": true,
	"hideMappings": true
}

What the example shows:

  • CMDPREFIX /api/ precedes every command. STATUS therefore fetches http://<IP>/api/status?filter=…, and SETAMA with the value 16 calls /api/set?ama=16.
  • STARTUPCMD queries the status right at startup, not only after 30 seconds.
  • Response patterns for JSON: "\"car\":\\*," captures the value between "car": and the next comma. The query is the same as in the complete profile of the Online Library and names more fields than this example uses. For the last field of a JSON object, see Patterns.
  • Format: {%/1000.00} converts Wh into kWh with two decimal places; {%/1000} would result in whole kWh.
  • Calculated value: CHARGING is 1 if CAR has the value 2 (charging).
  • Value lists: powerstate may only take 0, 1 or 2; the same list is in the template so that automations show a selection.
  • Polling with editableInterval: The interval can be changed when the device is created.
  • Reachability: Every successful query reports REACHABLE=1, every failed one REACHABLE=0.

TCP: Eastron SDM120 via Modbus TCP ​

The Eastron SDM120 electricity meter speaks Modbus RTU; a Modbus TCP gateway transfers it to the network. The profile reads voltage and grid power every 5 seconds and the meter readings every minute.

json
{
	"version": "1.0",
	"author": "Muster Integration GmbH",
	"description": "Eastron SDM120 über Modbus-TCP-Gateway",
	"manufacturer": "Eastron",
	"model": "SDM120 Modbus",
	"platform": "Eastron",
	"category": "Energy",
	"type": "Smart Meter",
	"nomosCertified": false,
	"compatibility": 50,
	"className": "EASTRON_SDM120",
	"engineType": "",
	"structure": {
		"config": {
			"ACTIVE": {"value": "YES", "editable": false},
			"DEBUG": {"value": "NO", "editable": false},
			"SERVERIP": {"value": "", "editable": {"type": "host", "default": ""}},
			"SERVERPORT": {"value": "502", "editable": {"type": "integer", "default": "502"}},
			"SERVERPROTOCOL": {"value": "TCP", "editable": false},
			"SERVERMODE": {"value": "HEX", "editable": false},
			"SERVERTIMEOUT_IN_MS": {"value": "NONE", "editable": false},
			"SPACING": {"value": "1000", "editable": false},
			"MATCHING": {"value": "FULL", "editable": false},
			"CONNECTEVENT": {"value": "REACHABLE=1", "editable": false},
			"DISCONNECTEVENT": {"value": "REACHABLE=0", "editable": false}
		},
		"commands": {
			"READ_INSTANT": {"sequence": "000000000006010400000020", "parameterCount": 0, "tag": "instant"},
			"READ_ENERGY": {"sequence": "000000000006010400480004", "parameterCount": 0, "tag": "energy"}
		},
		"mappings": {
			"L1_VOLTAGE": {"match": "000000000043010440\\!0!\\^^^^^^^^", "onChange": true, "condition": "{%swap32,%float}", "tag": "instant"},
			"GRID": {"match": "000000000043010440\\!48!\\^^^^^^^^", "onChange": true, "condition": "{%swap32,%float,%*-1}", "tag": "instant"},
			"E_IMPORT": {"match": "00000000000B010408\\!0!\\^^^^^^^^", "onChange": true, "condition": "{%swap32,%float}", "tag": "energy"},
			"E_EXPORT": {"match": "00000000000B010408\\!8!\\^^^^^^^^", "onChange": true, "condition": "{%swap32,%float}", "tag": "energy"}
		}
	},
	"polling": {
		"Instant": {"interval": 5, "editableInterval": false, "command": "READ_INSTANT"},
		"Energy": {"interval": 60, "editableInterval": false, "command": "READ_ENERGY"}
	},
	"properties": {},
	"propertiesMeta": {},
	"mappings": {
		"grid": {"method": "get", "property": "GRID", "datatype": "float", "unit": "W", "customFormat": {"format": {"Math.abs": {"Math.round": {"var": "value"}}}, "red-minus": {"<": [{"var": "value"}, 0]}, "green-plus": {">": [{"var": "value"}, 0]}}},
		"l1_voltage": {"method": "get", "property": "L1_VOLTAGE", "datatype": "float", "unit": "V", "uihidden": true},
		"meter_e_total_imp": {"method": "get", "property": "E_IMPORT", "datatype": "float", "unit": "kWh"},
		"meter_e_total_exp": {"method": "get", "property": "E_EXPORT", "datatype": "float", "unit": "kWh"},
		"reachable": {"method": "get", "property": "REACHABLE", "datatype": "bool", "defaultValue": false}
	},
	"mappingsMeta": {
		"grid": {"text": "Grid", "properties": ["grid"]},
		"l1_voltage": {"text": "Voltage", "properties": ["l1_voltage"]},
		"meter_e_total_imp": {"text": "Total Import", "properties": ["meter_e_total_imp"]},
		"meter_e_total_exp": {"text": "Total Export", "properties": ["meter_e_total_exp"]},
		"reachable": {"text": "Reachable", "properties": ["reachable"]}
	},
	"hideProperties": false,
	"hideMappings": false
}

What the example shows:

  • SERVERMODE HEX: Commands and responses are hex digits. 000000000006010400000020 is a Modbus TCP request: transaction 0000, protocol 0000, length 0006, device 01, function 04 (read input registers), from register 0000, 0020 (32) registers.
  • Tags: Both queries deliver responses with the same structure. Through tag, each response is evaluated only by the patterns of its query.
  • Patterns: 000000000043010440 is the header of the response (length 0x43, device 1, function 4, 0x40 bytes). \!48! skips 24 bytes, i.e. 6 registers; \^^^^^^^^ captures the next 4 bytes. The grid power is therefore read from register 12 (0x000C).
  • Format: %swap32,%float reads the 4 bytes as a decimal number (FLOAT32). The meter reports consumption as positive; in nomos, grid is seen from the house's point of view, feed-in positive and consumption negative. %*-1 therefore reverses the sign.
  • SERVERTIMEOUT_IN_MS NONE: The connection stays open, and the reachability follows it. SPACING 1000 gives the gateway time to respond before the next query comes.
  • Editable port: When the device is created, the dialog requests the IP address and port of the gateway; the port is pre-filled with 502.
  • Display: customFormat shows the grid power without a sign, red for consumption and green for feed-in.
  • Feedback values without actions: A meter is only read; properties stays empty.

For other Modbus devices, change the device number, function (03 for holding registers), start register and count in the sequence, and adapt length and byte count in the header of the pattern. Read signed integer registers with {%int16} or {%int32}.

UDP: KEBA KeContact P30 ​

The KEBA KeContact P30 wallbox responds via UDP on port 7090 with JSON. The profile queries status and measured values, enables charging and sets the charging current.

json
{
	"version": "1.0",
	"author": "Muster Integration GmbH",
	"description": "KEBA KeContact P30 (UDP)",
	"manufacturer": "KEBA",
	"model": "KeContact P30",
	"platform": "KEBA",
	"category": "Energy",
	"type": "EV Charger",
	"nomosCertified": false,
	"compatibility": 50,
	"className": "KEBA_P30",
	"engineType": "",
	"structure": {
		"config": {
			"ACTIVE": {"value": "YES", "editable": false},
			"DEBUG": {"value": "NO", "editable": false},
			"SERVERIP": {"value": "", "editable": {"type": "host", "default": ""}},
			"SERVERPORT": {"value": "7090", "editable": false},
			"LOCALPORT": {"value": "7090", "editable": false},
			"SERVERPROTOCOL": {"value": "UDP", "editable": false},
			"SERVERMODE": {"value": "ASCII", "editable": false},
			"SERVERTIMEOUT_IN_MS": {"value": "NONE", "editable": false},
			"SPACING": {"value": "200", "editable": false},
			"HEARTBEATCMD": {"value": "REPORT2;30", "editable": false},
			"HEARTBEATTIMEOUT": {"value": "2000", "editable": false},
			"DISCONNECTEVENT": {"value": "REACHABLE=0", "editable": false},
			"MATCHING": {"value": "FULL", "editable": false}
		},
		"commands": {
			"REPORT2": {"sequence": "report 2", "parameterCount": 0},
			"REPORT3": {"sequence": "report 3", "parameterCount": 0},
			"SETENA": {"sequence": "ena \\#", "parameterCount": 1, "spacing": "2000"},
			"SETCURR": {"sequence": "curr \\#", "parameterCount": 1}
		},
		"mappings": {
			"REACHABLE": {"match": "\"ID\": \"\\*\",", "onChange": false, "condition": "{%in2|3}"},
			"ENABLE_USER": {"match": "\"Enable user\": \\*,", "onChange": true, "condition": ""},
			"PLUG": {"match": "\"Plug\": \\*,", "onChange": true, "condition": ""},
			"MAX_CURR": {"match": "\"Max curr\": \\*,", "onChange": true, "condition": ""},
			"P": {"match": "\"P\": \\*,", "onChange": true, "condition": "{%/1000}"}
		}
	},
	"polling": {
		"Status": {"interval": 10, "editableInterval": false, "command": "REPORT2"},
		"Measurements": {"interval": 10, "editableInterval": false, "command": "REPORT3"}
	},
	"properties": {
		"state": {"method": "set", "property": "ENA", "datatype": "bool", "sizeInBit": 1},
		"switchon": {"method": "set", "property": "ENA", "value": 1, "datatype": "bool", "sizeInBit": 1, "uihidden": true},
		"switchoff": {"method": "set", "property": "ENA", "value": 0, "datatype": "bool", "sizeInBit": 1, "uihidden": true},
		"amperelimit": {"method": "set", "property": "CURR", "datatype": "int", "unit": "A", "min": 6, "max": 32, "internalMin": 6000, "internalMax": 32000, "stepValue": 1}
	},
	"propertiesMeta": {
		"state": {"text": "Charging", "properties": ["state", "switchon", "switchoff"]},
		"amperelimit": {"text": "Charging current", "properties": ["amperelimit"]}
	},
	"mappings": {
		"state": {"method": "get", "property": "ENABLE_USER", "datatype": "bool", "defaultValue": false},
		"plug": {"method": "get", "property": "PLUG", "datatype": "int", "valueList": [{"text": "Kein Kabel", "value": "0"}, {"text": "Kabel an Wallbox", "value": "1"}, {"text": "Kabel an Wallbox, verriegelt", "value": "3"}, {"text": "Fahrzeug verbunden", "value": "5"}, {"text": "Fahrzeug verbunden, verriegelt", "value": "7"}]},
		"amperelimit": {"method": "get", "property": "MAX_CURR", "datatype": "int", "unit": "A", "min": 6, "max": 32, "internalMin": 6000, "internalMax": 32000},
		"power": {"method": "get", "property": "P", "datatype": "float", "unit": "W", "customFormat": {"format": {"Math.round": {"var": "value"}}}},
		"reachable": {"method": "get", "property": "REACHABLE", "datatype": "bool", "defaultValue": false}
	},
	"mappingsMeta": {
		"state": {"text": "Charging", "properties": ["state"]},
		"plug": {"text": "Cable Status", "properties": ["plug"]},
		"amperelimit": {"text": "Charging current", "properties": ["amperelimit"]},
		"power": {"text": "Power", "properties": ["power"]},
		"reachable": {"text": "Reachable", "properties": ["reachable"]}
	},
	"actionTemplates": [
		{"templateid": "switchon", "mapping": "switchon", "text": "Turn On", "icon": "toggle-on"},
		{"templateid": "switchoff", "mapping": "switchoff", "text": "Turn Off", "icon": "toggle-off"},
		{"templateid": "amperelimit", "mapping": "amperelimit", "text": "Charging current", "icon": "bolt"}
	],
	"triggerTemplates": [
		{"templateid": "plug", "mapping": "plug", "text": "Cable Status", "icon": "plug", "valueList": [{"text": "Kein Kabel", "value": "0"}, {"text": "Kabel an Wallbox", "value": "1"}, {"text": "Kabel an Wallbox, verriegelt", "value": "3"}, {"text": "Fahrzeug verbunden", "value": "5"}, {"text": "Fahrzeug verbunden, verriegelt", "value": "7"}]},
		{"templateid": "power", "mapping": "power", "text": "Power", "icon": "bolt"}
	],
	"hideProperties": true,
	"hideMappings": true
}

What the example shows:

  • LOCALPORT 7090: The wallbox always responds to port 7090; the controller must receive there.
  • Reachability via UDP: Because UDP has no connection, HEARTBEATCMD sends report 2 every 30 seconds. If no response arrives within HEARTBEATTIMEOUT (2 seconds), DISCONNECTEVENT reports REACHABLE=0. A CONNECTEVENT is deliberately missing: with UDP, it would also arrive when the wallbox is off. Instead, the pattern REACHABLE sets the value to 1 as soon as a response to report 2 or report 3 arrives ({%in2|3}).
  • SET commands: The action {"method": "set", "property": "ENA"} calls the command SETENA; \# in ena \# takes the value.
  • state, switchon, switchoff: The app switches with switchon/switchoff, automations with state.
  • Scaling: The wallbox calculates in mA, the app in A. internalMin/internalMax 6000–32000 and min/max 6–32 convert in both directions, for the action as well as for the feedback value.
  • Format: The wallbox reports the power in mW; {%/1000} results in W.
  • Texts: Charging, Charging current, Cable Status and Power are terms that nomos translates. The texts of the value list are not; they appear in every language as in the profile.

MQTT: Dimmer with Tasmota ​

A dimmer with the Tasmota firmware, connected via the broker of the MQTT skill. When creating the device, enter as MQTT Topic the topic that is set in Tasmota.

json
{
	"version": "1.0",
	"author": "Muster Integration GmbH",
	"description": "Dimmer mit Tasmota-Firmware",
	"manufacturer": "Tasmota",
	"model": "Dimmer",
	"platform": "MQTT",
	"category": "Lighting",
	"type": "Lightbulb",
	"nomosCertified": false,
	"compatibility": 50,
	"className": "",
	"engineType": "MQTT",
	"properties": {
		"state": {"method": "command", "command": "power", "mqtt": "cmnd/%mqttTopic%/POWER", "datatype": "bool"},
		"switchon": {"method": "command", "command": "power", "value": 1, "mqtt": "cmnd/%mqttTopic%/POWER", "datatype": "null", "uihidden": true},
		"switchoff": {"method": "command", "command": "power", "value": 0, "mqtt": "cmnd/%mqttTopic%/POWER", "datatype": "null", "uihidden": true},
		"level": {"method": "command", "command": "brightness", "mqtt": "cmnd/%mqttTopic%/Dimmer", "datatype": "int", "unit": "percent", "min": 0, "max": 100, "internalMin": 0, "internalMax": 100}
	},
	"propertiesMeta": {
		"state": {"text": "State", "properties": ["state", "switchon", "switchoff"]},
		"level": {"text": "Brightness", "properties": ["level"]}
	},
	"mappings": {
		"state": {"method": "get", "property": "power", "mqtt": "stat/%mqttTopic%/RESULT", "mqttValue": "POWER", "datatype": "bool"},
		"level": {"method": "get", "property": "dimmer", "mqtt": "stat/%mqttTopic%/RESULT", "mqttValue": "Dimmer", "datatype": "int", "unit": "percent", "min": 0, "max": 100, "internalMin": 0, "internalMax": 100},
		"reachable": {"method": "get", "property": "reachable", "mqtt": "tele/%mqttTopic%/LWT", "mqttValue": "", "datatype": "bool", "defaultValue": true}
	},
	"mappingsMeta": {
		"state": {"text": "State", "properties": ["state"]},
		"level": {"text": "Brightness", "properties": ["level"]},
		"reachable": {"text": "Reachable", "properties": ["reachable"]}
	},
	"actionTemplates": [
		{"templateid": "switchon", "mapping": "switchon", "text": "Turn On", "icon": "toggle-on"},
		{"templateid": "switchoff", "mapping": "switchoff", "text": "Turn Off", "icon": "toggle-off"},
		{"templateid": "level", "mapping": "level", "text": "Brightness", "icon": "sun-o"}
	],
	"triggerTemplates": [
		{"templateid": "state.on", "mapping": "state", "text": "Is Turned On", "value": "1", "icon": "toggle-on"},
		{"templateid": "state.off", "mapping": "state", "text": "Is Turned Off", "value": "0", "icon": "toggle-off"},
		{"templateid": "level", "mapping": "level", "text": "Brightness", "icon": "sun-o"}
	],
	"hideProperties": true,
	"hideMappings": true
}

What the example shows:

  • Commands: Tasmota accepts commands on cmnd/<Topic>/<Command>. switchon sends 1 to cmnd/<Topic>/POWER, level sends the value to cmnd/<Topic>/Dimmer.
  • Same command, same topic: state, switchon and switchoff use the same command and therefore the same topic.
  • Feedback values from JSON: Tasmota responds on stat/<Topic>/RESULT with e.g. {"POWER":"ON","Dimmer":60}. mqttValue POWER or Dimmer selects the field; with the data type bool, ON counts as “on”.
  • Reachability: Tasmota reports Online or Offline on tele/<Topic>/LWT. An empty mqttValue takes the whole payload.
  • Empty className: With MQTT, each device gets its own identifier.

KNX: Ventilation unit with three speeds ​

A ventilation unit that is switched on and off via KNX, takes a speed from 0 to 3 and reports the supply air temperature and a filter alarm. The profile contains no addresses: Create device opens the dialog of the KNX skill, where you assign each value its group address.

json
{
	"version": "1.0",
	"author": "Muster Integration GmbH",
	"description": "KNX Lüftungsgerät mit drei Stufen",
	"manufacturer": "KNX",
	"model": "Lüftung 3 Stufen",
	"platform": "KNX",
	"category": "Fans",
	"type": "Fan",
	"nomosCertified": false,
	"compatibility": 50,
	"className": "KNX",
	"engineType": "KNX",
	"properties": {
		"state": {"method": "set", "property": "value", "datatype": "bool", "sizeInBit": 1, "filterDPT": ["1.001"]},
		"switchon": {"method": "set", "property": "value", "value": 1, "datatype": "bool", "sizeInBit": 1, "uihidden": true},
		"switchoff": {"method": "set", "property": "value", "value": 0, "datatype": "bool", "sizeInBit": 1, "uihidden": true},
		"fanspeed": {"method": "set", "property": "value", "datatype": "int", "sizeInBit": 8, "filterDPT": ["5.010"], "valueList": [{"text": "Off", "value": "0"}, {"text": "Low", "value": "1"}, {"text": "Medium", "value": "2"}, {"text": "High", "value": "3"}]}
	},
	"propertiesMeta": {
		"state": {"text": "State", "properties": ["state", "switchon", "switchoff"]},
		"fanspeed": {"text": "Speed", "properties": ["fanspeed"]}
	},
	"mappings": {
		"state": {"method": "get", "property": "value", "datatype": "bool", "sizeInBit": 1, "filterDPT": ["1.001"]},
		"fanspeed": {"method": "get", "property": "value", "datatype": "int", "sizeInBit": 8, "filterDPT": ["5.010"], "valueList": [{"text": "Off", "value": "0"}, {"text": "Low", "value": "1"}, {"text": "Medium", "value": "2"}, {"text": "High", "value": "3"}]},
		"temperature": {"method": "get", "property": "value", "datatype": "float", "unit": "temperature", "sizeInBit": 16, "filterDPT": ["9.001"]},
		"filter": {"method": "get", "property": "value", "datatype": "bool", "sizeInBit": 1, "filterDPT": ["1.005"]}
	},
	"mappingsMeta": {
		"state": {"text": "State", "properties": ["state"]},
		"fanspeed": {"text": "Speed", "properties": ["fanspeed"]},
		"temperature": {"text": "Temperature", "properties": ["temperature"]},
		"filter": {"text": "Filter wechseln", "properties": ["filter"]}
	},
	"actionTemplates": [
		{"templateid": "switchon", "mapping": "switchon", "text": "Turn On", "icon": "toggle-on"},
		{"templateid": "switchoff", "mapping": "switchoff", "text": "Turn Off", "icon": "toggle-off"},
		{"templateid": "fanspeed", "mapping": "fanspeed", "text": "Speed", "icon": "tachometer", "valueList": [{"text": "Off", "value": "0"}, {"text": "Low", "value": "1"}, {"text": "Medium", "value": "2"}, {"text": "High", "value": "3"}]}
	],
	"triggerTemplates": [
		{"templateid": "state.on", "mapping": "state", "text": "Is Turned On", "value": "1", "icon": "toggle-on"},
		{"templateid": "state.off", "mapping": "state", "text": "Is Turned Off", "value": "0", "icon": "toggle-off"},
		{"templateid": "temperature", "mapping": "temperature", "text": "Temperature", "icon": "thermometer"},
		{"templateid": "filter", "mapping": "filter", "text": "Filter wechseln", "value": "1", "icon": "exclamation-triangle"}
	],
	"hideProperties": true,
	"hideMappings": true
}

What the example shows:

  • Address fields: propertiesMeta produces the fields State and Speed for the group addresses for switching, mappingsMeta the fields for the status addresses of state, speed, temperature and filter alarm.
  • Size and datapoint type: sizeInBit 1 for switching (DPT 1.001) and the alarm (DPT 1.005), 8 for the speed (DPT 5.010), 16 for the temperature (DPT 9.001). filterDPT only offers matching group addresses when assigning.
  • Value list as allowlist: The action fanspeed only accepts 0 to 3.
  • No feedback value reachable: The reachability follows the KNX connection.
  • Templates: The filter alarm is set up as a trigger with the fixed value 1, so the automation does not ask for a value.
  • Text without translation: “Filter wechseln” is not a nomos term and appears like this in every language.

The KNX skill already includes light, dimmer, shading, thermostat and many sensors; a profile of your own is worthwhile for devices that are missing there.