{ "$schema": "https://raw.githubusercontent.com/nobrega8/mbmap-library/main/schema/mbmap-2.schema.json", "mbmap": 2, "vendor": "KEBA", "model": "KeContact P30", "models": ["KeContact P30 c-series", "KeContact P30 x-series"], "vendor_website": "keba.com", "description": "EV charging station, Modbus TCP", "revision": 1, "revised": "2026-11-10", "source": "KEBA, KeContact P30 Modbus TCP Programmers Guide, V 1.07 (en), 12.2025", "sources": [ { "title": "KeContact P30 Modbus TCP Programmers Guide", "version": "1.07", "date": "2025-12", "url": "https://a.storyblok.com/f/40131/x/44932c2bc8/kecontactp30modbustcp_pgen.pdf", "note": "linked in issue #198" } ], "notes": [ "The interface needs a P30 c-series with firmware 3.10.16 or later, or a P30 x-series with software 1.11 or later. DIP switch DSW1.3 on the station must be ON to enable Modbus TCP. The guide says Modbus TCP and the UDP interface must not be used together.", "The guide says the Unit ID must be 255, that only function codes 3 (read) and 6 (write) are supported, and that registers cannot be read in blocks: each value is read on its own, at most 2 registers (one 32-bit value). Registers are numbered from 0 (address_base 0), although the guide adds that some clients need +1.", "Every readable value is a 32-bit unsigned integer in two registers. The guide does not state the word order; big (high word first) is assumed. Check against the display or the serial number if a value looks wrong.", "Write registers hold one 16-bit value, are write-only (the guide marks them wo) and cannot be read back. The guide recommends reading no faster than every 0.5 s and writing no faster than every 5 s.", "Firmware version (1018) is hex-coded in the decimal value (30A0D00 hex is 3.10.14); it has no firmware role because the raw value is not a version string. The guide notes that Modbus TCP version 1.11 numbers this register 1013.", "Product type and features (1016) is a decimal number whose digits give the product type, cable or socket, maximum current, series, meter type and RFID; the digit tables are in the guide. Error code (1006) is a decimal number to be read as hex: the leading hex digit is the error group.", "Written from the manufacturer's document; not tested on a device." ], "protocol": "tcp", "unit_id": 255, "port": 502, "address_base": 0, "max_read_registers": 2, "byte_order": "big", "word_order": "big", "x_status": "official", "enums": { "charging_state": {"0": "Start-up", "1": "Not ready for charging", "2": "Ready for charging", "3": "Charging", "4": "Error", "5": "Interrupted (too hot or suspended)"}, "cable_state": {"0": "No cable", "1": "Cable at station", "3": "Cable at station, locked", "5": "Cable at station and vehicle", "7": "Cable at station and vehicle, locked"}, "phase_source": {"0": "None", "1": "OCPP", "2": "REST API", "3": "Modbus TCP", "4": "UDP"}, "phase_state": {"1": "Single-phase", "3": "Three-phase"}, "enable": {"0": "Disable (suspended)", "1": "Enable"}, "phase_toggle": {"0": "1 phase", "1": "3 phases"} }, "registers": [ {"name": "Charging state", "group": "Status", "area": "holding", "address": 1000, "type": "uint32", "access": "R", "enum": "charging_state"}, {"name": "Cable state", "group": "Status", "area": "holding", "address": 1004, "type": "uint32", "access": "R", "enum": "cable_state"}, {"name": "Error code", "group": "Status", "area": "holding", "address": 1006, "type": "uint32", "access": "R", "description": "0 is no error; otherwise read the decimal value as hex"}, {"name": "Current L1", "group": "Measurements", "area": "holding", "address": 1008, "type": "uint32", "access": "R", "scale": 0.001, "unit": "A"}, {"name": "Current L2", "group": "Measurements", "area": "holding", "address": 1010, "type": "uint32", "access": "R", "scale": 0.001, "unit": "A"}, {"name": "Current L3", "group": "Measurements", "area": "holding", "address": 1012, "type": "uint32", "access": "R", "scale": 0.001, "unit": "A"}, {"name": "Serial number", "group": "Device", "area": "holding", "address": 1014, "type": "uint32", "access": "R", "role": "serial"}, {"name": "Product type and features", "group": "Device", "area": "holding", "address": 1016, "type": "uint32", "access": "R", "description": "Decimal digits for type, cable or socket, current, series, meter and RFID; see the guide"}, {"name": "Firmware version", "group": "Device", "area": "holding", "address": 1018, "type": "uint32", "access": "R", "description": "Hex-coded: read the decimal value as hex, one byte per version part"}, {"name": "Active power", "group": "Measurements", "area": "holding", "address": 1020, "type": "uint32", "access": "R", "scale": 0.001, "unit": "W"}, {"name": "Total energy", "group": "Measurements", "area": "holding", "address": 1036, "type": "uint32", "access": "R", "scale": 0.1, "unit": "Wh", "description": "Lifetime energy of the station"}, {"name": "Voltage L1", "group": "Measurements", "area": "holding", "address": 1040, "type": "uint32", "access": "R", "unit": "V"}, {"name": "Voltage L2", "group": "Measurements", "area": "holding", "address": 1042, "type": "uint32", "access": "R", "unit": "V"}, {"name": "Voltage L3", "group": "Measurements", "area": "holding", "address": 1044, "type": "uint32", "access": "R", "unit": "V"}, {"name": "Power factor", "group": "Measurements", "area": "holding", "address": 1046, "type": "uint32", "access": "R", "scale": 0.1, "unit": "%"}, {"name": "Maximum charging current", "group": "Current limits", "area": "holding", "address": 1100, "type": "uint32", "access": "R", "scale": 0.001, "unit": "A"}, {"name": "Maximum supported current", "group": "Current limits", "area": "holding", "address": 1110, "type": "uint32", "access": "R", "scale": 0.001, "unit": "A", "description": "Hardware limit: lowest of DIP switch, cable coding and temperature limit; socket models show 6 A with no cable plugged"}, {"name": "RFID card", "group": "Session", "area": "holding", "address": 1500, "type": "uint32", "access": "R", "description": "First 4 bytes of the card UID, when the session was authorized by RFID"}, {"name": "Charged energy", "group": "Session", "area": "holding", "address": 1502, "type": "uint32", "access": "R", "scale": 0.1, "unit": "Wh", "description": "Energy of the current session"}, {"name": "Phase switching source", "group": "Phase switching", "area": "holding", "address": 1550, "type": "uint32", "access": "R", "enum": "phase_source"}, {"name": "Phase switching state", "group": "Phase switching", "area": "holding", "address": 1552, "type": "uint32", "access": "R", "enum": "phase_state"}, {"name": "Failsafe current setting", "group": "Failsafe", "area": "holding", "address": 1600, "type": "uint32", "access": "R", "scale": 0.001, "unit": "A", "description": "Active setting, not necessarily the persisted one"}, {"name": "Failsafe timeout setting", "group": "Failsafe", "area": "holding", "address": 1602, "type": "uint32", "access": "R", "unit": "s", "description": "Active setting, not necessarily the persisted one"}, {"name": "Set charging current", "group": "Commands", "area": "holding", "address": 5004, "type": "uint16", "access": "W", "scale": 0.001, "unit": "A", "write_min": 6000, "write_max": 63000, "description": "Raw value in mA; lasts until the next reboot"}, {"name": "Set energy limit", "group": "Commands", "area": "holding", "address": 5010, "type": "uint16", "access": "W", "scale": 10, "unit": "Wh", "description": "Ends the current or next session once this energy is delivered"}, {"name": "Unlock plug", "group": "Commands", "area": "holding", "address": 5012, "type": "uint16", "access": "W", "write_min": 0, "write_max": 0, "description": "Write 0; only in suspended state"}, {"name": "Enable charging station", "group": "Commands", "area": "holding", "address": 5014, "type": "uint16", "access": "W", "write_min": 0, "write_max": 1, "enum": "enable", "description": "Disabling stops an active session"}, {"name": "Failsafe current", "group": "Failsafe", "area": "holding", "address": 5016, "type": "uint16", "access": "W", "scale": 0.001, "unit": "A", "description": "Raw value in mA: 0 stops charging, otherwise 6000 to 32000. Only active once a failsafe timeout is sent"}, {"name": "Failsafe timeout", "group": "Failsafe", "area": "holding", "address": 5018, "type": "uint16", "access": "W", "unit": "s", "description": "0 turns failsafe off, otherwise 5 to 600"}, {"name": "Failsafe persist", "group": "Failsafe", "area": "holding", "address": 5020, "type": "uint16", "access": "W", "write_min": 1, "write_max": 1, "description": "Write 1 to store the failsafe settings"}, {"name": "Phase switch source select", "group": "Phase switching", "area": "holding", "address": 5050, "type": "uint16", "access": "W", "write_min": 0, "write_max": 4, "enum": "phase_source", "description": "Chooses the channel that drives contact x2"}, {"name": "Trigger phase switch", "group": "Phase switching", "area": "holding", "address": 5052, "type": "uint16", "access": "W", "write_min": 0, "write_max": 1, "enum": "phase_toggle"} ] }