Compare commits
80 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| a2ea9e5bbe | |||
| 3fca7161fc | |||
| 49dcd8785b | |||
| 780b4aa8d5 | |||
| 9598147dd5 | |||
| 4d2cfa3cb3 | |||
| fc4e9016cf | |||
| 530f0ecf12 | |||
| be9ff9c2c9 | |||
| 40a0e8e303 | |||
| dceede8602 | |||
| 6ffca719d9 | |||
| 1342ab6aaf | |||
| 4fa1b3cb06 | |||
| 6381ca58cf | |||
| b87c8087f5 | |||
| d39547bdc6 | |||
| c60ef2ccde | |||
| f39ae6f0c6 | |||
| bb0fb01c00 | |||
| b5b9e53c22 | |||
| 691a740111 | |||
| 29920195ba | |||
| 67c2410be7 | |||
| 8bda4f727e | |||
| a46cef3ee9 | |||
| 4c9f26a638 | |||
| 803348ea3a | |||
| 8211514fe3 | |||
| 078c37a20f | |||
| 6d0b36b60a | |||
| 7a820e700c | |||
| 5622e6ba81 | |||
| 865bf8425a | |||
| f922993d2f | |||
| 2b779d5532 | |||
| 0467179f70 | |||
| 20642e5ec3 | |||
| 0827befb06 | |||
| 2b8ef31263 | |||
| 8e80fd05b4 | |||
| 7ab1855295 | |||
| e8bf8c56cd | |||
| 416320604b | |||
| e489a2de36 | |||
| b73e0c6138 | |||
| 3165afe8a4 | |||
| 57950e7b0b | |||
| a3f03719f9 | |||
| e091b4301e | |||
| 226855362b | |||
| 3bc5355041 | |||
| 3af2995b40 | |||
| b447da5bfc | |||
| f2b7dee8bd | |||
| 77fe8c1b02 | |||
| 82142dd46c | |||
| 323ff24c04 | |||
| 277379abd7 | |||
| e79223c87e | |||
| 2a3808c1e4 | |||
| 449a3a801a | |||
| 3f15cd7f3f | |||
| f005d2bc09 | |||
| 70ae1ae6cf | |||
| f2ffb45ca6 | |||
| 0b2d00472e | |||
| 4553ed32e7 | |||
| 39ef630608 | |||
| b74367e5a0 | |||
| df1dd472cc | |||
| 888d021343 | |||
| de0edd5ad9 | |||
| e58115d303 | |||
| 626f86ec4e | |||
| 36d10702da | |||
| d231460612 | |||
| 70367f53ca | |||
| 1b8753636f | |||
| e94945fc0f |
@@ -1,3 +1,4 @@
|
|||||||
**/build/
|
**/build/
|
||||||
build/
|
build/
|
||||||
**/managed_components/
|
**/managed_components/
|
||||||
|
.DS_Store
|
||||||
|
|||||||
@@ -1,3 +1,11 @@
|
|||||||
[submodule "bacnet_stack"]
|
[submodule "bacnet_stack"]
|
||||||
path = bacnet_stack
|
path = bacnet_stack
|
||||||
url = https://git.tonycloud.org/dali/bacnet_stack.git
|
url = https://git.tonycloud.org/dali/bacnet_stack.git
|
||||||
|
[submodule "knx"]
|
||||||
|
path = knx
|
||||||
|
url = https://git.tonycloud.org/knx/knx.git
|
||||||
|
branch = v1
|
||||||
|
[submodule "tpuart"]
|
||||||
|
path = tpuart
|
||||||
|
url = https://git.tonycloud.org/knx/tpuart.git
|
||||||
|
branch = main
|
||||||
|
|||||||
@@ -4,6 +4,8 @@ This folder hosts the native ESP-IDF C++ rewrite of the Lua DALI gateway.
|
|||||||
|
|
||||||
## Layout
|
## Layout
|
||||||
|
|
||||||
|
This is the list of top-level directories and their purposes,
|
||||||
|
update as the project evolves:
|
||||||
- `apps/`: standard ESP-IDF applications for each firmware role.
|
- `apps/`: standard ESP-IDF applications for each firmware role.
|
||||||
- `apps/gateway/main/Kconfig.projbuild`: project-visible gateway-role settings such as per-channel native/serial PHY selection, gateway ids, pin mapping, and startup transport policy.
|
- `apps/gateway/main/Kconfig.projbuild`: project-visible gateway-role settings such as per-channel native/serial PHY selection, gateway ids, pin mapping, and startup transport policy.
|
||||||
- `components/`: reusable components shared by all gateway applications.
|
- `components/`: reusable components shared by all gateway applications.
|
||||||
@@ -12,18 +14,149 @@ This folder hosts the native ESP-IDF C++ rewrite of the Lua DALI gateway.
|
|||||||
- `dali_domain/`: native DALI domain facade over `dali_cpp` and raw frame sinks.
|
- `dali_domain/`: native DALI domain facade over `dali_cpp` and raw frame sinks.
|
||||||
- `gateway_cache/`: DALI scene/group/settings/runtime cache used by controller reconciliation and protocol bridges.
|
- `gateway_cache/`: DALI scene/group/settings/runtime cache used by controller reconciliation and protocol bridges.
|
||||||
- `gateway_bridge/`: per-channel bridge provisioning, command execution, protocol startup, and HTTP bridge actions.
|
- `gateway_bridge/`: per-channel bridge provisioning, command execution, protocol startup, and HTTP bridge actions.
|
||||||
|
- `openknx_idf/`: ESP-IDF port layer for the OpenKNX `gateway/knx` and `gateway/tpuart` submodules, including NVS-backed OpenKNX memory, development KNX security storage, ETS cEMI programming support, UDP multicast/unicast plumbing, and a native TP-UART interface without the Arduino framework.
|
||||||
- `gateway_modbus/`: gateway-owned Modbus TCP/RTU/ASCII config, generated DALI point tables, and provisioned Modbus model override dispatch.
|
- `gateway_modbus/`: gateway-owned Modbus TCP/RTU/ASCII config, generated DALI point tables, and provisioned Modbus model override dispatch.
|
||||||
- `gateway_bacnet/`: BACnet/IP server adapter backed by bacnet-stack, including the gateway-owned BACnet bridge model adapter.
|
- `gateway_bacnet/`: BACnet/IP server adapter backed by bacnet-stack, including the gateway-owned BACnet bridge model adapter.
|
||||||
- `gateway_ble/`: NimBLE GATT bridge for BLE transport parity on `FFF1`/`FFF2`/`FFF3`, including raw DALI notifications.
|
- `gateway_ble/`: NimBLE GATT bridge for BLE transport parity on `FFF1`/`FFF2`/`FFF3`, including raw DALI notifications.
|
||||||
- `gateway_controller/`: Lua-compatible gateway command dispatcher, internal scene/group state, and notification fan-out.
|
- `gateway_controller/`: Lua-compatible gateway command dispatcher, internal scene/group state, and notification fan-out.
|
||||||
- `gateway_network/`: HTTP `/info`, `/dali/cmd`, `/led/1`, `/led/0`, `/jq.js`, UDP port `2020` command/notify routing, Wi-Fi STA lifecycle, ESP-Touch smartconfig, setup AP mode, ESP-NOW setup ingress, and BOOT-button Wi-Fi reset for the native gateway.
|
- `gateway_network/`: HTTP `/info`, `/dali/cmd`, `/led/1`, `/led/0`, `/jq.js`, UDP port `2020` command/notify routing, Wi-Fi STA lifecycle, W5500 SPI Ethernet startup/teardown, ESP-Touch smartconfig, setup AP mode, ESP-NOW setup ingress, setup AP GPIO handling, and optional Wi-Fi reset GPIO handling for the native gateway.
|
||||||
- `gateway_runtime/`: persistent runtime state, command queueing, and device info services.
|
- `gateway_runtime/`: persistent runtime state, command queueing, and device info services.
|
||||||
- `gateway_485_control/`: optional 485 Lua control bridge for framed `0x28 0x01` commands and `0x22 ... checksum` notifications at `9600 8N1`; disabled by default because UART0 must be moved off the ESP-IDF console first.
|
- `gateway_485_control/`: optional 485 Lua control bridge for framed `0x28 0x01` commands and `0x22 ... checksum` notifications at `9600 8N1`; disabled by default because UART0 must be moved off the ESP-IDF console first.
|
||||||
- `gateway_usb_setup/`: optional USB Serial/JTAG setup bridge; disabled by default so USB remains available for debug at boot.
|
- `gateway_usb_setup/`: optional USB Serial/JTAG setup bridge; disabled by default so USB remains available for debug at boot.
|
||||||
|
- `knx`: The forked OpenKNX cEMI programming support, ESP-IDF port, and KNX security storage used by the gateway. You can edit this code when necessary to support missing ETS programming features or to implement the secure-session transport path.
|
||||||
|
- `knx_dali_gw`: The forked OpenKNX DALI-GW function-property support used by the gateway. You can edit this code when necessary to support missing DALI-GW features or to fix bugs.
|
||||||
|
|
||||||
|
## Gateway DALI cache
|
||||||
|
|
||||||
|
The gateway owns the shared DALI cache for multi-user deployments. App, BLE,
|
||||||
|
IP, Modbus, BACnet, KNX, and local control paths should treat the gateway cache
|
||||||
|
as the shared read surface instead of maintaining separate app-side device-state
|
||||||
|
caches. Transparent/setup raw forwarding paths remain bypass-oriented, but raw
|
||||||
|
DALI bus observation still feeds the passive decoder when frames are visible to
|
||||||
|
the gateway.
|
||||||
|
|
||||||
|
`gateway_cache` stores internal scene/group data and per-short-address DALI
|
||||||
|
state. Device settings, group masks, scene levels, known flags, and the last
|
||||||
|
runtime status are batched to NVS using `GATEWAY_CACHE_FLUSH_INTERVAL_MS`, which
|
||||||
|
defaults to 10000 ms. Runtime status loaded from disk is marked stale until the
|
||||||
|
gateway observes a bus command or the background refresher verifies it again.
|
||||||
|
|
||||||
|
`GATEWAY_CACHE_REFRESH_INTERVAL_MS` defaults to 120000 ms. When nonzero, the
|
||||||
|
controller maintenance loop refreshes direct short-address actual levels one
|
||||||
|
small step at a time. The refresh is low priority: it yields to queued gateway
|
||||||
|
commands, address allocation, live management reads, bridge traffic, and any raw
|
||||||
|
DALI bus activity from another master until the bus has been idle. Group and
|
||||||
|
broadcast targets are never queried for refresh.
|
||||||
|
|
||||||
|
Gateway feature opcode `0x06` keeps the Lua-compatible low-byte feature bits,
|
||||||
|
advertises cache support with bit `0x40`, advertises gateway/channel name
|
||||||
|
support with bit `0x80`, and advertises the native C++ gateway type with bit
|
||||||
|
`0x0100`. Bit `0x0200` advertises the generic gateway operation protocol, and
|
||||||
|
bit `0x0400` advertises explicit raw-report leases. Gateway opcode `0x05` reads
|
||||||
|
and writes user-facing gateway identity: operation `0x00` reads the channel
|
||||||
|
name, `0x01` writes the channel name, `0x02` reads the physical gateway device
|
||||||
|
name, and `0x03` writes the physical gateway device name. Empty writes reset to
|
||||||
|
the default name. Gateway opcode `0x39` returns cache summary and target
|
||||||
|
snapshots so frontend clients can read cached state without issuing live DALI
|
||||||
|
queries on supported gateways.
|
||||||
|
|
||||||
|
Gateway opcode `0x09` with address/data `0x00/0x00` is a chip-level channel-id
|
||||||
|
report. It returns the enabled DALI channel ids so clients do not need to probe
|
||||||
|
every possible gateway id one by one. For native C++ gateways, channel number is
|
||||||
|
the fixed 1-based Kconfig slot (`1` to `16`) and channel id is the persisted,
|
||||||
|
Lua-compatible gateway id used by normal `0x28 0x01 ...` command frames.
|
||||||
|
|
||||||
|
Gateway opcode `0x0B` is the serial-scoped channel command. The serial is the
|
||||||
|
last three bytes of the ESP base MAC. Operation `0x00` reports serial plus
|
||||||
|
`(channel number, channel id)` pairs. Operations `0x01` and `0x02` get and set
|
||||||
|
the channel id for the fixed channel number in the command frame gateway byte.
|
||||||
|
Operation `0x03` wraps an existing gateway command and dispatches it by fixed
|
||||||
|
channel number after the serial matches, so BLE/Wi-Fi configuration and DALI
|
||||||
|
send/query commands can target a channel even when its variable channel id is
|
||||||
|
unknown.
|
||||||
|
|
||||||
|
## Gateway operation protocol
|
||||||
|
|
||||||
|
Opcode `0x67` starts, aborts, and polls gateway-executed high-level DALI
|
||||||
|
operations. Clients send one compact gateway command and the controller runs the
|
||||||
|
required DTR setup, device-type select, query chain, retry, or address iteration
|
||||||
|
on the gateway. The command frame is:
|
||||||
|
|
||||||
|
- Start: `28 01 <gw> 67 01 <requestId> <operationIdLo> <operationIdHi> <payloadLenLo> <payloadLenHi> <TLV...> <checksum>`.
|
||||||
|
- Abort: `28 01 <gw> 67 02 <requestId> 00 00 00 00 <checksum>`.
|
||||||
|
- Status: `28 01 <gw> 67 03 <requestId> 00 00 00 00 <checksum>`.
|
||||||
|
|
||||||
|
Multi-byte fields are little-endian. TLV payload fields use
|
||||||
|
`{fieldId:u8, type:u8, len:u8, value...}`. Types are `0x01` u8, `0x02` u16,
|
||||||
|
`0x03` u32, `0x04` signed i32, `0x05` bool, and `0x06` byte list. Dynamic
|
||||||
|
snapshot metadata is returned as repeated byte-list entries using compact
|
||||||
|
`key=value` payloads.
|
||||||
|
|
||||||
|
Operation events are emitted as
|
||||||
|
`22 67 <gw> <requestId> <operationIdLo> <operationIdHi> <event> <status> <progress> <target> <count> <checksum>`.
|
||||||
|
Event values are accepted `0x00`, progress `0x01`, item result `0x02`,
|
||||||
|
completed `0x03`, aborted `0x04`, and error `0x05`. Status values are ok
|
||||||
|
`0x00`, busy `0x01`, invalid `0x02`, unsupported `0x03`, no response `0x04`,
|
||||||
|
failed `0x05`, and aborted `0x06`.
|
||||||
|
|
||||||
|
Large result payloads are emitted as chunks:
|
||||||
|
`22 68 <gw> <requestId> <operationIdLo> <operationIdHi> <total> <index> <chunkLen> <TLV...> <checksum>`.
|
||||||
|
Clients assemble chunks by gateway, request id, and operation id before
|
||||||
|
processing result TLVs.
|
||||||
|
|
||||||
|
The initial C++ executor accepts the shared `BridgeOperation` numeric ids for
|
||||||
|
raw send/query, brightness/on/off/recall, color-temperature and DT8 RGB/XY/RGBW
|
||||||
|
setters, DT1/DT4/DT5/DT6/DT8 snapshots, group masks, scene levels/maps, address
|
||||||
|
settings, short-address range search, and short-address allocation/reset/stop.
|
||||||
|
Unsupported ids return an `unsupported` operation error so old clients can fall
|
||||||
|
back to their app-side workflow. Legacy opcodes such as `0x12`, `0x13`, `0x14`,
|
||||||
|
`0x30`, `0x32`, `0x60`-`0x65`, and `0x39` remain available for compatibility.
|
||||||
|
|
||||||
|
Operation id `84` performs a direct-short-address DALI identity memory batch
|
||||||
|
read. The start TLV must include target field `0x01` as a u8 short address
|
||||||
|
`0..63`; group and broadcast reads are rejected. Kind field `0x20` as u8
|
||||||
|
selects compact (`0`) or extended (`nonzero`) identity coverage. Results are
|
||||||
|
repeated field `0x30` byte-list entries, each with payload
|
||||||
|
`[bank, location, value]`. Missing byte replies are omitted; a completed result
|
||||||
|
with no entries reports `no response` so clients can fall back to single-byte
|
||||||
|
`READ MEMORY LOCATION` reads.
|
||||||
|
|
||||||
|
Opcode `0x66` controls passive raw-report leases. Command
|
||||||
|
`28 01 <gw> 66 01 <enabled> <ttlLo> <ttlHi> <checksum>` enables or disables a
|
||||||
|
volatile per-gateway lease; `ttl=0` disables. The response is
|
||||||
|
`22 66 <gw> <status> <enabled> <ttlLo> <ttlHi> <checksum>`. Passive raw DALI
|
||||||
|
notifications over UDP, BLE raw characteristics, ESP-NOW setup UART mirroring,
|
||||||
|
and gateway notification opcodes `0x01` and `0x65` are suppressed unless the
|
||||||
|
lease is active. Direct command/query responses still work without a raw-report
|
||||||
|
lease.
|
||||||
|
|
||||||
## Current status
|
## Current status
|
||||||
|
|
||||||
The native rewrite now wires a shared `gateway_core` bootstrap component, a multi-channel `dali_domain` wrapper over `dali_cpp`, a local vendored `dali` hardware backend from the LuatOS ESP-IDF port with raw receive fan-out, an initial `gateway_runtime` service that provides persistent settings, device info, Lua-compatible command framing helpers, and Lua-style query command deduplication, plus a `gateway_controller` service that starts the gateway command task, dispatches core Lua gateway opcodes, and owns internal scene/group state. The gateway app also includes a `gateway_ble` NimBLE bridge that advertises a Lua-compatible GATT service and forwards `FFF3` framed notifications, incoming `FFF1`/`FFF2`/`FFF3` writes, and native raw DALI frame notifications into the matching raw channel, a `gateway_network` service that provides the native HTTP `/info`, `GET`/`POST /dali/cmd`, `/led/1`, `/led/0`, `/jq.js`, UDP control-plane router on port `2020`, Wi-Fi STA lifecycle, ESP-Touch smartconfig credential provisioning, the Lua-style `LAMMIN_Gateway` setup AP on `192.168.3.1`, ESP-NOW setup ingress for Lua-compatible `connReq`/`connAck`/`echo`/`cmd`/`data`/`uart` packets, native raw DALI frame forwarding back to connected setup peers, and BOOT-button Wi-Fi credential clearing, and an optional `gateway_485_control` bridge that claims UART0 for Lua-compatible framed command ingress plus `0x22` notification egress when the console is moved off UART0. Startup behavior is configured in `main/Kconfig.projbuild`: BLE is enabled by default, Wi-Fi STA, smartconfig, and ESP-NOW setup mode are disabled by default, the built-in USB Serial/JTAG interface stays in debug mode unless the optional USB setup bridge mode is selected, and the UART0 control bridge stays disabled unless the deployment explicitly repurposes UART0 away from the ESP-IDF console. Runtime settings and internal scene/group data are cached in RAM after load, skip unchanged flash writes, and batch Wi-Fi credential commits to reduce flash stalls on ESP32-S3 boards where flash and PSRAM share the SPI bus. The gateway app exposes per-channel PHY selection through `main/Kconfig.projbuild`; each channel can be disabled, bound to the native DALI GPIO HAL, or bound to a UART1/UART2 serial PHY. The checked-in `sdkconfig` is aligned with the app's custom 16 MB partition table so the Wi-Fi/BLE/network-enabled image fits the OTA app slots.
|
The native rewrite now wires a shared `gateway_core` bootstrap component, a multi-channel `dali_domain` wrapper over `dali_cpp`, a local vendored `dali` hardware backend from the LuatOS ESP-IDF port with raw receive fan-out, an initial `gateway_runtime` service that provides persistent settings, device info, Lua-compatible command framing helpers, and Lua-style query command deduplication, plus a `gateway_controller` service that starts the gateway command task, dispatches core Lua gateway opcodes, and owns internal scene/group state. The gateway app also includes a `gateway_ble` NimBLE bridge that advertises a Lua-compatible GATT service and forwards `FFF3` framed notifications, incoming `FFF1`/`FFF2`/`FFF3` writes, and native raw DALI frame notifications into the matching raw channel, a `gateway_network` service that provides the native HTTP `/info`, `GET`/`POST /dali/cmd`, `/led/1`, `/led/0`, `/jq.js`, UDP control-plane router on port `2020`, W5500 SPI Ethernet with DHCP, Wi-Fi STA lifecycle, ESP-Touch smartconfig credential provisioning, the Lua-style `LAMMIN_Gateway` setup AP on `192.168.3.1`, ESP-NOW setup ingress for Lua-compatible `connReq`/`connAck`/`echo`/`cmd`/`data`/`uart` packets, native raw DALI frame forwarding back to connected setup peers, setup AP GPIO entry, and optional Wi-Fi credential reset GPIO handling, and an optional `gateway_485_control` bridge that claims UART0 for Lua-compatible framed command ingress plus `0x22` notification egress when the console is moved off UART0. Startup behavior is configured in `main/Kconfig.projbuild`: BLE and wired Ethernet are enabled by default, W5500 initialization and startup probe failures are ignored by default for boards without populated Ethernet hardware by fully disabling Ethernet for that boot, Wi-Fi STA, smartconfig, and ESP-NOW setup mode are disabled by default, the built-in USB Serial/JTAG interface stays in debug mode unless the optional USB setup bridge mode is selected, and the UART0 control bridge stays disabled unless the deployment explicitly repurposes UART0 away from the ESP-IDF console. Runtime settings and internal scene/group data are cached in RAM after load, skip unchanged flash writes, and batch Wi-Fi credential commits to reduce flash stalls on ESP32-S3 boards where flash and PSRAM share the SPI bus. The gateway app exposes per-channel PHY selection through `main/Kconfig.projbuild`; each channel can be disabled, bound to the native DALI GPIO HAL, or bound to a UART1/UART2 serial PHY. The checked-in `sdkconfig` is aligned with the app's custom 16 MB partition table so the Wi-Fi/BLE/network-enabled image fits the OTA app slots.
|
||||||
|
|
||||||
|
## KNX Security
|
||||||
|
|
||||||
|
KNX Data Secure and KNXnet/IP Secure support are controlled by `GATEWAY_KNX_DATA_SECURE_SUPPORTED` and `GATEWAY_KNX_IP_SECURE_SUPPORTED`. KNXnet/IP Secure now recognizes the secure service family, performs secure session setup/authentication with provisioned tunnel user keys, wraps secure tunnel responses, handles secure group-sync frames, and wraps/unpacks secure multicast routing frames when an OAM backbone key is active. The gateway derives its KNX serial identity from the ESP base MAC, and the development factory setup key is deterministically derived from that KNX serial so the same board keeps the same FDSK across NVS erases.
|
||||||
|
|
||||||
|
The shared KNXnet/IP endpoint can also be provisioned with an OAM-compatible IP-Router persona by enabling `GATEWAY_KNX_OAM_ROUTER_SUPPORTED` and the nested `knx.oamRouter` config. This second logical application is part of the same KNX/IP router endpoint: it does not open a second UDP/TCP listener and it does not own a second TP-UART driver. When OAM is enabled, KNXnet/IP search, description, tunnel, and multicast identity are advertised as the OAM IP router and follow the OAM individual address instead of a DALI-channel namespace. The gateway hosts a BAU091A/OAM router runtime beside the REG1-Dali BAU07B0 runtime, with separate individual/tunnel addresses, separate programming button/LED GPIOs, separate ETS/security storage, and a KNX serial derived from the ESP base MAC plus one. Secure tunnels are assigned to the OAM persona, and non-secure IP management/tunnel connections opened while OAM programming mode is active are also assigned to the OAM persona so ETS can modify and verify the OAM individual address. OAM-addressed management frames are dispatched to the BAU091A runtime while DALI group/function-property traffic stays on the REG1-Dali application. Physical TP ingress is brokered at the shared TP-UART owner: OAM-addressed TP telegrams and broadcast management telegrams are delivered to the matching local logical runtime, and OAM responses are transmitted through the same TP-UART and mirrored to KNXnet/IP once. Normal REG1-Dali TP group/application traffic remains on the existing REG1 data-link path so ETS group-object dispatch and DALI routing do not duplicate. The default OAM identity follows the OAM-IP-Router release database (`0x00FA` manufacturer, `0xA11F` application number, version `0x07`) unless overridden in Kconfig.
|
||||||
|
|
||||||
|
OAM IP Secure keyring preparation uses the `knx_oam_sec` NVS namespace. Development HTTP actions can read/generate/reset/export the OAM factory setup key and store already-extracted IP Secure keyring material (`backboneKeyHex`, tunnel user keys, and an optional device-authentication key). Stored OAM credentials are reported in `knx.security.oamRouter.ipSecureCredentials`; the tunnel user keys authenticate secure sessions and the backbone key protects secure routing/group-sync traffic. The routing sequence counter is persisted back to NVS after secure routing sends or authenticated sync updates.
|
||||||
|
|
||||||
|
Cloud KNX remote-access preparation is part of the `knx.oamRouter.cloudRemote` config. The status JSON reports the selected mode (`mqtt`, relay, or UDP punch-through-oriented deployments), whether secure tunnels are required, and whether relay endpoint, MQTT topic prefix, and token-reference fields are configured. The firmware does not start an external relay client yet; this config is the stable handoff surface for a future UDP relay/MQTT tunnel transport that will reuse the secure OAM tunnel path.
|
||||||
|
|
||||||
|
The KNXnet/IP tunnel can start from the built-in default configuration before any ETS download. KNX TP-UART is enabled only when `GATEWAY_KNX_TP_UART_PORT` is `0`, `1`, or `2`; set that UART port to `-1` for IP-only operation. UART TX/RX GPIO values of `-1` mean use the ESP-IDF target default pins for that UART, not disabled. `GATEWAY_KNX_TP_UART_9BIT_MODE` enables the NCN5120/OpenKNX-style 9-bit host frame on the wire, represented on ESP-IDF as 8 data bits plus even parity. Enable `GATEWAY_KNX_TP_FULL_IP_FORWARD` when the gateway must mirror all physical TP telegrams back out to KNXnet/IP tunnelling and multicast so ETS can monitor or download other TP devices through the gateway's IP endpoint. Local logical-device responses are de-duplicated by exact cEMI payload at the tunnel egress, so the same response is not replayed through tunnel, routing, and TP echo paths while distinct source addresses remain visible as separate devices. Non-UART GPIO options use `-1` as disabled, including the KNX programming button, KNX programming LED, setup AP button, Wi-Fi reset button, and status LED.
|
||||||
|
|
||||||
|
When no KNX bridge config or ETS application data has been downloaded, the KNXnet/IP router starts in commissioning mode: OpenKNX receives tunnel programming traffic from ETS, while DALI group routing and REG1-Dali function-property actions stay inactive until ETS reports a configured application.
|
||||||
|
|
||||||
|
The bridge service exposes one chip-level KNXnet/IP endpoint per physical gateway module on the configured UDP port. Per-channel DALI/KNX bridge runtimes keep their own group-address mappings behind that endpoint, and incoming group writes are dispatched to matching channel bridges instead of starting one UDP socket or multicast responder per DALI channel. If a non-owner channel router was already running, starting the shared endpoint stops it so KNXnet/IP search and description requests receive one response from the chip-level interface.
|
||||||
|
|
||||||
|
KNX programming mode can be controlled locally with `GATEWAY_KNX_PROGRAMMING_BUTTON_GPIO`, and `GATEWAY_KNX_PROGRAMMING_LED_GPIO` mirrors the current programming-mode state. The setup AP entry button is configured separately with `GATEWAY_SETUP_AP_BUTTON_GPIO`; Wi-Fi credential reset remains a separate long-press function on `GATEWAY_BOOT_BUTTON_GPIO` when enabled.
|
||||||
|
|
||||||
|
When the OAM router persona is enabled, use `GATEWAY_KNX_OAM_PROGRAMMING_BUTTON_GPIO` and `GATEWAY_KNX_OAM_PROGRAMMING_LED_GPIO` for its separate programming controls. The bridge config validator rejects duplicate REG1-Dali and OAM programming button or LED GPIO assignments so ETS programming-mode selection remains unambiguous.
|
||||||
|
|
||||||
|
When `GATEWAY_KNX_SECURITY_DEV_ENDPOINTS` is enabled, the bridge HTTP action surface exposes development-only operations for reading, writing, generating, and resetting the factory setup key, exporting the factory certificate payload, and clearing local KNX security failure diagnostics. These endpoints require explicit confirmation fields in the JSON body and should stay disabled in production builds. The default development storage mode is plain NVS via `GATEWAY_KNX_SECURITY_PLAIN_NVS`; production builds should replace that with encrypted NVS, flash encryption, and secure boot before handling real commissioning keys.
|
||||||
|
|
||||||
|
The normal bridge status response includes a `knx.security` object with compile-time capability flags, storage mode, factory setup key metadata, factory certificate metadata, and security failure counters/log entries. Secret FDSK strings are returned only by the explicit development actions, not by passive status polling.
|
||||||
|
|
||||||
## Modbus
|
## Modbus
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,2 @@
|
|||||||
|
CompileFlags:
|
||||||
|
Remove: [-f*, -m*]
|
||||||
+15
@@ -0,0 +1,15 @@
|
|||||||
|
{
|
||||||
|
"configurations": [
|
||||||
|
{
|
||||||
|
"name": "Mac",
|
||||||
|
"includePath": [
|
||||||
|
"${workspaceFolder}/**"
|
||||||
|
],
|
||||||
|
"defines": [],
|
||||||
|
"cStandard": "c17",
|
||||||
|
"cppStandard": "c++14",
|
||||||
|
"intelliSenseMode": "${default}"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"version": 4
|
||||||
|
}
|
||||||
Vendored
+13
@@ -0,0 +1,13 @@
|
|||||||
|
{
|
||||||
|
"idf.currentSetup": "/Users/tonylu/.espressif/v5.5.4/esp-idf",
|
||||||
|
"idf.customExtraVars": {
|
||||||
|
"OPENOCD_SCRIPTS": "/Users/tonylu/.espressif/tools/openocd-esp32/v0.12.0-esp32-20240318/openocd-esp32/share/openocd/scripts",
|
||||||
|
"ESP_ROM_ELF_DIR": "/Users/tonylu/.espressif/tools/esp-rom-elfs/20240305/"
|
||||||
|
},
|
||||||
|
"clangd.path": "/Users/tonylu/.espressif/tools/esp-clang/esp-19.1.2_20250312/esp-clang/bin/clangd",
|
||||||
|
"clangd.arguments": [
|
||||||
|
"--background-index",
|
||||||
|
"--query-driver=**",
|
||||||
|
"--compile-commands-dir=/Users/tonylu/StudioProjects/dalimaster/gateway/apps/gateway/build"
|
||||||
|
]
|
||||||
|
}
|
||||||
@@ -6,6 +6,7 @@ endif()
|
|||||||
|
|
||||||
set(EXTRA_COMPONENT_DIRS
|
set(EXTRA_COMPONENT_DIRS
|
||||||
"${CMAKE_CURRENT_LIST_DIR}/../../components"
|
"${CMAKE_CURRENT_LIST_DIR}/../../components"
|
||||||
|
"${CMAKE_CURRENT_LIST_DIR}/../../knx"
|
||||||
"${CMAKE_CURRENT_LIST_DIR}/../../../dali_cpp"
|
"${CMAKE_CURRENT_LIST_DIR}/../../../dali_cpp"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
+1789
-31
File diff suppressed because it is too large
Load Diff
+618
-149
@@ -12,9 +12,11 @@
|
|||||||
#include "esp_log.h"
|
#include "esp_log.h"
|
||||||
#include "sdkconfig.h"
|
#include "sdkconfig.h"
|
||||||
|
|
||||||
|
#include <array>
|
||||||
#include <cstdio>
|
#include <cstdio>
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
#ifndef CONFIG_GATEWAY_CHANNEL_COUNT
|
#ifndef CONFIG_GATEWAY_CHANNEL_COUNT
|
||||||
#define CONFIG_GATEWAY_CHANNEL_COUNT 2
|
#define CONFIG_GATEWAY_CHANNEL_COUNT 2
|
||||||
@@ -40,6 +42,21 @@
|
|||||||
#define CONFIG_GATEWAY_BOOT_BUTTON_LONG_PRESS_MS 3000
|
#define CONFIG_GATEWAY_BOOT_BUTTON_LONG_PRESS_MS 3000
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifndef CONFIG_GATEWAY_SETUP_AP_BUTTON_GPIO
|
||||||
|
#ifdef CONFIG_GATEWAY_BOOT_BUTTON_GPIO
|
||||||
|
#define CONFIG_GATEWAY_SETUP_AP_BUTTON_GPIO CONFIG_GATEWAY_BOOT_BUTTON_GPIO
|
||||||
|
#ifdef CONFIG_GATEWAY_BOOT_BUTTON_ACTIVE_LOW
|
||||||
|
#define CONFIG_GATEWAY_SETUP_AP_BUTTON_ACTIVE_LOW 1
|
||||||
|
#endif
|
||||||
|
#else
|
||||||
|
#define CONFIG_GATEWAY_SETUP_AP_BUTTON_GPIO -1
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef CONFIG_GATEWAY_BUTTON_TASK_STACK_SIZE
|
||||||
|
#define CONFIG_GATEWAY_BUTTON_TASK_STACK_SIZE 8192
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifndef CONFIG_GATEWAY_USB_SETUP_CHANNEL_INDEX
|
#ifndef CONFIG_GATEWAY_USB_SETUP_CHANNEL_INDEX
|
||||||
#define CONFIG_GATEWAY_USB_SETUP_CHANNEL_INDEX 0
|
#define CONFIG_GATEWAY_USB_SETUP_CHANNEL_INDEX 0
|
||||||
#endif
|
#endif
|
||||||
@@ -56,6 +73,10 @@
|
|||||||
#define CONFIG_GATEWAY_USB_SETUP_READ_TIMEOUT_MS 20
|
#define CONFIG_GATEWAY_USB_SETUP_READ_TIMEOUT_MS 20
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifndef CONFIG_DALI_BUS_RESET_PULSE_MS
|
||||||
|
#define CONFIG_DALI_BUS_RESET_PULSE_MS 10
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifndef CONFIG_GATEWAY_485_CONTROL_BAUDRATE
|
#ifndef CONFIG_GATEWAY_485_CONTROL_BAUDRATE
|
||||||
#define CONFIG_GATEWAY_485_CONTROL_BAUDRATE 9600
|
#define CONFIG_GATEWAY_485_CONTROL_BAUDRATE 9600
|
||||||
#endif
|
#endif
|
||||||
@@ -92,10 +113,66 @@
|
|||||||
#define CONFIG_GATEWAY_485_CONTROL_TASK_PRIORITY 4
|
#define CONFIG_GATEWAY_485_CONTROL_TASK_PRIORITY 4
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifndef CONFIG_GATEWAY_KNX_TP_STARTUP_TIMEOUT_MS
|
||||||
|
#define CONFIG_GATEWAY_KNX_TP_STARTUP_TIMEOUT_MS 2000
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifndef CONFIG_GATEWAY_SMARTCONFIG_TIMEOUT_SEC
|
#ifndef CONFIG_GATEWAY_SMARTCONFIG_TIMEOUT_SEC
|
||||||
#define CONFIG_GATEWAY_SMARTCONFIG_TIMEOUT_SEC 60
|
#define CONFIG_GATEWAY_SMARTCONFIG_TIMEOUT_SEC 60
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifndef CONFIG_GATEWAY_ETHERNET_IGNORE_INIT_FAILURE
|
||||||
|
#define CONFIG_GATEWAY_ETHERNET_IGNORE_INIT_FAILURE 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef CONFIG_GATEWAY_ETHERNET_W5500_SPI_HOST
|
||||||
|
#define CONFIG_GATEWAY_ETHERNET_W5500_SPI_HOST 1
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef CONFIG_GATEWAY_ETHERNET_W5500_SCLK_GPIO
|
||||||
|
#define CONFIG_GATEWAY_ETHERNET_W5500_SCLK_GPIO 14
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef CONFIG_GATEWAY_ETHERNET_W5500_MOSI_GPIO
|
||||||
|
#define CONFIG_GATEWAY_ETHERNET_W5500_MOSI_GPIO 13
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef CONFIG_GATEWAY_ETHERNET_W5500_MISO_GPIO
|
||||||
|
#define CONFIG_GATEWAY_ETHERNET_W5500_MISO_GPIO 12
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef CONFIG_GATEWAY_ETHERNET_W5500_CS_GPIO
|
||||||
|
#define CONFIG_GATEWAY_ETHERNET_W5500_CS_GPIO 15
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef CONFIG_GATEWAY_ETHERNET_W5500_INT_GPIO
|
||||||
|
#define CONFIG_GATEWAY_ETHERNET_W5500_INT_GPIO 4
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef CONFIG_GATEWAY_ETHERNET_W5500_POLL_PERIOD_MS
|
||||||
|
#define CONFIG_GATEWAY_ETHERNET_W5500_POLL_PERIOD_MS 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef CONFIG_GATEWAY_ETHERNET_W5500_CLOCK_MHZ
|
||||||
|
#define CONFIG_GATEWAY_ETHERNET_W5500_CLOCK_MHZ 36
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef CONFIG_GATEWAY_ETHERNET_PHY_RESET_GPIO
|
||||||
|
#define CONFIG_GATEWAY_ETHERNET_PHY_RESET_GPIO 5
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef CONFIG_GATEWAY_ETHERNET_PHY_ADDR
|
||||||
|
#define CONFIG_GATEWAY_ETHERNET_PHY_ADDR 1
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef CONFIG_GATEWAY_ETHERNET_RX_TASK_STACK_SIZE
|
||||||
|
#define CONFIG_GATEWAY_ETHERNET_RX_TASK_STACK_SIZE 3072
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef CONFIG_GATEWAY_CONTROLLER_TASK_STACK_SIZE
|
||||||
|
#define CONFIG_GATEWAY_CONTROLLER_TASK_STACK_SIZE 12288
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifndef CONFIG_GATEWAY_BRIDGE_MODBUS_TASK_STACK_SIZE
|
#ifndef CONFIG_GATEWAY_BRIDGE_MODBUS_TASK_STACK_SIZE
|
||||||
#define CONFIG_GATEWAY_BRIDGE_MODBUS_TASK_STACK_SIZE 6144
|
#define CONFIG_GATEWAY_BRIDGE_MODBUS_TASK_STACK_SIZE 6144
|
||||||
#endif
|
#endif
|
||||||
@@ -145,7 +222,7 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef CONFIG_GATEWAY_BRIDGE_KNX_TASK_STACK_SIZE
|
#ifndef CONFIG_GATEWAY_BRIDGE_KNX_TASK_STACK_SIZE
|
||||||
#define CONFIG_GATEWAY_BRIDGE_KNX_TASK_STACK_SIZE 8192
|
#define CONFIG_GATEWAY_BRIDGE_KNX_TASK_STACK_SIZE 12288
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef CONFIG_GATEWAY_BRIDGE_KNX_TASK_PRIORITY
|
#ifndef CONFIG_GATEWAY_BRIDGE_KNX_TASK_PRIORITY
|
||||||
@@ -156,6 +233,10 @@
|
|||||||
#define CONFIG_GATEWAY_KNX_MAIN_GROUP 0
|
#define CONFIG_GATEWAY_KNX_MAIN_GROUP 0
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifndef CONFIG_GATEWAY_KNX_DALI_BUS_ID
|
||||||
|
#define CONFIG_GATEWAY_KNX_DALI_BUS_ID 0
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifndef CONFIG_GATEWAY_KNX_UDP_PORT
|
#ifndef CONFIG_GATEWAY_KNX_UDP_PORT
|
||||||
#define CONFIG_GATEWAY_KNX_UDP_PORT 3671
|
#define CONFIG_GATEWAY_KNX_UDP_PORT 3671
|
||||||
#endif
|
#endif
|
||||||
@@ -165,11 +246,39 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef CONFIG_GATEWAY_KNX_INDIVIDUAL_ADDRESS
|
#ifndef CONFIG_GATEWAY_KNX_INDIVIDUAL_ADDRESS
|
||||||
#define CONFIG_GATEWAY_KNX_INDIVIDUAL_ADDRESS 4353
|
#define CONFIG_GATEWAY_KNX_INDIVIDUAL_ADDRESS 65534
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef CONFIG_GATEWAY_KNX_IP_INTERFACE_INDIVIDUAL_ADDRESS
|
||||||
|
#define CONFIG_GATEWAY_KNX_IP_INTERFACE_INDIVIDUAL_ADDRESS 65281
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef CONFIG_GATEWAY_KNX_OAM_ROUTER_INDIVIDUAL_ADDRESS
|
||||||
|
#define CONFIG_GATEWAY_KNX_OAM_ROUTER_INDIVIDUAL_ADDRESS 65282
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef CONFIG_GATEWAY_KNX_OAM_ROUTER_TUNNEL_ADDRESS_BASE
|
||||||
|
#define CONFIG_GATEWAY_KNX_OAM_ROUTER_TUNNEL_ADDRESS_BASE 65296
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef CONFIG_GATEWAY_KNX_OAM_PROGRAMMING_BUTTON_GPIO
|
||||||
|
#define CONFIG_GATEWAY_KNX_OAM_PROGRAMMING_BUTTON_GPIO -1
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef CONFIG_GATEWAY_KNX_OAM_PROGRAMMING_LED_GPIO
|
||||||
|
#define CONFIG_GATEWAY_KNX_OAM_PROGRAMMING_LED_GPIO -1
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef CONFIG_GATEWAY_KNX_PROGRAMMING_BUTTON_GPIO
|
||||||
|
#define CONFIG_GATEWAY_KNX_PROGRAMMING_BUTTON_GPIO -1
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef CONFIG_GATEWAY_KNX_PROGRAMMING_LED_GPIO
|
||||||
|
#define CONFIG_GATEWAY_KNX_PROGRAMMING_LED_GPIO -1
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef CONFIG_GATEWAY_KNX_TP_UART_PORT
|
#ifndef CONFIG_GATEWAY_KNX_TP_UART_PORT
|
||||||
#define CONFIG_GATEWAY_KNX_TP_UART_PORT 1
|
#define CONFIG_GATEWAY_KNX_TP_UART_PORT -1
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef CONFIG_GATEWAY_KNX_TP_TX_PIN
|
#ifndef CONFIG_GATEWAY_KNX_TP_TX_PIN
|
||||||
@@ -185,7 +294,11 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef CONFIG_GATEWAY_CACHE_FLUSH_INTERVAL_MS
|
#ifndef CONFIG_GATEWAY_CACHE_FLUSH_INTERVAL_MS
|
||||||
#define CONFIG_GATEWAY_CACHE_FLUSH_INTERVAL_MS 5000
|
#define CONFIG_GATEWAY_CACHE_FLUSH_INTERVAL_MS 10000
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef CONFIG_GATEWAY_CACHE_REFRESH_INTERVAL_MS
|
||||||
|
#define CONFIG_GATEWAY_CACHE_REFRESH_INTERVAL_MS 120000
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
@@ -199,12 +312,24 @@ constexpr bool kWifiSupported = true;
|
|||||||
constexpr bool kWifiSupported = false;
|
constexpr bool kWifiSupported = false;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef CONFIG_GATEWAY_ETHERNET_SUPPORTED
|
||||||
|
constexpr bool kEthernetSupported = true;
|
||||||
|
#else
|
||||||
|
constexpr bool kEthernetSupported = false;
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef CONFIG_GATEWAY_START_WIFI_STA_ENABLED
|
#ifdef CONFIG_GATEWAY_START_WIFI_STA_ENABLED
|
||||||
constexpr bool kWifiStartupEnabled = true;
|
constexpr bool kWifiStartupEnabled = true;
|
||||||
#else
|
#else
|
||||||
constexpr bool kWifiStartupEnabled = false;
|
constexpr bool kWifiStartupEnabled = false;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef CONFIG_GATEWAY_START_ETHERNET_ENABLED
|
||||||
|
constexpr bool kEthernetStartupEnabled = true;
|
||||||
|
#else
|
||||||
|
constexpr bool kEthernetStartupEnabled = false;
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef CONFIG_GATEWAY_BLE_SUPPORTED
|
#ifdef CONFIG_GATEWAY_BLE_SUPPORTED
|
||||||
constexpr bool kBleSupported = true;
|
constexpr bool kBleSupported = true;
|
||||||
#else
|
#else
|
||||||
@@ -301,6 +426,18 @@ constexpr bool kKnxMulticastEnabled = true;
|
|||||||
constexpr bool kKnxMulticastEnabled = false;
|
constexpr bool kKnxMulticastEnabled = false;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef CONFIG_GATEWAY_KNX_OAM_ROUTER_SUPPORTED
|
||||||
|
constexpr bool kKnxOamRouterSupported = true;
|
||||||
|
#else
|
||||||
|
constexpr bool kKnxOamRouterSupported = false;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef CONFIG_GATEWAY_KNX_OAM_ROUTER_ENABLED
|
||||||
|
constexpr bool kKnxOamRouterEnabled = true;
|
||||||
|
#else
|
||||||
|
constexpr bool kKnxOamRouterEnabled = false;
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef CONFIG_GATEWAY_CLOUD_BRIDGE_SUPPORTED
|
#ifdef CONFIG_GATEWAY_CLOUD_BRIDGE_SUPPORTED
|
||||||
constexpr bool kCloudBridgeSupported = true;
|
constexpr bool kCloudBridgeSupported = true;
|
||||||
#else
|
#else
|
||||||
@@ -398,57 +535,245 @@ struct ChannelBindingConfig {
|
|||||||
bool enabled{false};
|
bool enabled{false};
|
||||||
bool native_phy{false};
|
bool native_phy{false};
|
||||||
bool serial_phy{false};
|
bool serial_phy{false};
|
||||||
|
uint8_t channel_index{0};
|
||||||
uint8_t gateway_id{0};
|
uint8_t gateway_id{0};
|
||||||
uint8_t native_bus_id{0};
|
uint8_t native_bus_id{0};
|
||||||
uint32_t native_baudrate{0};
|
uint32_t native_baudrate{0};
|
||||||
|
int native_tx_pin{-1};
|
||||||
|
int native_rx_pin{-1};
|
||||||
int uart_port{-1};
|
int uart_port{-1};
|
||||||
|
int serial_tx_pin{-1};
|
||||||
|
int serial_rx_pin{-1};
|
||||||
|
uint32_t serial_baudrate{0};
|
||||||
|
size_t serial_rx_buffer_size{0};
|
||||||
|
size_t serial_tx_buffer_size{0};
|
||||||
|
uint32_t serial_query_timeout_ms{0};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
ChannelBindingConfig NativeChannelConfig(uint8_t channel_index, uint8_t gateway_id,
|
||||||
|
uint8_t bus_id, int tx_pin, int rx_pin,
|
||||||
|
uint32_t baudrate) {
|
||||||
|
ChannelBindingConfig channel{};
|
||||||
|
channel.enabled = true;
|
||||||
|
channel.native_phy = true;
|
||||||
|
channel.channel_index = channel_index;
|
||||||
|
channel.gateway_id = gateway_id;
|
||||||
|
channel.native_bus_id = bus_id;
|
||||||
|
channel.native_tx_pin = tx_pin;
|
||||||
|
channel.native_rx_pin = rx_pin;
|
||||||
|
channel.native_baudrate = baudrate;
|
||||||
|
return channel;
|
||||||
|
}
|
||||||
|
|
||||||
|
[[maybe_unused]] ChannelBindingConfig SerialChannelConfig(uint8_t channel_index, uint8_t gateway_id,
|
||||||
|
int uart_port, int tx_pin, int rx_pin,
|
||||||
|
uint32_t baudrate, size_t rx_buffer_size,
|
||||||
|
size_t tx_buffer_size,
|
||||||
|
uint32_t query_timeout_ms) {
|
||||||
|
ChannelBindingConfig channel{};
|
||||||
|
channel.enabled = true;
|
||||||
|
channel.serial_phy = true;
|
||||||
|
channel.channel_index = channel_index;
|
||||||
|
channel.gateway_id = gateway_id;
|
||||||
|
channel.uart_port = uart_port;
|
||||||
|
channel.serial_tx_pin = tx_pin;
|
||||||
|
channel.serial_rx_pin = rx_pin;
|
||||||
|
channel.serial_baudrate = baudrate;
|
||||||
|
channel.serial_rx_buffer_size = rx_buffer_size;
|
||||||
|
channel.serial_tx_buffer_size = tx_buffer_size;
|
||||||
|
channel.serial_query_timeout_ms = query_timeout_ms;
|
||||||
|
return channel;
|
||||||
|
}
|
||||||
|
|
||||||
|
#define GATEWAY_CONFIGURE_NATIVE_CHANNEL(slot, number) \
|
||||||
|
channels[slot] = NativeChannelConfig( \
|
||||||
|
static_cast<uint8_t>(slot), static_cast<uint8_t>(CONFIG_GATEWAY_CHANNEL##number##_GW_ID), \
|
||||||
|
static_cast<uint8_t>(CONFIG_GATEWAY_CHANNEL##number##_NATIVE_BUS_ID), \
|
||||||
|
CONFIG_GATEWAY_CHANNEL##number##_NATIVE_TX_PIN, \
|
||||||
|
CONFIG_GATEWAY_CHANNEL##number##_NATIVE_RX_PIN, \
|
||||||
|
static_cast<uint32_t>(CONFIG_GATEWAY_CHANNEL##number##_NATIVE_BAUDRATE))
|
||||||
|
|
||||||
|
#define GATEWAY_CONFIGURE_SERIAL_CHANNEL(slot, number, uart) \
|
||||||
|
channels[slot] = SerialChannelConfig( \
|
||||||
|
static_cast<uint8_t>(slot), static_cast<uint8_t>(CONFIG_GATEWAY_CHANNEL##number##_GW_ID), \
|
||||||
|
uart, CONFIG_GATEWAY_CHANNEL##number##_SERIAL_TX_PIN, \
|
||||||
|
CONFIG_GATEWAY_CHANNEL##number##_SERIAL_RX_PIN, \
|
||||||
|
static_cast<uint32_t>(CONFIG_GATEWAY_CHANNEL##number##_SERIAL_BAUDRATE), \
|
||||||
|
static_cast<size_t>(CONFIG_GATEWAY_CHANNEL##number##_SERIAL_RX_BUFFER), \
|
||||||
|
static_cast<size_t>(CONFIG_GATEWAY_CHANNEL##number##_SERIAL_TX_BUFFER), \
|
||||||
|
static_cast<uint32_t>(CONFIG_GATEWAY_CHANNEL##number##_SERIAL_QUERY_TIMEOUT_MS))
|
||||||
|
|
||||||
|
std::array<ChannelBindingConfig, CONFIG_GATEWAY_CHANNEL_COUNT> BuildChannelBindings() {
|
||||||
|
std::array<ChannelBindingConfig, CONFIG_GATEWAY_CHANNEL_COUNT> channels{};
|
||||||
|
|
||||||
|
#if CONFIG_GATEWAY_CHANNEL1_PHY_NATIVE
|
||||||
|
GATEWAY_CONFIGURE_NATIVE_CHANNEL(0, 1);
|
||||||
|
#elif CONFIG_GATEWAY_CHANNEL1_PHY_UART1
|
||||||
|
GATEWAY_CONFIGURE_SERIAL_CHANNEL(0, 1, 1);
|
||||||
|
#elif CONFIG_GATEWAY_CHANNEL1_PHY_UART2
|
||||||
|
GATEWAY_CONFIGURE_SERIAL_CHANNEL(0, 1, 2);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if CONFIG_GATEWAY_CHANNEL_COUNT >= 2
|
||||||
|
#if CONFIG_GATEWAY_CHANNEL2_PHY_NATIVE
|
||||||
|
GATEWAY_CONFIGURE_NATIVE_CHANNEL(1, 2);
|
||||||
|
#elif CONFIG_GATEWAY_CHANNEL2_PHY_UART1
|
||||||
|
GATEWAY_CONFIGURE_SERIAL_CHANNEL(1, 2, 1);
|
||||||
|
#elif CONFIG_GATEWAY_CHANNEL2_PHY_UART2
|
||||||
|
GATEWAY_CONFIGURE_SERIAL_CHANNEL(1, 2, 2);
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if CONFIG_GATEWAY_CHANNEL_COUNT >= 3
|
||||||
|
#if CONFIG_GATEWAY_CHANNEL3_PHY_NATIVE
|
||||||
|
GATEWAY_CONFIGURE_NATIVE_CHANNEL(2, 3);
|
||||||
|
#elif CONFIG_GATEWAY_CHANNEL3_PHY_UART1
|
||||||
|
GATEWAY_CONFIGURE_SERIAL_CHANNEL(2, 3, 1);
|
||||||
|
#elif CONFIG_GATEWAY_CHANNEL3_PHY_UART2
|
||||||
|
GATEWAY_CONFIGURE_SERIAL_CHANNEL(2, 3, 2);
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if CONFIG_GATEWAY_CHANNEL_COUNT >= 4
|
||||||
|
#if CONFIG_GATEWAY_CHANNEL4_PHY_NATIVE
|
||||||
|
GATEWAY_CONFIGURE_NATIVE_CHANNEL(3, 4);
|
||||||
|
#elif CONFIG_GATEWAY_CHANNEL4_PHY_UART1
|
||||||
|
GATEWAY_CONFIGURE_SERIAL_CHANNEL(3, 4, 1);
|
||||||
|
#elif CONFIG_GATEWAY_CHANNEL4_PHY_UART2
|
||||||
|
GATEWAY_CONFIGURE_SERIAL_CHANNEL(3, 4, 2);
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if CONFIG_GATEWAY_CHANNEL_COUNT >= 5
|
||||||
|
#if CONFIG_GATEWAY_CHANNEL5_PHY_NATIVE
|
||||||
|
GATEWAY_CONFIGURE_NATIVE_CHANNEL(4, 5);
|
||||||
|
#elif CONFIG_GATEWAY_CHANNEL5_PHY_UART1
|
||||||
|
GATEWAY_CONFIGURE_SERIAL_CHANNEL(4, 5, 1);
|
||||||
|
#elif CONFIG_GATEWAY_CHANNEL5_PHY_UART2
|
||||||
|
GATEWAY_CONFIGURE_SERIAL_CHANNEL(4, 5, 2);
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if CONFIG_GATEWAY_CHANNEL_COUNT >= 6
|
||||||
|
#if CONFIG_GATEWAY_CHANNEL6_PHY_NATIVE
|
||||||
|
GATEWAY_CONFIGURE_NATIVE_CHANNEL(5, 6);
|
||||||
|
#elif CONFIG_GATEWAY_CHANNEL6_PHY_UART1
|
||||||
|
GATEWAY_CONFIGURE_SERIAL_CHANNEL(5, 6, 1);
|
||||||
|
#elif CONFIG_GATEWAY_CHANNEL6_PHY_UART2
|
||||||
|
GATEWAY_CONFIGURE_SERIAL_CHANNEL(5, 6, 2);
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if CONFIG_GATEWAY_CHANNEL_COUNT >= 7
|
||||||
|
#if CONFIG_GATEWAY_CHANNEL7_PHY_NATIVE
|
||||||
|
GATEWAY_CONFIGURE_NATIVE_CHANNEL(6, 7);
|
||||||
|
#elif CONFIG_GATEWAY_CHANNEL7_PHY_UART1
|
||||||
|
GATEWAY_CONFIGURE_SERIAL_CHANNEL(6, 7, 1);
|
||||||
|
#elif CONFIG_GATEWAY_CHANNEL7_PHY_UART2
|
||||||
|
GATEWAY_CONFIGURE_SERIAL_CHANNEL(6, 7, 2);
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if CONFIG_GATEWAY_CHANNEL_COUNT >= 8
|
||||||
|
#if CONFIG_GATEWAY_CHANNEL8_PHY_NATIVE
|
||||||
|
GATEWAY_CONFIGURE_NATIVE_CHANNEL(7, 8);
|
||||||
|
#elif CONFIG_GATEWAY_CHANNEL8_PHY_UART1
|
||||||
|
GATEWAY_CONFIGURE_SERIAL_CHANNEL(7, 8, 1);
|
||||||
|
#elif CONFIG_GATEWAY_CHANNEL8_PHY_UART2
|
||||||
|
GATEWAY_CONFIGURE_SERIAL_CHANNEL(7, 8, 2);
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if CONFIG_GATEWAY_CHANNEL_COUNT >= 9
|
||||||
|
#if CONFIG_GATEWAY_CHANNEL9_PHY_NATIVE
|
||||||
|
GATEWAY_CONFIGURE_NATIVE_CHANNEL(8, 9);
|
||||||
|
#elif CONFIG_GATEWAY_CHANNEL9_PHY_UART1
|
||||||
|
GATEWAY_CONFIGURE_SERIAL_CHANNEL(8, 9, 1);
|
||||||
|
#elif CONFIG_GATEWAY_CHANNEL9_PHY_UART2
|
||||||
|
GATEWAY_CONFIGURE_SERIAL_CHANNEL(8, 9, 2);
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if CONFIG_GATEWAY_CHANNEL_COUNT >= 10
|
||||||
|
#if CONFIG_GATEWAY_CHANNEL10_PHY_NATIVE
|
||||||
|
GATEWAY_CONFIGURE_NATIVE_CHANNEL(9, 10);
|
||||||
|
#elif CONFIG_GATEWAY_CHANNEL10_PHY_UART1
|
||||||
|
GATEWAY_CONFIGURE_SERIAL_CHANNEL(9, 10, 1);
|
||||||
|
#elif CONFIG_GATEWAY_CHANNEL10_PHY_UART2
|
||||||
|
GATEWAY_CONFIGURE_SERIAL_CHANNEL(9, 10, 2);
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if CONFIG_GATEWAY_CHANNEL_COUNT >= 11
|
||||||
|
#if CONFIG_GATEWAY_CHANNEL11_PHY_NATIVE
|
||||||
|
GATEWAY_CONFIGURE_NATIVE_CHANNEL(10, 11);
|
||||||
|
#elif CONFIG_GATEWAY_CHANNEL11_PHY_UART1
|
||||||
|
GATEWAY_CONFIGURE_SERIAL_CHANNEL(10, 11, 1);
|
||||||
|
#elif CONFIG_GATEWAY_CHANNEL11_PHY_UART2
|
||||||
|
GATEWAY_CONFIGURE_SERIAL_CHANNEL(10, 11, 2);
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if CONFIG_GATEWAY_CHANNEL_COUNT >= 12
|
||||||
|
#if CONFIG_GATEWAY_CHANNEL12_PHY_NATIVE
|
||||||
|
GATEWAY_CONFIGURE_NATIVE_CHANNEL(11, 12);
|
||||||
|
#elif CONFIG_GATEWAY_CHANNEL12_PHY_UART1
|
||||||
|
GATEWAY_CONFIGURE_SERIAL_CHANNEL(11, 12, 1);
|
||||||
|
#elif CONFIG_GATEWAY_CHANNEL12_PHY_UART2
|
||||||
|
GATEWAY_CONFIGURE_SERIAL_CHANNEL(11, 12, 2);
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if CONFIG_GATEWAY_CHANNEL_COUNT >= 13
|
||||||
|
#if CONFIG_GATEWAY_CHANNEL13_PHY_NATIVE
|
||||||
|
GATEWAY_CONFIGURE_NATIVE_CHANNEL(12, 13);
|
||||||
|
#elif CONFIG_GATEWAY_CHANNEL13_PHY_UART1
|
||||||
|
GATEWAY_CONFIGURE_SERIAL_CHANNEL(12, 13, 1);
|
||||||
|
#elif CONFIG_GATEWAY_CHANNEL13_PHY_UART2
|
||||||
|
GATEWAY_CONFIGURE_SERIAL_CHANNEL(12, 13, 2);
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if CONFIG_GATEWAY_CHANNEL_COUNT >= 14
|
||||||
|
#if CONFIG_GATEWAY_CHANNEL14_PHY_NATIVE
|
||||||
|
GATEWAY_CONFIGURE_NATIVE_CHANNEL(13, 14);
|
||||||
|
#elif CONFIG_GATEWAY_CHANNEL14_PHY_UART1
|
||||||
|
GATEWAY_CONFIGURE_SERIAL_CHANNEL(13, 14, 1);
|
||||||
|
#elif CONFIG_GATEWAY_CHANNEL14_PHY_UART2
|
||||||
|
GATEWAY_CONFIGURE_SERIAL_CHANNEL(13, 14, 2);
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if CONFIG_GATEWAY_CHANNEL_COUNT >= 15
|
||||||
|
#if CONFIG_GATEWAY_CHANNEL15_PHY_NATIVE
|
||||||
|
GATEWAY_CONFIGURE_NATIVE_CHANNEL(14, 15);
|
||||||
|
#elif CONFIG_GATEWAY_CHANNEL15_PHY_UART1
|
||||||
|
GATEWAY_CONFIGURE_SERIAL_CHANNEL(14, 15, 1);
|
||||||
|
#elif CONFIG_GATEWAY_CHANNEL15_PHY_UART2
|
||||||
|
GATEWAY_CONFIGURE_SERIAL_CHANNEL(14, 15, 2);
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if CONFIG_GATEWAY_CHANNEL_COUNT >= 16
|
||||||
|
#if CONFIG_GATEWAY_CHANNEL16_PHY_NATIVE
|
||||||
|
GATEWAY_CONFIGURE_NATIVE_CHANNEL(15, 16);
|
||||||
|
#elif CONFIG_GATEWAY_CHANNEL16_PHY_UART1
|
||||||
|
GATEWAY_CONFIGURE_SERIAL_CHANNEL(15, 16, 1);
|
||||||
|
#elif CONFIG_GATEWAY_CHANNEL16_PHY_UART2
|
||||||
|
GATEWAY_CONFIGURE_SERIAL_CHANNEL(15, 16, 2);
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return channels;
|
||||||
|
}
|
||||||
|
|
||||||
bool ValidateChannelBindings() {
|
bool ValidateChannelBindings() {
|
||||||
if (k485ControlEnabled && kConsoleOnUart0) {
|
if (k485ControlEnabled && kConsoleOnUart0) {
|
||||||
ESP_LOGE(kTag, "485 control bridge requires moving the ESP-IDF console off UART0");
|
ESP_LOGE(kTag, "485 control bridge requires moving the ESP-IDF console off UART0");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
ChannelBindingConfig channels[CONFIG_GATEWAY_CHANNEL_COUNT] = {};
|
const auto channels = BuildChannelBindings();
|
||||||
|
|
||||||
#if CONFIG_GATEWAY_CHANNEL1_PHY_NATIVE
|
|
||||||
channels[0].enabled = true;
|
|
||||||
channels[0].native_phy = true;
|
|
||||||
channels[0].gateway_id = static_cast<uint8_t>(CONFIG_GATEWAY_CHANNEL1_GW_ID);
|
|
||||||
channels[0].native_bus_id = static_cast<uint8_t>(CONFIG_GATEWAY_CHANNEL1_NATIVE_BUS_ID);
|
|
||||||
channels[0].native_baudrate = static_cast<uint32_t>(CONFIG_GATEWAY_CHANNEL1_NATIVE_BAUDRATE);
|
|
||||||
#elif CONFIG_GATEWAY_CHANNEL1_PHY_UART1
|
|
||||||
channels[0].enabled = true;
|
|
||||||
channels[0].serial_phy = true;
|
|
||||||
channels[0].gateway_id = static_cast<uint8_t>(CONFIG_GATEWAY_CHANNEL1_GW_ID);
|
|
||||||
channels[0].uart_port = 1;
|
|
||||||
#elif CONFIG_GATEWAY_CHANNEL1_PHY_UART2
|
|
||||||
channels[0].enabled = true;
|
|
||||||
channels[0].serial_phy = true;
|
|
||||||
channels[0].gateway_id = static_cast<uint8_t>(CONFIG_GATEWAY_CHANNEL1_GW_ID);
|
|
||||||
channels[0].uart_port = 2;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if CONFIG_GATEWAY_CHANNEL_COUNT >= 2
|
|
||||||
#if CONFIG_GATEWAY_CHANNEL2_PHY_NATIVE
|
|
||||||
channels[1].enabled = true;
|
|
||||||
channels[1].native_phy = true;
|
|
||||||
channels[1].gateway_id = static_cast<uint8_t>(CONFIG_GATEWAY_CHANNEL2_GW_ID);
|
|
||||||
channels[1].native_bus_id = static_cast<uint8_t>(CONFIG_GATEWAY_CHANNEL2_NATIVE_BUS_ID);
|
|
||||||
channels[1].native_baudrate = static_cast<uint32_t>(CONFIG_GATEWAY_CHANNEL2_NATIVE_BAUDRATE);
|
|
||||||
#elif CONFIG_GATEWAY_CHANNEL2_PHY_UART1
|
|
||||||
channels[1].enabled = true;
|
|
||||||
channels[1].serial_phy = true;
|
|
||||||
channels[1].gateway_id = static_cast<uint8_t>(CONFIG_GATEWAY_CHANNEL2_GW_ID);
|
|
||||||
channels[1].uart_port = 1;
|
|
||||||
#elif CONFIG_GATEWAY_CHANNEL2_PHY_UART2
|
|
||||||
channels[1].enabled = true;
|
|
||||||
channels[1].serial_phy = true;
|
|
||||||
channels[1].gateway_id = static_cast<uint8_t>(CONFIG_GATEWAY_CHANNEL2_GW_ID);
|
|
||||||
channels[1].uart_port = 2;
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
bool any_enabled = false;
|
bool any_enabled = false;
|
||||||
bool saw_native = false;
|
bool saw_native = false;
|
||||||
@@ -459,6 +784,11 @@ bool ValidateChannelBindings() {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
any_enabled = true;
|
any_enabled = true;
|
||||||
|
if (channels[i].native_phy &&
|
||||||
|
(channels[i].native_tx_pin < 0 || channels[i].native_rx_pin < 0)) {
|
||||||
|
ESP_LOGE(kTag, "native DALI channel %d requires TX and RX GPIO pins", i + 1);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
for (int j = i + 1; j < CONFIG_GATEWAY_CHANNEL_COUNT; ++j) {
|
for (int j = i + 1; j < CONFIG_GATEWAY_CHANNEL_COUNT; ++j) {
|
||||||
if (!channels[j].enabled) {
|
if (!channels[j].enabled) {
|
||||||
continue;
|
continue;
|
||||||
@@ -504,6 +834,10 @@ bool ValidateChannelBindings() {
|
|||||||
ESP_LOGE(kTag, "Modbus serial is configured on UART0, but UART0 is reserved for console");
|
ESP_LOGE(kTag, "Modbus serial is configured on UART0, but UART0 is reserved for console");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
if (modbus_uart == 0 && kConsoleOnUart0) {
|
||||||
|
ESP_LOGE(kTag, "Modbus serial UART0 requires moving the ESP-IDF console off UART0");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
for (int i = 0; i < CONFIG_GATEWAY_CHANNEL_COUNT; ++i) {
|
for (int i = 0; i < CONFIG_GATEWAY_CHANNEL_COUNT; ++i) {
|
||||||
if (channels[i].enabled && channels[i].serial_phy && channels[i].uart_port == modbus_uart) {
|
if (channels[i].enabled && channels[i].serial_phy && channels[i].uart_port == modbus_uart) {
|
||||||
ESP_LOGE(kTag, "Modbus serial UART%d conflicts with DALI channel %d serial PHY",
|
ESP_LOGE(kTag, "Modbus serial UART%d conflicts with DALI channel %d serial PHY",
|
||||||
@@ -515,17 +849,38 @@ bool ValidateChannelBindings() {
|
|||||||
|
|
||||||
if (kKnxBridgeSupported) {
|
if (kKnxBridgeSupported) {
|
||||||
const int knx_uart = CONFIG_GATEWAY_KNX_TP_UART_PORT;
|
const int knx_uart = CONFIG_GATEWAY_KNX_TP_UART_PORT;
|
||||||
if (k485ControlEnabled && knx_uart == 0) {
|
if (kKnxBridgeStartupEnabled) {
|
||||||
|
const uint8_t knx_dali_bus_id = static_cast<uint8_t>(CONFIG_GATEWAY_KNX_DALI_BUS_ID);
|
||||||
|
int matches = 0;
|
||||||
|
for (int i = 0; i < CONFIG_GATEWAY_CHANNEL_COUNT; ++i) {
|
||||||
|
if (channels[i].enabled && channels[i].native_phy &&
|
||||||
|
channels[i].native_bus_id == knx_dali_bus_id) {
|
||||||
|
++matches;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (matches != 1) {
|
||||||
|
ESP_LOGE(kTag,
|
||||||
|
"KNX DALI bus id %u must match exactly one enabled native DALI channel",
|
||||||
|
knx_dali_bus_id);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (knx_uart >= 0 && k485ControlEnabled && knx_uart == 0) {
|
||||||
ESP_LOGE(kTag, "KNX TP UART0 conflicts with the UART0 control bridge");
|
ESP_LOGE(kTag, "KNX TP UART0 conflicts with the UART0 control bridge");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (kModbusBridgeSupported && kModbusDefaultSerialTransport &&
|
if (knx_uart >= 0 && knx_uart == 0 && kConsoleOnUart0) {
|
||||||
|
ESP_LOGE(kTag, "KNX TP-UART on UART0 requires moving the ESP-IDF console off UART0");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (knx_uart >= 0 && kModbusBridgeSupported && kModbusDefaultSerialTransport &&
|
||||||
knx_uart == CONFIG_GATEWAY_MODBUS_SERIAL_UART_PORT) {
|
knx_uart == CONFIG_GATEWAY_MODBUS_SERIAL_UART_PORT) {
|
||||||
ESP_LOGE(kTag, "KNX TP UART%d conflicts with default Modbus serial UART", knx_uart);
|
ESP_LOGE(kTag, "KNX TP UART%d conflicts with default Modbus serial UART", knx_uart);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
for (int i = 0; i < CONFIG_GATEWAY_CHANNEL_COUNT; ++i) {
|
for (int i = 0; i < CONFIG_GATEWAY_CHANNEL_COUNT; ++i) {
|
||||||
if (channels[i].enabled && channels[i].serial_phy && channels[i].uart_port == knx_uart) {
|
if (knx_uart >= 0 && channels[i].enabled && channels[i].serial_phy &&
|
||||||
|
channels[i].uart_port == knx_uart) {
|
||||||
ESP_LOGE(kTag, "KNX TP UART%d conflicts with DALI channel %d serial PHY", knx_uart,
|
ESP_LOGE(kTag, "KNX TP UART%d conflicts with DALI channel %d serial PHY", knx_uart,
|
||||||
i + 1);
|
i + 1);
|
||||||
return false;
|
return false;
|
||||||
@@ -543,83 +898,51 @@ bool ValidateChannelBindings() {
|
|||||||
|
|
||||||
esp_err_t BindConfiguredChannels(gateway::DaliDomainService& dali_domain,
|
esp_err_t BindConfiguredChannels(gateway::DaliDomainService& dali_domain,
|
||||||
const gateway::GatewayRuntime& runtime) {
|
const gateway::GatewayRuntime& runtime) {
|
||||||
#if CONFIG_GATEWAY_CHANNEL1_PHY_NATIVE
|
std::array<bool, 256> used_gateway_ids{};
|
||||||
gateway::DaliHardwareBusConfig channel1{};
|
for (const auto& channel : BuildChannelBindings()) {
|
||||||
channel1.channel_index = 0;
|
if (!channel.enabled) {
|
||||||
channel1.gateway_id = static_cast<uint8_t>(CONFIG_GATEWAY_CHANNEL1_GW_ID);
|
continue;
|
||||||
channel1.bus_id = static_cast<uint8_t>(CONFIG_GATEWAY_CHANNEL1_NATIVE_BUS_ID);
|
}
|
||||||
channel1.tx_pin = static_cast<uint8_t>(CONFIG_GATEWAY_CHANNEL1_NATIVE_TX_PIN);
|
const uint8_t gateway_id =
|
||||||
channel1.rx_pin = static_cast<uint8_t>(CONFIG_GATEWAY_CHANNEL1_NATIVE_RX_PIN);
|
runtime.gatewayIdForChannel(channel.channel_index, channel.gateway_id);
|
||||||
channel1.baudrate = static_cast<uint32_t>(CONFIG_GATEWAY_CHANNEL1_NATIVE_BAUDRATE);
|
if (used_gateway_ids[gateway_id]) {
|
||||||
channel1.name = runtime.gatewayName(channel1.gateway_id);
|
ESP_LOGE(kTag, "duplicate runtime gateway id configured: %u", gateway_id);
|
||||||
esp_err_t err = dali_domain.bindHardwareBus(channel1);
|
return ESP_ERR_INVALID_STATE;
|
||||||
LogBindError("channel1 native DALI", err);
|
}
|
||||||
if (err != ESP_OK) {
|
used_gateway_ids[gateway_id] = true;
|
||||||
return err;
|
if (channel.native_phy) {
|
||||||
|
gateway::DaliHardwareBusConfig config{};
|
||||||
|
config.channel_index = channel.channel_index;
|
||||||
|
config.gateway_id = gateway_id;
|
||||||
|
config.bus_id = channel.native_bus_id;
|
||||||
|
config.tx_pin = static_cast<uint8_t>(channel.native_tx_pin);
|
||||||
|
config.rx_pin = static_cast<uint8_t>(channel.native_rx_pin);
|
||||||
|
config.baudrate = channel.native_baudrate;
|
||||||
|
config.name = runtime.gatewayName(config.gateway_id);
|
||||||
|
const esp_err_t err = dali_domain.bindHardwareBus(config);
|
||||||
|
LogBindError(config.name.c_str(), err);
|
||||||
|
if (err != ESP_OK) {
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
} else if (channel.serial_phy) {
|
||||||
|
gateway::DaliSerialBusConfig config{};
|
||||||
|
config.channel_index = channel.channel_index;
|
||||||
|
config.gateway_id = gateway_id;
|
||||||
|
config.uart_port = channel.uart_port;
|
||||||
|
config.tx_pin = channel.serial_tx_pin;
|
||||||
|
config.rx_pin = channel.serial_rx_pin;
|
||||||
|
config.baudrate = channel.serial_baudrate;
|
||||||
|
config.rx_buffer_size = channel.serial_rx_buffer_size;
|
||||||
|
config.tx_buffer_size = channel.serial_tx_buffer_size;
|
||||||
|
config.query_timeout_ms = channel.serial_query_timeout_ms;
|
||||||
|
config.name = runtime.gatewayName(config.gateway_id);
|
||||||
|
const esp_err_t err = dali_domain.bindSerialBus(config);
|
||||||
|
LogBindError(config.name.c_str(), err);
|
||||||
|
if (err != ESP_OK) {
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
#elif CONFIG_GATEWAY_CHANNEL1_PHY_UART1 || CONFIG_GATEWAY_CHANNEL1_PHY_UART2
|
|
||||||
gateway::DaliSerialBusConfig channel1{};
|
|
||||||
channel1.channel_index = 0;
|
|
||||||
channel1.gateway_id = static_cast<uint8_t>(CONFIG_GATEWAY_CHANNEL1_GW_ID);
|
|
||||||
#if CONFIG_GATEWAY_CHANNEL1_PHY_UART1
|
|
||||||
channel1.uart_port = 1;
|
|
||||||
#else
|
|
||||||
channel1.uart_port = 2;
|
|
||||||
#endif
|
|
||||||
channel1.tx_pin = CONFIG_GATEWAY_CHANNEL1_SERIAL_TX_PIN;
|
|
||||||
channel1.rx_pin = CONFIG_GATEWAY_CHANNEL1_SERIAL_RX_PIN;
|
|
||||||
channel1.baudrate = static_cast<uint32_t>(CONFIG_GATEWAY_CHANNEL1_SERIAL_BAUDRATE);
|
|
||||||
channel1.rx_buffer_size = static_cast<size_t>(CONFIG_GATEWAY_CHANNEL1_SERIAL_RX_BUFFER);
|
|
||||||
channel1.tx_buffer_size = static_cast<size_t>(CONFIG_GATEWAY_CHANNEL1_SERIAL_TX_BUFFER);
|
|
||||||
channel1.query_timeout_ms =
|
|
||||||
static_cast<uint32_t>(CONFIG_GATEWAY_CHANNEL1_SERIAL_QUERY_TIMEOUT_MS);
|
|
||||||
channel1.name = runtime.gatewayName(channel1.gateway_id);
|
|
||||||
esp_err_t err1 = dali_domain.bindSerialBus(channel1);
|
|
||||||
LogBindError("channel1 serial DALI", err1);
|
|
||||||
if (err1 != ESP_OK) {
|
|
||||||
return err1;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if CONFIG_GATEWAY_CHANNEL_COUNT >= 2
|
|
||||||
#if CONFIG_GATEWAY_CHANNEL2_PHY_NATIVE
|
|
||||||
gateway::DaliHardwareBusConfig channel2{};
|
|
||||||
channel2.channel_index = 1;
|
|
||||||
channel2.gateway_id = static_cast<uint8_t>(CONFIG_GATEWAY_CHANNEL2_GW_ID);
|
|
||||||
channel2.bus_id = static_cast<uint8_t>(CONFIG_GATEWAY_CHANNEL2_NATIVE_BUS_ID);
|
|
||||||
channel2.tx_pin = static_cast<uint8_t>(CONFIG_GATEWAY_CHANNEL2_NATIVE_TX_PIN);
|
|
||||||
channel2.rx_pin = static_cast<uint8_t>(CONFIG_GATEWAY_CHANNEL2_NATIVE_RX_PIN);
|
|
||||||
channel2.baudrate = static_cast<uint32_t>(CONFIG_GATEWAY_CHANNEL2_NATIVE_BAUDRATE);
|
|
||||||
channel2.name = runtime.gatewayName(channel2.gateway_id);
|
|
||||||
esp_err_t err2 = dali_domain.bindHardwareBus(channel2);
|
|
||||||
LogBindError("channel2 native DALI", err2);
|
|
||||||
if (err2 != ESP_OK) {
|
|
||||||
return err2;
|
|
||||||
}
|
|
||||||
#elif CONFIG_GATEWAY_CHANNEL2_PHY_UART1 || CONFIG_GATEWAY_CHANNEL2_PHY_UART2
|
|
||||||
gateway::DaliSerialBusConfig channel2{};
|
|
||||||
channel2.channel_index = 1;
|
|
||||||
channel2.gateway_id = static_cast<uint8_t>(CONFIG_GATEWAY_CHANNEL2_GW_ID);
|
|
||||||
#if CONFIG_GATEWAY_CHANNEL2_PHY_UART1
|
|
||||||
channel2.uart_port = 1;
|
|
||||||
#else
|
|
||||||
channel2.uart_port = 2;
|
|
||||||
#endif
|
|
||||||
channel2.tx_pin = CONFIG_GATEWAY_CHANNEL2_SERIAL_TX_PIN;
|
|
||||||
channel2.rx_pin = CONFIG_GATEWAY_CHANNEL2_SERIAL_RX_PIN;
|
|
||||||
channel2.baudrate = static_cast<uint32_t>(CONFIG_GATEWAY_CHANNEL2_SERIAL_BAUDRATE);
|
|
||||||
channel2.rx_buffer_size = static_cast<size_t>(CONFIG_GATEWAY_CHANNEL2_SERIAL_RX_BUFFER);
|
|
||||||
channel2.tx_buffer_size = static_cast<size_t>(CONFIG_GATEWAY_CHANNEL2_SERIAL_TX_BUFFER);
|
|
||||||
channel2.query_timeout_ms =
|
|
||||||
static_cast<uint32_t>(CONFIG_GATEWAY_CHANNEL2_SERIAL_QUERY_TIMEOUT_MS);
|
|
||||||
channel2.name = runtime.gatewayName(channel2.gateway_id);
|
|
||||||
esp_err_t err2 = dali_domain.bindSerialBus(channel2);
|
|
||||||
LogBindError("channel2 serial DALI", err2);
|
|
||||||
if (err2 != ESP_OK) {
|
|
||||||
return err2;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
return ESP_OK;
|
return ESP_OK;
|
||||||
}
|
}
|
||||||
@@ -634,7 +957,7 @@ extern "C" void app_main(void) {
|
|||||||
"gateway",
|
"gateway",
|
||||||
kWifiSupported,
|
kWifiSupported,
|
||||||
kBleSupported,
|
kBleSupported,
|
||||||
true,
|
kEthernetSupported,
|
||||||
kEspnowSetupSupported,
|
kEspnowSetupSupported,
|
||||||
kUsbSetupStartupEnabled,
|
kUsbSetupStartupEnabled,
|
||||||
};
|
};
|
||||||
@@ -656,8 +979,8 @@ extern "C" void app_main(void) {
|
|||||||
},
|
},
|
||||||
s_dali_domain.get());
|
s_dali_domain.get());
|
||||||
ESP_ERROR_CHECK(s_runtime->start());
|
ESP_ERROR_CHECK(s_runtime->start());
|
||||||
s_runtime->setGatewayCount(CONFIG_GATEWAY_CHANNEL_COUNT);
|
|
||||||
ESP_ERROR_CHECK(BindConfiguredChannels(*s_dali_domain, *s_runtime));
|
ESP_ERROR_CHECK(BindConfiguredChannels(*s_dali_domain, *s_runtime));
|
||||||
|
s_runtime->setGatewayCount(s_dali_domain->channelCount());
|
||||||
|
|
||||||
gateway::GatewayCacheConfig cache_config;
|
gateway::GatewayCacheConfig cache_config;
|
||||||
cache_config.cache_enabled = kCacheSupported && kCacheStartupEnabled && s_runtime->cacheEnabled();
|
cache_config.cache_enabled = kCacheSupported && kCacheStartupEnabled && s_runtime->cacheEnabled();
|
||||||
@@ -665,17 +988,25 @@ extern "C" void app_main(void) {
|
|||||||
cache_config.full_state_mirror_enabled = cache_config.reconciliation_enabled &&
|
cache_config.full_state_mirror_enabled = cache_config.reconciliation_enabled &&
|
||||||
kCacheFullStateMirrorEnabled;
|
kCacheFullStateMirrorEnabled;
|
||||||
cache_config.flush_interval_ms = static_cast<uint32_t>(CONFIG_GATEWAY_CACHE_FLUSH_INTERVAL_MS);
|
cache_config.flush_interval_ms = static_cast<uint32_t>(CONFIG_GATEWAY_CACHE_FLUSH_INTERVAL_MS);
|
||||||
|
cache_config.refresh_interval_ms =
|
||||||
|
static_cast<uint32_t>(CONFIG_GATEWAY_CACHE_REFRESH_INTERVAL_MS);
|
||||||
cache_config.default_priority_mode = kCachePriorityMode;
|
cache_config.default_priority_mode = kCachePriorityMode;
|
||||||
s_cache = std::make_unique<gateway::GatewayCache>(cache_config);
|
s_cache = std::make_unique<gateway::GatewayCache>(cache_config);
|
||||||
ESP_ERROR_CHECK(s_cache->start());
|
ESP_ERROR_CHECK(s_cache->start());
|
||||||
|
|
||||||
gateway::GatewayControllerConfig controller_config;
|
gateway::GatewayControllerConfig controller_config;
|
||||||
|
controller_config.task_stack_size =
|
||||||
|
static_cast<uint32_t>(CONFIG_GATEWAY_CONTROLLER_TASK_STACK_SIZE);
|
||||||
|
const bool network_transport_supported = profile.enable_wifi || profile.enable_eth;
|
||||||
controller_config.setup_supported = true;
|
controller_config.setup_supported = true;
|
||||||
controller_config.ble_supported = profile.enable_ble;
|
controller_config.ble_supported = profile.enable_ble;
|
||||||
controller_config.wifi_supported = profile.enable_wifi;
|
controller_config.wifi_supported = profile.enable_wifi;
|
||||||
controller_config.ip_router_supported = profile.enable_wifi || profile.enable_eth;
|
controller_config.ip_router_supported = network_transport_supported;
|
||||||
controller_config.internal_scene_supported = true;
|
controller_config.internal_scene_supported = true;
|
||||||
controller_config.internal_group_supported = true;
|
controller_config.internal_group_supported = true;
|
||||||
|
controller_config.cache_supported = kCacheSupported;
|
||||||
|
controller_config.cache_refresh_interval_ms =
|
||||||
|
static_cast<uint32_t>(CONFIG_GATEWAY_CACHE_REFRESH_INTERVAL_MS);
|
||||||
|
|
||||||
s_controller = std::make_unique<gateway::GatewayController>(*s_runtime, *s_dali_domain,
|
s_controller = std::make_unique<gateway::GatewayController>(*s_runtime, *s_dali_domain,
|
||||||
*s_cache,
|
*s_cache,
|
||||||
@@ -707,37 +1038,25 @@ extern "C" void app_main(void) {
|
|||||||
bridge_config.bridge_enabled = true;
|
bridge_config.bridge_enabled = true;
|
||||||
bridge_config.modbus_enabled = kModbusBridgeSupported;
|
bridge_config.modbus_enabled = kModbusBridgeSupported;
|
||||||
bridge_config.modbus_startup_enabled = kModbusBridgeSupported && kModbusBridgeStartupEnabled;
|
bridge_config.modbus_startup_enabled = kModbusBridgeSupported && kModbusBridgeStartupEnabled;
|
||||||
bridge_config.bacnet_enabled = profile.enable_wifi && kBacnetBridgeSupported;
|
bridge_config.bacnet_enabled = network_transport_supported && kBacnetBridgeSupported;
|
||||||
bridge_config.bacnet_startup_enabled = profile.enable_wifi && kBacnetBridgeSupported &&
|
bridge_config.bacnet_startup_enabled = network_transport_supported && kBacnetBridgeSupported &&
|
||||||
kBacnetBridgeStartupEnabled;
|
kBacnetBridgeStartupEnabled;
|
||||||
bridge_config.knx_enabled = profile.enable_wifi && kKnxBridgeSupported;
|
bridge_config.knx_enabled = network_transport_supported && kKnxBridgeSupported;
|
||||||
bridge_config.knx_startup_enabled = profile.enable_wifi && kKnxBridgeSupported &&
|
bridge_config.knx_startup_enabled = network_transport_supported && kKnxBridgeSupported &&
|
||||||
kKnxBridgeStartupEnabled;
|
kKnxBridgeStartupEnabled;
|
||||||
bridge_config.cloud_enabled = profile.enable_wifi && kCloudBridgeSupported;
|
bridge_config.cloud_enabled = network_transport_supported && kCloudBridgeSupported;
|
||||||
bridge_config.cloud_startup_enabled = profile.enable_wifi && kCloudBridgeSupported &&
|
bridge_config.cloud_startup_enabled = network_transport_supported && kCloudBridgeSupported &&
|
||||||
kCloudBridgeStartupEnabled;
|
kCloudBridgeStartupEnabled;
|
||||||
bridge_config.modbus_task_stack_size =
|
bridge_config.modbus_task_stack_size =
|
||||||
static_cast<uint32_t>(CONFIG_GATEWAY_BRIDGE_MODBUS_TASK_STACK_SIZE);
|
static_cast<uint32_t>(CONFIG_GATEWAY_BRIDGE_MODBUS_TASK_STACK_SIZE);
|
||||||
bridge_config.modbus_task_priority =
|
bridge_config.modbus_task_priority =
|
||||||
static_cast<UBaseType_t>(CONFIG_GATEWAY_BRIDGE_MODBUS_TASK_PRIORITY);
|
static_cast<UBaseType_t>(CONFIG_GATEWAY_BRIDGE_MODBUS_TASK_PRIORITY);
|
||||||
bridge_config.allow_modbus_uart0 = kModbusAllowUart0 && !k485ControlEnabled;
|
bridge_config.allow_modbus_uart0 = kModbusAllowUart0 && !kConsoleOnUart0 && !k485ControlEnabled;
|
||||||
if (!bridge_config.allow_modbus_uart0) {
|
bridge_config.allow_knx_uart0 = !kConsoleOnUart0 && !k485ControlEnabled;
|
||||||
bridge_config.reserved_uart_ports.push_back(0);
|
for (const auto& channel : BuildChannelBindings()) {
|
||||||
}
|
if (channel.enabled && channel.serial_phy) {
|
||||||
#if CONFIG_GATEWAY_CHANNEL1_PHY_UART1
|
bridge_config.reserved_uart_ports.push_back(channel.uart_port);
|
||||||
bridge_config.reserved_uart_ports.push_back(1);
|
}
|
||||||
#elif CONFIG_GATEWAY_CHANNEL1_PHY_UART2
|
|
||||||
bridge_config.reserved_uart_ports.push_back(2);
|
|
||||||
#endif
|
|
||||||
#if CONFIG_GATEWAY_CHANNEL_COUNT >= 2
|
|
||||||
#if CONFIG_GATEWAY_CHANNEL2_PHY_UART1
|
|
||||||
bridge_config.reserved_uart_ports.push_back(1);
|
|
||||||
#elif CONFIG_GATEWAY_CHANNEL2_PHY_UART2
|
|
||||||
bridge_config.reserved_uart_ports.push_back(2);
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
if (kKnxBridgeSupported) {
|
|
||||||
bridge_config.reserved_uart_ports.push_back(CONFIG_GATEWAY_KNX_TP_UART_PORT);
|
|
||||||
}
|
}
|
||||||
if (kModbusBridgeSupported) {
|
if (kModbusBridgeSupported) {
|
||||||
gateway::GatewayModbusConfig default_modbus;
|
gateway::GatewayModbusConfig default_modbus;
|
||||||
@@ -772,27 +1091,154 @@ extern "C" void app_main(void) {
|
|||||||
default_knx.tunnel_enabled = kKnxTunnelEnabled;
|
default_knx.tunnel_enabled = kKnxTunnelEnabled;
|
||||||
default_knx.multicast_enabled = kKnxMulticastEnabled;
|
default_knx.multicast_enabled = kKnxMulticastEnabled;
|
||||||
default_knx.main_group = static_cast<uint8_t>(CONFIG_GATEWAY_KNX_MAIN_GROUP);
|
default_knx.main_group = static_cast<uint8_t>(CONFIG_GATEWAY_KNX_MAIN_GROUP);
|
||||||
|
default_knx.dali_bus_id = static_cast<uint8_t>(CONFIG_GATEWAY_KNX_DALI_BUS_ID);
|
||||||
default_knx.udp_port = static_cast<uint16_t>(CONFIG_GATEWAY_KNX_UDP_PORT);
|
default_knx.udp_port = static_cast<uint16_t>(CONFIG_GATEWAY_KNX_UDP_PORT);
|
||||||
default_knx.multicast_address = CONFIG_GATEWAY_KNX_MULTICAST_ADDRESS;
|
default_knx.multicast_address = CONFIG_GATEWAY_KNX_MULTICAST_ADDRESS;
|
||||||
|
default_knx.ip_interface_individual_address =
|
||||||
|
static_cast<uint16_t>(CONFIG_GATEWAY_KNX_IP_INTERFACE_INDIVIDUAL_ADDRESS);
|
||||||
default_knx.individual_address =
|
default_knx.individual_address =
|
||||||
static_cast<uint16_t>(CONFIG_GATEWAY_KNX_INDIVIDUAL_ADDRESS);
|
static_cast<uint16_t>(CONFIG_GATEWAY_KNX_INDIVIDUAL_ADDRESS);
|
||||||
|
default_knx.oam_router.enabled = kKnxOamRouterSupported && kKnxOamRouterEnabled;
|
||||||
|
default_knx.oam_router.individual_address =
|
||||||
|
static_cast<uint16_t>(CONFIG_GATEWAY_KNX_OAM_ROUTER_INDIVIDUAL_ADDRESS);
|
||||||
|
default_knx.oam_router.tunnel_address_base =
|
||||||
|
static_cast<uint16_t>(CONFIG_GATEWAY_KNX_OAM_ROUTER_TUNNEL_ADDRESS_BASE);
|
||||||
|
if (default_knx.oam_router.enabled) {
|
||||||
|
default_knx.ip_interface_individual_address = default_knx.oam_router.individual_address;
|
||||||
|
}
|
||||||
|
default_knx.oam_router.programming_button_gpio =
|
||||||
|
CONFIG_GATEWAY_KNX_OAM_PROGRAMMING_BUTTON_GPIO;
|
||||||
|
default_knx.oam_router.programming_led_gpio =
|
||||||
|
CONFIG_GATEWAY_KNX_OAM_PROGRAMMING_LED_GPIO;
|
||||||
|
#ifdef CONFIG_GATEWAY_KNX_OAM_PROGRAMMING_BUTTON_ACTIVE_LOW
|
||||||
|
default_knx.oam_router.programming_button_active_low = true;
|
||||||
|
#else
|
||||||
|
default_knx.oam_router.programming_button_active_low = false;
|
||||||
|
#endif
|
||||||
|
#ifdef CONFIG_GATEWAY_KNX_OAM_PROGRAMMING_LED_ACTIVE_HIGH
|
||||||
|
default_knx.oam_router.programming_led_active_high = true;
|
||||||
|
#else
|
||||||
|
default_knx.oam_router.programming_led_active_high = false;
|
||||||
|
#endif
|
||||||
|
default_knx.programming_button_gpio = CONFIG_GATEWAY_KNX_PROGRAMMING_BUTTON_GPIO;
|
||||||
|
default_knx.programming_led_gpio = CONFIG_GATEWAY_KNX_PROGRAMMING_LED_GPIO;
|
||||||
|
#ifdef CONFIG_GATEWAY_KNX_PROGRAMMING_BUTTON_ACTIVE_LOW
|
||||||
|
default_knx.programming_button_active_low = true;
|
||||||
|
#else
|
||||||
|
default_knx.programming_button_active_low = false;
|
||||||
|
#endif
|
||||||
|
#ifdef CONFIG_GATEWAY_KNX_PROGRAMMING_LED_ACTIVE_HIGH
|
||||||
|
default_knx.programming_led_active_high = true;
|
||||||
|
#else
|
||||||
|
default_knx.programming_led_active_high = false;
|
||||||
|
#endif
|
||||||
default_knx.tp_uart.uart_port = CONFIG_GATEWAY_KNX_TP_UART_PORT;
|
default_knx.tp_uart.uart_port = CONFIG_GATEWAY_KNX_TP_UART_PORT;
|
||||||
default_knx.tp_uart.tx_pin = CONFIG_GATEWAY_KNX_TP_TX_PIN;
|
default_knx.tp_uart.tx_pin = CONFIG_GATEWAY_KNX_TP_TX_PIN;
|
||||||
default_knx.tp_uart.rx_pin = CONFIG_GATEWAY_KNX_TP_RX_PIN;
|
default_knx.tp_uart.rx_pin = CONFIG_GATEWAY_KNX_TP_RX_PIN;
|
||||||
default_knx.tp_uart.baudrate = static_cast<uint32_t>(CONFIG_GATEWAY_KNX_TP_BAUDRATE);
|
default_knx.tp_uart.baudrate = static_cast<uint32_t>(CONFIG_GATEWAY_KNX_TP_BAUDRATE);
|
||||||
|
default_knx.tp_uart.startup_timeout_ms =
|
||||||
|
static_cast<uint32_t>(CONFIG_GATEWAY_KNX_TP_STARTUP_TIMEOUT_MS);
|
||||||
|
#ifdef CONFIG_GATEWAY_KNX_TP_UART_9BIT_MODE
|
||||||
|
default_knx.tp_uart.nine_bit_mode = true;
|
||||||
|
#else
|
||||||
|
default_knx.tp_uart.nine_bit_mode = false;
|
||||||
|
#endif
|
||||||
bridge_config.default_knx_config = default_knx;
|
bridge_config.default_knx_config = default_knx;
|
||||||
}
|
}
|
||||||
bridge_config.knx_task_stack_size =
|
bridge_config.knx_task_stack_size =
|
||||||
static_cast<uint32_t>(CONFIG_GATEWAY_BRIDGE_KNX_TASK_STACK_SIZE);
|
static_cast<uint32_t>(CONFIG_GATEWAY_BRIDGE_KNX_TASK_STACK_SIZE);
|
||||||
bridge_config.knx_task_priority =
|
bridge_config.knx_task_priority =
|
||||||
static_cast<UBaseType_t>(CONFIG_GATEWAY_BRIDGE_KNX_TASK_PRIORITY);
|
static_cast<UBaseType_t>(CONFIG_GATEWAY_BRIDGE_KNX_TASK_PRIORITY);
|
||||||
|
bridge_config.gateway_device_name_provider = []() {
|
||||||
|
return s_runtime == nullptr ? std::string() : s_runtime->deviceName();
|
||||||
|
};
|
||||||
|
bridge_config.knx_gateway_snapshot_provider = []() {
|
||||||
|
gateway::GatewayKnxGatewaySnapshot out;
|
||||||
|
if (s_controller == nullptr) {
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
const auto snapshot = s_controller->snapshot();
|
||||||
|
out.channels.reserve(snapshot.channels.size());
|
||||||
|
for (const auto& channel : snapshot.channels) {
|
||||||
|
out.channels.push_back(
|
||||||
|
gateway::GatewayKnxGatewayChannelSnapshot{channel.gateway_id});
|
||||||
|
}
|
||||||
|
return out;
|
||||||
|
};
|
||||||
|
bridge_config.knx_gateway_command_transactor =
|
||||||
|
[](const std::vector<uint8_t>& frame, uint32_t timeout_ms) {
|
||||||
|
gateway::GatewayKnxGatewayTransactionResult out;
|
||||||
|
if (s_controller == nullptr) {
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
if (!gateway::GatewayRuntime::isGatewayCommandFrame(frame) ||
|
||||||
|
!gateway::GatewayRuntime::hasValidChecksum(frame) ||
|
||||||
|
frame.size() < 5) {
|
||||||
|
out.status = gateway::GatewayKnxGatewayTransactionStatus::kInvalidFrame;
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
const auto is_write_only_dali_frame =
|
||||||
|
[](const std::vector<uint8_t>& command) {
|
||||||
|
if (command.size() < 5) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
switch (command[3]) {
|
||||||
|
case 0x12:
|
||||||
|
case 0x13:
|
||||||
|
return command.size() >= 7;
|
||||||
|
case 0x60:
|
||||||
|
case 0x61:
|
||||||
|
return command.size() >= 8;
|
||||||
|
default:
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
if (is_write_only_dali_frame(frame)) {
|
||||||
|
out.status = s_controller->enqueueCommandFrame(frame)
|
||||||
|
? gateway::GatewayKnxGatewayTransactionStatus::kOk
|
||||||
|
: gateway::GatewayKnxGatewayTransactionStatus::kQueueRejected;
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
const auto result = s_controller->transactCommandFrame(frame, timeout_ms);
|
||||||
|
switch (result.status) {
|
||||||
|
case gateway::GatewayCommandTransactionStatus::kOk:
|
||||||
|
out.status = gateway::GatewayKnxGatewayTransactionStatus::kOk;
|
||||||
|
break;
|
||||||
|
case gateway::GatewayCommandTransactionStatus::kInvalidFrame:
|
||||||
|
out.status = gateway::GatewayKnxGatewayTransactionStatus::kInvalidFrame;
|
||||||
|
break;
|
||||||
|
case gateway::GatewayCommandTransactionStatus::kQueueRejected:
|
||||||
|
out.status = gateway::GatewayKnxGatewayTransactionStatus::kQueueRejected;
|
||||||
|
break;
|
||||||
|
case gateway::GatewayCommandTransactionStatus::kTimeout:
|
||||||
|
out.status = gateway::GatewayKnxGatewayTransactionStatus::kTimeout;
|
||||||
|
break;
|
||||||
|
case gateway::GatewayCommandTransactionStatus::kNoResponse:
|
||||||
|
out.status = gateway::GatewayKnxGatewayTransactionStatus::kNoResponse;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
out.frames = result.frames;
|
||||||
|
return out;
|
||||||
|
};
|
||||||
s_bridge = std::make_unique<gateway::GatewayBridgeService>(*s_dali_domain, *s_cache,
|
s_bridge = std::make_unique<gateway::GatewayBridgeService>(*s_dali_domain, *s_cache,
|
||||||
bridge_config);
|
bridge_config);
|
||||||
|
s_controller->setBridgeService(s_bridge.get());
|
||||||
|
s_controller->addGatewayNameSink([](uint8_t gateway_id) {
|
||||||
|
if (s_bridge != nullptr) {
|
||||||
|
s_bridge->handleGatewayNameChanged(gateway_id);
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
if (profile.enable_wifi || profile.enable_eth) {
|
if (profile.enable_wifi || profile.enable_eth) {
|
||||||
gateway::GatewayNetworkServiceConfig network_config;
|
gateway::GatewayNetworkServiceConfig network_config;
|
||||||
network_config.wifi_enabled = profile.enable_wifi && kWifiStartupEnabled;
|
network_config.wifi_enabled = profile.enable_wifi && kWifiStartupEnabled;
|
||||||
|
network_config.ethernet_enabled = profile.enable_eth && kEthernetStartupEnabled;
|
||||||
|
#if CONFIG_GATEWAY_ETHERNET_IGNORE_INIT_FAILURE
|
||||||
|
network_config.ethernet_ignore_init_failure = true;
|
||||||
|
#else
|
||||||
|
network_config.ethernet_ignore_init_failure = false;
|
||||||
|
#endif
|
||||||
network_config.espnow_setup_enabled = profile.enable_espnow;
|
network_config.espnow_setup_enabled = profile.enable_espnow;
|
||||||
network_config.espnow_setup_startup_enabled =
|
network_config.espnow_setup_startup_enabled =
|
||||||
profile.enable_espnow && kEspnowSetupStartupEnabled;
|
profile.enable_espnow && kEspnowSetupStartupEnabled;
|
||||||
@@ -812,9 +1258,26 @@ extern "C" void app_main(void) {
|
|||||||
#endif
|
#endif
|
||||||
network_config.http_port = static_cast<uint16_t>(CONFIG_GATEWAY_NETWORK_HTTP_PORT);
|
network_config.http_port = static_cast<uint16_t>(CONFIG_GATEWAY_NETWORK_HTTP_PORT);
|
||||||
network_config.udp_port = static_cast<uint16_t>(CONFIG_GATEWAY_NETWORK_UDP_PORT);
|
network_config.udp_port = static_cast<uint16_t>(CONFIG_GATEWAY_NETWORK_UDP_PORT);
|
||||||
|
network_config.ethernet_spi_host = CONFIG_GATEWAY_ETHERNET_W5500_SPI_HOST;
|
||||||
|
network_config.ethernet_spi_sclk_gpio = CONFIG_GATEWAY_ETHERNET_W5500_SCLK_GPIO;
|
||||||
|
network_config.ethernet_spi_mosi_gpio = CONFIG_GATEWAY_ETHERNET_W5500_MOSI_GPIO;
|
||||||
|
network_config.ethernet_spi_miso_gpio = CONFIG_GATEWAY_ETHERNET_W5500_MISO_GPIO;
|
||||||
|
network_config.ethernet_spi_cs_gpio = CONFIG_GATEWAY_ETHERNET_W5500_CS_GPIO;
|
||||||
|
network_config.ethernet_spi_int_gpio = CONFIG_GATEWAY_ETHERNET_W5500_INT_GPIO;
|
||||||
|
network_config.ethernet_poll_period_ms =
|
||||||
|
static_cast<uint32_t>(CONFIG_GATEWAY_ETHERNET_W5500_POLL_PERIOD_MS);
|
||||||
|
network_config.ethernet_spi_clock_mhz =
|
||||||
|
static_cast<uint8_t>(CONFIG_GATEWAY_ETHERNET_W5500_CLOCK_MHZ);
|
||||||
|
network_config.ethernet_phy_reset_gpio = CONFIG_GATEWAY_ETHERNET_PHY_RESET_GPIO;
|
||||||
|
network_config.ethernet_phy_addr = CONFIG_GATEWAY_ETHERNET_PHY_ADDR;
|
||||||
|
network_config.ethernet_rx_task_stack_size =
|
||||||
|
static_cast<uint32_t>(CONFIG_GATEWAY_ETHERNET_RX_TASK_STACK_SIZE);
|
||||||
network_config.status_led_gpio = CONFIG_GATEWAY_STATUS_LED_GPIO;
|
network_config.status_led_gpio = CONFIG_GATEWAY_STATUS_LED_GPIO;
|
||||||
network_config.boot_button_gpio = CONFIG_GATEWAY_BOOT_BUTTON_GPIO;
|
network_config.boot_button_gpio = CONFIG_GATEWAY_BOOT_BUTTON_GPIO;
|
||||||
|
network_config.setup_ap_button_gpio = CONFIG_GATEWAY_SETUP_AP_BUTTON_GPIO;
|
||||||
network_config.boot_button_long_press_ms = CONFIG_GATEWAY_BOOT_BUTTON_LONG_PRESS_MS;
|
network_config.boot_button_long_press_ms = CONFIG_GATEWAY_BOOT_BUTTON_LONG_PRESS_MS;
|
||||||
|
network_config.boot_button_task_stack_size =
|
||||||
|
static_cast<uint32_t>(CONFIG_GATEWAY_BUTTON_TASK_STACK_SIZE);
|
||||||
#ifdef CONFIG_GATEWAY_STATUS_LED_ACTIVE_HIGH
|
#ifdef CONFIG_GATEWAY_STATUS_LED_ACTIVE_HIGH
|
||||||
network_config.status_led_active_high = true;
|
network_config.status_led_active_high = true;
|
||||||
#else
|
#else
|
||||||
@@ -824,6 +1287,11 @@ extern "C" void app_main(void) {
|
|||||||
network_config.boot_button_active_low = true;
|
network_config.boot_button_active_low = true;
|
||||||
#else
|
#else
|
||||||
network_config.boot_button_active_low = false;
|
network_config.boot_button_active_low = false;
|
||||||
|
#endif
|
||||||
|
#ifdef CONFIG_GATEWAY_SETUP_AP_BUTTON_ACTIVE_LOW
|
||||||
|
network_config.setup_ap_button_active_low = true;
|
||||||
|
#else
|
||||||
|
network_config.setup_ap_button_active_low = false;
|
||||||
#endif
|
#endif
|
||||||
s_network = std::make_unique<gateway::GatewayNetworkService>(*s_controller, *s_runtime,
|
s_network = std::make_unique<gateway::GatewayNetworkService>(*s_controller, *s_runtime,
|
||||||
*s_dali_domain, network_config,
|
*s_dali_domain, network_config,
|
||||||
@@ -848,6 +1316,7 @@ extern "C" void app_main(void) {
|
|||||||
usb_config.rx_buffer_size = static_cast<size_t>(CONFIG_GATEWAY_USB_SETUP_RX_BUFFER);
|
usb_config.rx_buffer_size = static_cast<size_t>(CONFIG_GATEWAY_USB_SETUP_RX_BUFFER);
|
||||||
usb_config.tx_buffer_size = static_cast<size_t>(CONFIG_GATEWAY_USB_SETUP_TX_BUFFER);
|
usb_config.tx_buffer_size = static_cast<size_t>(CONFIG_GATEWAY_USB_SETUP_TX_BUFFER);
|
||||||
usb_config.read_timeout_ms = static_cast<uint32_t>(CONFIG_GATEWAY_USB_SETUP_READ_TIMEOUT_MS);
|
usb_config.read_timeout_ms = static_cast<uint32_t>(CONFIG_GATEWAY_USB_SETUP_READ_TIMEOUT_MS);
|
||||||
|
usb_config.reset_pulse_ms = static_cast<uint32_t>(CONFIG_DALI_BUS_RESET_PULSE_MS);
|
||||||
s_usb_setup_bridge = std::make_unique<gateway::GatewayUsbSetupBridge>(*s_controller,
|
s_usb_setup_bridge = std::make_unique<gateway::GatewayUsbSetupBridge>(*s_controller,
|
||||||
*s_dali_domain,
|
*s_dali_domain,
|
||||||
usb_config);
|
usb_config);
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
# Name, Type, SubType, Offset, Size, Flags
|
# Name, Type, SubType, Offset, Size, Flags
|
||||||
nvs, data, nvs, 0x9000, 0x6000,
|
nvs, data, nvs, 0x9000, 0x14000,
|
||||||
otadata, data, ota, 0xf000, 0x2000,
|
otadata, data, ota, 0x1D000, 0x2000,
|
||||||
phy_init, data, phy, 0x11000, 0x1000,
|
phy_init, data, phy, 0x1F000, 0x1000,
|
||||||
factory, app, factory, 0x20000, 0x200000,
|
factory, app, factory, 0x20000, 0x300000,
|
||||||
storage, data, spiffs, 0x220000, 0x180000,
|
knxprops, data, 0x40, 0x320000, 0x60000,
|
||||||
|
storage, data, spiffs, 0x380000, 0x80000,
|
||||||
|
|||||||
|
+286
-91
@@ -596,56 +596,120 @@ CONFIG_PARTITION_TABLE_MD5=y
|
|||||||
#
|
#
|
||||||
# Gateway App
|
# Gateway App
|
||||||
#
|
#
|
||||||
CONFIG_GATEWAY_CHANNEL_COUNT=2
|
|
||||||
|
#
|
||||||
|
# DALI Settings
|
||||||
|
#
|
||||||
|
CONFIG_GATEWAY_CHANNEL_COUNT=1
|
||||||
|
|
||||||
#
|
#
|
||||||
# Gateway Channel 1
|
# Gateway Channel 1
|
||||||
#
|
#
|
||||||
CONFIG_GATEWAY_CHANNEL1_GW_ID=3
|
CONFIG_GATEWAY_CHANNEL1_GW_ID=0
|
||||||
# CONFIG_GATEWAY_CHANNEL1_PHY_DISABLED is not set
|
# CONFIG_GATEWAY_CHANNEL1_PHY_DISABLED is not set
|
||||||
# CONFIG_GATEWAY_CHANNEL1_PHY_NATIVE is not set
|
CONFIG_GATEWAY_CHANNEL1_PHY_NATIVE=y
|
||||||
CONFIG_GATEWAY_CHANNEL1_PHY_UART1=y
|
# CONFIG_GATEWAY_CHANNEL1_PHY_UART1 is not set
|
||||||
# CONFIG_GATEWAY_CHANNEL1_PHY_UART2 is not set
|
# CONFIG_GATEWAY_CHANNEL1_PHY_UART2 is not set
|
||||||
CONFIG_GATEWAY_CHANNEL1_SERIAL_TX_PIN=1
|
CONFIG_GATEWAY_CHANNEL1_NATIVE_BUS_ID=0
|
||||||
CONFIG_GATEWAY_CHANNEL1_SERIAL_RX_PIN=2
|
CONFIG_GATEWAY_CHANNEL1_NATIVE_TX_PIN=2
|
||||||
CONFIG_GATEWAY_CHANNEL1_SERIAL_BAUDRATE=9600
|
CONFIG_GATEWAY_CHANNEL1_NATIVE_RX_PIN=1
|
||||||
CONFIG_GATEWAY_CHANNEL1_SERIAL_RX_BUFFER=512
|
CONFIG_GATEWAY_CHANNEL1_NATIVE_BAUDRATE=1200
|
||||||
CONFIG_GATEWAY_CHANNEL1_SERIAL_TX_BUFFER=512
|
|
||||||
CONFIG_GATEWAY_CHANNEL1_SERIAL_QUERY_TIMEOUT_MS=100
|
|
||||||
# end of Gateway Channel 1
|
# end of Gateway Channel 1
|
||||||
|
|
||||||
#
|
#
|
||||||
# Gateway Channel 2
|
# Gateway Channel 2
|
||||||
#
|
#
|
||||||
CONFIG_GATEWAY_CHANNEL2_GW_ID=4
|
|
||||||
# CONFIG_GATEWAY_CHANNEL2_PHY_DISABLED is not set
|
|
||||||
# CONFIG_GATEWAY_CHANNEL2_PHY_NATIVE is not set
|
|
||||||
# CONFIG_GATEWAY_CHANNEL2_PHY_UART1 is not set
|
|
||||||
CONFIG_GATEWAY_CHANNEL2_PHY_UART2=y
|
|
||||||
CONFIG_GATEWAY_CHANNEL2_SERIAL_TX_PIN=6
|
|
||||||
CONFIG_GATEWAY_CHANNEL2_SERIAL_RX_PIN=7
|
|
||||||
CONFIG_GATEWAY_CHANNEL2_SERIAL_BAUDRATE=9600
|
|
||||||
CONFIG_GATEWAY_CHANNEL2_SERIAL_RX_BUFFER=512
|
|
||||||
CONFIG_GATEWAY_CHANNEL2_SERIAL_TX_BUFFER=512
|
|
||||||
CONFIG_GATEWAY_CHANNEL2_SERIAL_QUERY_TIMEOUT_MS=100
|
|
||||||
# end of Gateway Channel 2
|
# end of Gateway Channel 2
|
||||||
|
|
||||||
|
#
|
||||||
|
# Gateway Channel 3
|
||||||
|
#
|
||||||
|
# end of Gateway Channel 3
|
||||||
|
|
||||||
|
#
|
||||||
|
# Gateway Channel 4
|
||||||
|
#
|
||||||
|
# end of Gateway Channel 4
|
||||||
|
|
||||||
|
#
|
||||||
|
# Gateway Channel 5
|
||||||
|
#
|
||||||
|
# end of Gateway Channel 5
|
||||||
|
|
||||||
|
#
|
||||||
|
# Gateway Channel 6
|
||||||
|
#
|
||||||
|
# end of Gateway Channel 6
|
||||||
|
|
||||||
|
#
|
||||||
|
# Gateway Channel 7
|
||||||
|
#
|
||||||
|
# end of Gateway Channel 7
|
||||||
|
|
||||||
|
#
|
||||||
|
# Gateway Channel 8
|
||||||
|
#
|
||||||
|
# end of Gateway Channel 8
|
||||||
|
|
||||||
|
#
|
||||||
|
# Gateway Channel 9
|
||||||
|
#
|
||||||
|
# end of Gateway Channel 9
|
||||||
|
|
||||||
|
#
|
||||||
|
# Gateway Channel 10
|
||||||
|
#
|
||||||
|
# end of Gateway Channel 10
|
||||||
|
|
||||||
|
#
|
||||||
|
# Gateway Channel 11
|
||||||
|
#
|
||||||
|
# end of Gateway Channel 11
|
||||||
|
|
||||||
|
#
|
||||||
|
# Gateway Channel 12
|
||||||
|
#
|
||||||
|
# end of Gateway Channel 12
|
||||||
|
|
||||||
|
#
|
||||||
|
# Gateway Channel 13
|
||||||
|
#
|
||||||
|
# end of Gateway Channel 13
|
||||||
|
|
||||||
|
#
|
||||||
|
# Gateway Channel 14
|
||||||
|
#
|
||||||
|
# end of Gateway Channel 14
|
||||||
|
|
||||||
|
#
|
||||||
|
# Gateway Channel 15
|
||||||
|
#
|
||||||
|
# end of Gateway Channel 15
|
||||||
|
|
||||||
|
#
|
||||||
|
# Gateway Channel 16
|
||||||
|
#
|
||||||
|
# end of Gateway Channel 16
|
||||||
|
|
||||||
#
|
#
|
||||||
# Gateway Cache
|
# Gateway Cache
|
||||||
#
|
#
|
||||||
CONFIG_GATEWAY_CACHE_SUPPORTED=y
|
CONFIG_GATEWAY_CACHE_SUPPORTED=y
|
||||||
CONFIG_GATEWAY_CACHE_START_ENABLED=y
|
CONFIG_GATEWAY_CACHE_START_ENABLED=y
|
||||||
CONFIG_GATEWAY_CACHE_RECONCILIATION_ENABLED=y
|
CONFIG_GATEWAY_CACHE_RECONCILIATION_ENABLED=y
|
||||||
# CONFIG_GATEWAY_CACHE_FULL_STATE_MIRROR is not set
|
CONFIG_GATEWAY_CACHE_FULL_STATE_MIRROR=y
|
||||||
CONFIG_GATEWAY_CACHE_FLUSH_INTERVAL_MS=5000
|
CONFIG_GATEWAY_CACHE_FLUSH_INTERVAL_MS=600000
|
||||||
|
CONFIG_GATEWAY_CACHE_REFRESH_INTERVAL_MS=120000
|
||||||
CONFIG_GATEWAY_CACHE_OUTSIDE_BUS_FIRST=y
|
CONFIG_GATEWAY_CACHE_OUTSIDE_BUS_FIRST=y
|
||||||
# CONFIG_GATEWAY_CACHE_LOCAL_GATEWAY_FIRST is not set
|
# CONFIG_GATEWAY_CACHE_LOCAL_GATEWAY_FIRST is not set
|
||||||
# end of Gateway Cache
|
# end of Gateway Cache
|
||||||
|
|
||||||
# CONFIG_GATEWAY_ENABLE_DALI_BUS is not set
|
# CONFIG_GATEWAY_ENABLE_DALI_BUS is not set
|
||||||
|
CONFIG_GATEWAY_CONTROLLER_TASK_STACK_SIZE=12288
|
||||||
|
# end of DALI Settings
|
||||||
|
|
||||||
#
|
#
|
||||||
# Gateway Startup Services
|
# Connectivity Startup
|
||||||
#
|
#
|
||||||
CONFIG_GATEWAY_BLE_SUPPORTED=y
|
CONFIG_GATEWAY_BLE_SUPPORTED=y
|
||||||
CONFIG_GATEWAY_START_BLE_ENABLED=y
|
CONFIG_GATEWAY_START_BLE_ENABLED=y
|
||||||
@@ -656,7 +720,36 @@ CONFIG_GATEWAY_SMARTCONFIG_SUPPORTED=y
|
|||||||
# CONFIG_GATEWAY_START_ESPNOW_SETUP_ENABLED is not set
|
# CONFIG_GATEWAY_START_ESPNOW_SETUP_ENABLED is not set
|
||||||
# CONFIG_GATEWAY_START_SMARTCONFIG_ENABLED is not set
|
# CONFIG_GATEWAY_START_SMARTCONFIG_ENABLED is not set
|
||||||
CONFIG_GATEWAY_SMARTCONFIG_TIMEOUT_SEC=60
|
CONFIG_GATEWAY_SMARTCONFIG_TIMEOUT_SEC=60
|
||||||
|
CONFIG_GATEWAY_ETHERNET_SUPPORTED=y
|
||||||
|
CONFIG_GATEWAY_START_ETHERNET_ENABLED=y
|
||||||
|
CONFIG_GATEWAY_ETHERNET_IGNORE_INIT_FAILURE=y
|
||||||
|
# end of Connectivity Startup
|
||||||
|
|
||||||
|
#
|
||||||
|
# Gateway Wired Ethernet
|
||||||
|
#
|
||||||
|
CONFIG_GATEWAY_ETHERNET_W5500_SPI_HOST=2
|
||||||
|
CONFIG_GATEWAY_ETHERNET_W5500_SCLK_GPIO=48
|
||||||
|
CONFIG_GATEWAY_ETHERNET_W5500_MOSI_GPIO=47
|
||||||
|
CONFIG_GATEWAY_ETHERNET_W5500_MISO_GPIO=33
|
||||||
|
CONFIG_GATEWAY_ETHERNET_W5500_CS_GPIO=34
|
||||||
|
CONFIG_GATEWAY_ETHERNET_W5500_INT_GPIO=36
|
||||||
|
CONFIG_GATEWAY_ETHERNET_W5500_POLL_PERIOD_MS=0
|
||||||
|
CONFIG_GATEWAY_ETHERNET_W5500_CLOCK_MHZ=20
|
||||||
|
CONFIG_GATEWAY_ETHERNET_PHY_RESET_GPIO=-1
|
||||||
|
CONFIG_GATEWAY_ETHERNET_PHY_ADDR=1
|
||||||
|
CONFIG_GATEWAY_ETHERNET_RX_TASK_STACK_SIZE=4096
|
||||||
|
# end of Gateway Wired Ethernet
|
||||||
|
|
||||||
|
#
|
||||||
|
# Bridge Runtime
|
||||||
|
#
|
||||||
CONFIG_GATEWAY_BRIDGE_SUPPORTED=y
|
CONFIG_GATEWAY_BRIDGE_SUPPORTED=y
|
||||||
|
# end of Bridge Runtime
|
||||||
|
|
||||||
|
#
|
||||||
|
# Modbus Settings
|
||||||
|
#
|
||||||
CONFIG_GATEWAY_MODBUS_BRIDGE_SUPPORTED=y
|
CONFIG_GATEWAY_MODBUS_BRIDGE_SUPPORTED=y
|
||||||
# CONFIG_GATEWAY_START_MODBUS_BRIDGE_ENABLED is not set
|
# CONFIG_GATEWAY_START_MODBUS_BRIDGE_ENABLED is not set
|
||||||
CONFIG_GATEWAY_MODBUS_DEFAULT_TRANSPORT_TCP=y
|
CONFIG_GATEWAY_MODBUS_DEFAULT_TRANSPORT_TCP=y
|
||||||
@@ -664,28 +757,99 @@ CONFIG_GATEWAY_MODBUS_DEFAULT_TRANSPORT_TCP=y
|
|||||||
# CONFIG_GATEWAY_MODBUS_DEFAULT_TRANSPORT_ASCII is not set
|
# CONFIG_GATEWAY_MODBUS_DEFAULT_TRANSPORT_ASCII is not set
|
||||||
CONFIG_GATEWAY_MODBUS_TCP_PORT=1502
|
CONFIG_GATEWAY_MODBUS_TCP_PORT=1502
|
||||||
CONFIG_GATEWAY_MODBUS_UNIT_ID=1
|
CONFIG_GATEWAY_MODBUS_UNIT_ID=1
|
||||||
|
# end of Modbus Settings
|
||||||
|
|
||||||
|
#
|
||||||
|
# BACnet Settings
|
||||||
|
#
|
||||||
CONFIG_GATEWAY_BACNET_BRIDGE_SUPPORTED=y
|
CONFIG_GATEWAY_BACNET_BRIDGE_SUPPORTED=y
|
||||||
# CONFIG_GATEWAY_START_BACNET_BRIDGE_ENABLED is not set
|
# CONFIG_GATEWAY_START_BACNET_BRIDGE_ENABLED is not set
|
||||||
# CONFIG_GATEWAY_KNX_BRIDGE_SUPPORTED is not set
|
# end of BACnet Settings
|
||||||
|
|
||||||
|
#
|
||||||
|
# KNX Settings
|
||||||
|
#
|
||||||
|
CONFIG_GATEWAY_KNX_INSTANCE_COUNT=1
|
||||||
|
CONFIG_GATEWAY_KNX_BRIDGE_SUPPORTED=y
|
||||||
|
CONFIG_GATEWAY_START_KNX_BRIDGE_ENABLED=y
|
||||||
|
CONFIG_GATEWAY_KNX_DATA_SECURE_SUPPORTED=y
|
||||||
|
CONFIG_GATEWAY_KNX_IP_SECURE_SUPPORTED=y
|
||||||
|
CONFIG_GATEWAY_KNX_SECURITY_DEV_ENDPOINTS=y
|
||||||
|
CONFIG_GATEWAY_KNX_SECURITY_PLAIN_NVS=y
|
||||||
|
CONFIG_GATEWAY_KNX_OEM_MANUFACTURER_ID=0x01e5
|
||||||
|
CONFIG_GATEWAY_KNX_OEM_HARDWARE_ID=0xa401
|
||||||
|
CONFIG_GATEWAY_KNX_OEM_APPLICATION_NUMBER=0x0001
|
||||||
|
CONFIG_GATEWAY_KNX_OEM_APPLICATION_VERSION=0x08
|
||||||
|
CONFIG_GATEWAY_KNX_MAIN_GROUP=0
|
||||||
|
CONFIG_GATEWAY_KNX_DALI_BUS_ID=0
|
||||||
|
# CONFIG_GATEWAY_KNX_DEBUG_DUMP_MEMORY is not set
|
||||||
|
CONFIG_GATEWAY_KNX_TUNNEL_ENABLED=y
|
||||||
|
CONFIG_GATEWAY_KNX_MULTICAST_ENABLED=y
|
||||||
|
CONFIG_GATEWAY_KNX_UDP_PORT=3671
|
||||||
|
CONFIG_GATEWAY_KNX_MULTICAST_ADDRESS="224.0.23.12"
|
||||||
|
CONFIG_GATEWAY_KNX_IP_INTERFACE_INDIVIDUAL_ADDRESS=65281
|
||||||
|
CONFIG_GATEWAY_KNX_INDIVIDUAL_ADDRESS=65534
|
||||||
|
CONFIG_GATEWAY_KNX_OAM_ROUTER_SUPPORTED=y
|
||||||
|
CONFIG_GATEWAY_KNX_OAM_ROUTER_ENABLED=y
|
||||||
|
CONFIG_GATEWAY_KNX_OAM_ROUTER_OEM_MANUFACTURER_ID=0x00FA
|
||||||
|
CONFIG_GATEWAY_KNX_OAM_ROUTER_HARDWARE_ID=0x0001
|
||||||
|
CONFIG_GATEWAY_KNX_OAM_ROUTER_APPLICATION_NUMBER=0xA11F
|
||||||
|
CONFIG_GATEWAY_KNX_OAM_ROUTER_APPLICATION_VERSION=0x07
|
||||||
|
CONFIG_GATEWAY_KNX_OAM_ROUTER_INDIVIDUAL_ADDRESS=65282
|
||||||
|
CONFIG_GATEWAY_KNX_OAM_ROUTER_TUNNEL_ADDRESS_BASE=65296
|
||||||
|
CONFIG_GATEWAY_KNX_OAM_PROGRAMMING_BUTTON_GPIO=-1
|
||||||
|
CONFIG_GATEWAY_KNX_OAM_PROGRAMMING_LED_GPIO=-1
|
||||||
|
CONFIG_GATEWAY_KNX_PROGRAMMING_BUTTON_GPIO=0
|
||||||
|
CONFIG_GATEWAY_KNX_PROGRAMMING_BUTTON_ACTIVE_LOW=y
|
||||||
|
CONFIG_GATEWAY_KNX_PROGRAMMING_LED_GPIO=10
|
||||||
|
# CONFIG_GATEWAY_KNX_PROGRAMMING_LED_ACTIVE_HIGH is not set
|
||||||
|
CONFIG_GATEWAY_KNX_TP_UART_PORT=0
|
||||||
|
CONFIG_GATEWAY_KNX_TP_TX_PIN=-1
|
||||||
|
CONFIG_GATEWAY_KNX_TP_RX_PIN=-1
|
||||||
|
CONFIG_GATEWAY_KNX_TP_BAUDRATE=19200
|
||||||
|
CONFIG_GATEWAY_KNX_TP_STARTUP_TIMEOUT_MS=2000
|
||||||
|
CONFIG_GATEWAY_KNX_TP_UART_9BIT_MODE=y
|
||||||
|
CONFIG_GATEWAY_KNX_TP_FULL_IP_FORWARD=y
|
||||||
|
CONFIG_GATEWAY_BRIDGE_KNX_TASK_STACK_SIZE=12288
|
||||||
|
CONFIG_GATEWAY_BRIDGE_KNX_TASK_PRIORITY=5
|
||||||
|
# end of KNX Settings
|
||||||
|
|
||||||
|
#
|
||||||
|
# Cloud Settings
|
||||||
|
#
|
||||||
CONFIG_GATEWAY_CLOUD_BRIDGE_SUPPORTED=y
|
CONFIG_GATEWAY_CLOUD_BRIDGE_SUPPORTED=y
|
||||||
# CONFIG_GATEWAY_START_CLOUD_BRIDGE_ENABLED is not set
|
# CONFIG_GATEWAY_START_CLOUD_BRIDGE_ENABLED is not set
|
||||||
|
CONFIG_GATEWAY_CLOUD_TOPIC_PREFIX="devices"
|
||||||
|
CONFIG_GATEWAY_CLOUD_CEMI_TRANSPORT_MQTT=y
|
||||||
|
# CONFIG_GATEWAY_CLOUD_CEMI_TRANSPORT_LTE_UART is not set
|
||||||
|
# CONFIG_GATEWAY_CLOUD_CEMI_TRANSPORT_MQTT_AND_LTE_UART is not set
|
||||||
|
CONFIG_GATEWAY_CLOUD_LTE_UART_PORT=-1
|
||||||
|
CONFIG_GATEWAY_CLOUD_LTE_UART_TX_PIN=-1
|
||||||
|
CONFIG_GATEWAY_CLOUD_LTE_UART_RX_PIN=-1
|
||||||
|
CONFIG_GATEWAY_CLOUD_LTE_UART_BAUDRATE=115200
|
||||||
|
# end of Cloud Settings
|
||||||
|
|
||||||
|
#
|
||||||
|
# Bridge Task Settings
|
||||||
|
#
|
||||||
CONFIG_GATEWAY_BRIDGE_MODBUS_TASK_STACK_SIZE=6144
|
CONFIG_GATEWAY_BRIDGE_MODBUS_TASK_STACK_SIZE=6144
|
||||||
CONFIG_GATEWAY_BRIDGE_MODBUS_TASK_PRIORITY=4
|
CONFIG_GATEWAY_BRIDGE_MODBUS_TASK_PRIORITY=4
|
||||||
CONFIG_GATEWAY_BRIDGE_BACNET_TASK_STACK_SIZE=8192
|
CONFIG_GATEWAY_BRIDGE_BACNET_TASK_STACK_SIZE=8192
|
||||||
CONFIG_GATEWAY_BRIDGE_BACNET_TASK_PRIORITY=5
|
CONFIG_GATEWAY_BRIDGE_BACNET_TASK_PRIORITY=5
|
||||||
|
# end of Bridge Task Settings
|
||||||
|
|
||||||
|
#
|
||||||
|
# USB Setup
|
||||||
|
#
|
||||||
CONFIG_GATEWAY_USB_STARTUP_DEBUG_JTAG=y
|
CONFIG_GATEWAY_USB_STARTUP_DEBUG_JTAG=y
|
||||||
# CONFIG_GATEWAY_USB_STARTUP_SETUP_SERIAL is not set
|
# CONFIG_GATEWAY_USB_STARTUP_SETUP_SERIAL is not set
|
||||||
CONFIG_GATEWAY_485_CONTROL_ENABLED=y
|
# end of USB Setup
|
||||||
CONFIG_GATEWAY_485_CONTROL_BAUDRATE=9600
|
|
||||||
CONFIG_GATEWAY_485_CONTROL_TX_PIN=-1
|
#
|
||||||
CONFIG_GATEWAY_485_CONTROL_RX_PIN=-1
|
# UART0 Control
|
||||||
CONFIG_GATEWAY_485_CONTROL_RX_BUFFER=256
|
#
|
||||||
CONFIG_GATEWAY_485_CONTROL_TX_BUFFER=256
|
# CONFIG_GATEWAY_485_CONTROL_ENABLED is not set
|
||||||
CONFIG_GATEWAY_485_CONTROL_READ_TIMEOUT_MS=20
|
# end of UART0 Control
|
||||||
CONFIG_GATEWAY_485_CONTROL_WRITE_TIMEOUT_MS=20
|
|
||||||
CONFIG_GATEWAY_485_CONTROL_TASK_STACK_SIZE=4096
|
|
||||||
CONFIG_GATEWAY_485_CONTROL_TASK_PRIORITY=4
|
|
||||||
# end of Gateway Startup Services
|
|
||||||
|
|
||||||
#
|
#
|
||||||
# Gateway Network Services
|
# Gateway Network Services
|
||||||
@@ -698,6 +862,8 @@ CONFIG_GATEWAY_STATUS_LED_GPIO=-1
|
|||||||
CONFIG_GATEWAY_BOOT_BUTTON_GPIO=0
|
CONFIG_GATEWAY_BOOT_BUTTON_GPIO=0
|
||||||
CONFIG_GATEWAY_BOOT_BUTTON_ACTIVE_LOW=y
|
CONFIG_GATEWAY_BOOT_BUTTON_ACTIVE_LOW=y
|
||||||
CONFIG_GATEWAY_BOOT_BUTTON_LONG_PRESS_MS=3000
|
CONFIG_GATEWAY_BOOT_BUTTON_LONG_PRESS_MS=3000
|
||||||
|
CONFIG_GATEWAY_SETUP_AP_BUTTON_GPIO=-1
|
||||||
|
CONFIG_GATEWAY_BUTTON_TASK_STACK_SIZE=8192
|
||||||
# end of Gateway Network Services
|
# end of Gateway Network Services
|
||||||
# end of Gateway App
|
# end of Gateway App
|
||||||
|
|
||||||
@@ -771,12 +937,12 @@ CONFIG_BT_CONTROLLER_ENABLED=y
|
|||||||
#
|
#
|
||||||
# General
|
# General
|
||||||
#
|
#
|
||||||
CONFIG_BT_NIMBLE_MEM_ALLOC_MODE_INTERNAL=y
|
# CONFIG_BT_NIMBLE_MEM_ALLOC_MODE_INTERNAL is not set
|
||||||
# CONFIG_BT_NIMBLE_MEM_ALLOC_MODE_EXTERNAL is not set
|
CONFIG_BT_NIMBLE_MEM_ALLOC_MODE_EXTERNAL=y
|
||||||
# CONFIG_BT_NIMBLE_MEM_ALLOC_MODE_DEFAULT is not set
|
# CONFIG_BT_NIMBLE_MEM_ALLOC_MODE_DEFAULT is not set
|
||||||
CONFIG_BT_NIMBLE_PINNED_TO_CORE=0
|
CONFIG_BT_NIMBLE_PINNED_TO_CORE=1
|
||||||
CONFIG_BT_NIMBLE_PINNED_TO_CORE_0=y
|
# CONFIG_BT_NIMBLE_PINNED_TO_CORE_0 is not set
|
||||||
# CONFIG_BT_NIMBLE_PINNED_TO_CORE_1 is not set
|
CONFIG_BT_NIMBLE_PINNED_TO_CORE_1=y
|
||||||
CONFIG_BT_NIMBLE_HOST_TASK_STACK_SIZE=4096
|
CONFIG_BT_NIMBLE_HOST_TASK_STACK_SIZE=4096
|
||||||
CONFIG_BT_NIMBLE_LEGACY_VHCI_ENABLE=y
|
CONFIG_BT_NIMBLE_LEGACY_VHCI_ENABLE=y
|
||||||
# end of General
|
# end of General
|
||||||
@@ -818,7 +984,7 @@ CONFIG_BT_NIMBLE_MAX_CONN_REATTEMPT=3
|
|||||||
CONFIG_BT_NIMBLE_HS_PVCY=y
|
CONFIG_BT_NIMBLE_HS_PVCY=y
|
||||||
# CONFIG_BT_NIMBLE_HOST_ALLOW_CONNECT_WITH_SCAN is not set
|
# CONFIG_BT_NIMBLE_HOST_ALLOW_CONNECT_WITH_SCAN is not set
|
||||||
# CONFIG_BT_NIMBLE_HOST_QUEUE_CONG_CHECK is not set
|
# CONFIG_BT_NIMBLE_HOST_QUEUE_CONG_CHECK is not set
|
||||||
CONFIG_BT_NIMBLE_MAX_CONNECTIONS=3
|
CONFIG_BT_NIMBLE_MAX_CONNECTIONS=4
|
||||||
CONFIG_BT_NIMBLE_MAX_CCCDS=8
|
CONFIG_BT_NIMBLE_MAX_CCCDS=8
|
||||||
CONFIG_BT_NIMBLE_CRYPTO_STACK_MBEDTLS=y
|
CONFIG_BT_NIMBLE_CRYPTO_STACK_MBEDTLS=y
|
||||||
CONFIG_BT_NIMBLE_HS_STOP_TIMEOUT_MS=2000
|
CONFIG_BT_NIMBLE_HS_STOP_TIMEOUT_MS=2000
|
||||||
@@ -981,10 +1147,10 @@ CONFIG_BT_NIMBLE_HCI_UART_CTS_PIN=23
|
|||||||
# CONFIG_BT_NIMBLE_MEM_DEBUG is not set
|
# CONFIG_BT_NIMBLE_MEM_DEBUG is not set
|
||||||
# CONFIG_BT_NIMBLE_LOG_LEVEL_NONE is not set
|
# CONFIG_BT_NIMBLE_LOG_LEVEL_NONE is not set
|
||||||
# CONFIG_BT_NIMBLE_LOG_LEVEL_ERROR is not set
|
# CONFIG_BT_NIMBLE_LOG_LEVEL_ERROR is not set
|
||||||
# CONFIG_BT_NIMBLE_LOG_LEVEL_WARNING is not set
|
CONFIG_BT_NIMBLE_LOG_LEVEL_WARNING=y
|
||||||
CONFIG_BT_NIMBLE_LOG_LEVEL_INFO=y
|
# CONFIG_BT_NIMBLE_LOG_LEVEL_INFO is not set
|
||||||
# CONFIG_BT_NIMBLE_LOG_LEVEL_DEBUG is not set
|
# CONFIG_BT_NIMBLE_LOG_LEVEL_DEBUG is not set
|
||||||
CONFIG_BT_NIMBLE_LOG_LEVEL=1
|
CONFIG_BT_NIMBLE_LOG_LEVEL=2
|
||||||
CONFIG_BT_NIMBLE_PRINT_ERR_NAME=y
|
CONFIG_BT_NIMBLE_PRINT_ERR_NAME=y
|
||||||
# CONFIG_BT_NIMBLE_DEBUG is not set
|
# CONFIG_BT_NIMBLE_DEBUG is not set
|
||||||
# CONFIG_BT_NIMBLE_TEST_THROUGHPUT_TEST is not set
|
# CONFIG_BT_NIMBLE_TEST_THROUGHPUT_TEST is not set
|
||||||
@@ -1013,9 +1179,9 @@ CONFIG_BT_CTRL_MODE_EFF=1
|
|||||||
CONFIG_BT_CTRL_BLE_MAX_ACT=6
|
CONFIG_BT_CTRL_BLE_MAX_ACT=6
|
||||||
CONFIG_BT_CTRL_BLE_MAX_ACT_EFF=6
|
CONFIG_BT_CTRL_BLE_MAX_ACT_EFF=6
|
||||||
CONFIG_BT_CTRL_BLE_STATIC_ACL_TX_BUF_NB=0
|
CONFIG_BT_CTRL_BLE_STATIC_ACL_TX_BUF_NB=0
|
||||||
CONFIG_BT_CTRL_PINNED_TO_CORE_0=y
|
# CONFIG_BT_CTRL_PINNED_TO_CORE_0 is not set
|
||||||
# CONFIG_BT_CTRL_PINNED_TO_CORE_1 is not set
|
CONFIG_BT_CTRL_PINNED_TO_CORE_1=y
|
||||||
CONFIG_BT_CTRL_PINNED_TO_CORE=0
|
CONFIG_BT_CTRL_PINNED_TO_CORE=1
|
||||||
CONFIG_BT_CTRL_HCI_MODE_VHCI=y
|
CONFIG_BT_CTRL_HCI_MODE_VHCI=y
|
||||||
# CONFIG_BT_CTRL_HCI_MODE_UART_H4 is not set
|
# CONFIG_BT_CTRL_HCI_MODE_UART_H4 is not set
|
||||||
CONFIG_BT_CTRL_HCI_TL=1
|
CONFIG_BT_CTRL_HCI_TL=1
|
||||||
@@ -1278,15 +1444,15 @@ CONFIG_ESP_ERR_TO_NAME_LOOKUP=y
|
|||||||
#
|
#
|
||||||
# ESP-Driver:GPIO Configurations
|
# ESP-Driver:GPIO Configurations
|
||||||
#
|
#
|
||||||
# CONFIG_GPIO_CTRL_FUNC_IN_IRAM is not set
|
CONFIG_GPIO_CTRL_FUNC_IN_IRAM=y
|
||||||
# end of ESP-Driver:GPIO Configurations
|
# end of ESP-Driver:GPIO Configurations
|
||||||
|
|
||||||
#
|
#
|
||||||
# ESP-Driver:GPTimer Configurations
|
# ESP-Driver:GPTimer Configurations
|
||||||
#
|
#
|
||||||
CONFIG_GPTIMER_ISR_HANDLER_IN_IRAM=y
|
CONFIG_GPTIMER_ISR_HANDLER_IN_IRAM=y
|
||||||
# CONFIG_GPTIMER_CTRL_FUNC_IN_IRAM is not set
|
CONFIG_GPTIMER_CTRL_FUNC_IN_IRAM=y
|
||||||
# CONFIG_GPTIMER_ISR_CACHE_SAFE is not set
|
CONFIG_GPTIMER_ISR_CACHE_SAFE=y
|
||||||
CONFIG_GPTIMER_OBJ_CACHE_SAFE=y
|
CONFIG_GPTIMER_OBJ_CACHE_SAFE=y
|
||||||
# CONFIG_GPTIMER_ENABLE_DEBUG_LOG is not set
|
# CONFIG_GPTIMER_ENABLE_DEBUG_LOG is not set
|
||||||
# end of ESP-Driver:GPTimer Configurations
|
# end of ESP-Driver:GPTimer Configurations
|
||||||
@@ -1619,7 +1785,7 @@ CONFIG_ESP_NETIF_TCPIP_LWIP=y
|
|||||||
# CONFIG_ESP_NETIF_LOOPBACK is not set
|
# CONFIG_ESP_NETIF_LOOPBACK is not set
|
||||||
CONFIG_ESP_NETIF_USES_TCPIP_WITH_BSD_API=y
|
CONFIG_ESP_NETIF_USES_TCPIP_WITH_BSD_API=y
|
||||||
CONFIG_ESP_NETIF_REPORT_DATA_TRAFFIC=y
|
CONFIG_ESP_NETIF_REPORT_DATA_TRAFFIC=y
|
||||||
# CONFIG_ESP_NETIF_RECEIVE_REPORT_ERRORS is not set
|
CONFIG_ESP_NETIF_RECEIVE_REPORT_ERRORS=y
|
||||||
# CONFIG_ESP_NETIF_L2_TAP is not set
|
# CONFIG_ESP_NETIF_L2_TAP is not set
|
||||||
# CONFIG_ESP_NETIF_BRIDGE_EN is not set
|
# CONFIG_ESP_NETIF_BRIDGE_EN is not set
|
||||||
# CONFIG_ESP_NETIF_SET_DNS_PER_DEFAULT_NETIF is not set
|
# CONFIG_ESP_NETIF_SET_DNS_PER_DEFAULT_NETIF is not set
|
||||||
@@ -1695,7 +1861,7 @@ CONFIG_SPIRAM_USE_MALLOC=y
|
|||||||
CONFIG_SPIRAM_MEMTEST=y
|
CONFIG_SPIRAM_MEMTEST=y
|
||||||
CONFIG_SPIRAM_MALLOC_ALWAYSINTERNAL=16384
|
CONFIG_SPIRAM_MALLOC_ALWAYSINTERNAL=16384
|
||||||
CONFIG_SPIRAM_TRY_ALLOCATE_WIFI_LWIP=y
|
CONFIG_SPIRAM_TRY_ALLOCATE_WIFI_LWIP=y
|
||||||
CONFIG_SPIRAM_MALLOC_RESERVE_INTERNAL=32768
|
CONFIG_SPIRAM_MALLOC_RESERVE_INTERNAL=65535
|
||||||
# CONFIG_SPIRAM_ALLOW_BSS_SEG_EXTERNAL_MEMORY is not set
|
# CONFIG_SPIRAM_ALLOW_BSS_SEG_EXTERNAL_MEMORY is not set
|
||||||
# CONFIG_SPIRAM_ALLOW_NOINIT_SEG_EXTERNAL_MEMORY is not set
|
# CONFIG_SPIRAM_ALLOW_NOINIT_SEG_EXTERNAL_MEMORY is not set
|
||||||
# end of SPI RAM config
|
# end of SPI RAM config
|
||||||
@@ -1722,9 +1888,9 @@ CONFIG_ESP_ROM_PRINT_IN_IRAM=y
|
|||||||
# ESP System Settings
|
# ESP System Settings
|
||||||
#
|
#
|
||||||
# CONFIG_ESP_DEFAULT_CPU_FREQ_MHZ_80 is not set
|
# CONFIG_ESP_DEFAULT_CPU_FREQ_MHZ_80 is not set
|
||||||
CONFIG_ESP_DEFAULT_CPU_FREQ_MHZ_160=y
|
# CONFIG_ESP_DEFAULT_CPU_FREQ_MHZ_160 is not set
|
||||||
# CONFIG_ESP_DEFAULT_CPU_FREQ_MHZ_240 is not set
|
CONFIG_ESP_DEFAULT_CPU_FREQ_MHZ_240=y
|
||||||
CONFIG_ESP_DEFAULT_CPU_FREQ_MHZ=160
|
CONFIG_ESP_DEFAULT_CPU_FREQ_MHZ=240
|
||||||
|
|
||||||
#
|
#
|
||||||
# Cache config
|
# Cache config
|
||||||
@@ -1770,7 +1936,7 @@ CONFIG_ESP_SYSTEM_IN_IRAM=y
|
|||||||
CONFIG_ESP_SYSTEM_PANIC_PRINT_REBOOT=y
|
CONFIG_ESP_SYSTEM_PANIC_PRINT_REBOOT=y
|
||||||
# CONFIG_ESP_SYSTEM_PANIC_SILENT_REBOOT is not set
|
# CONFIG_ESP_SYSTEM_PANIC_SILENT_REBOOT is not set
|
||||||
# CONFIG_ESP_SYSTEM_PANIC_GDBSTUB is not set
|
# CONFIG_ESP_SYSTEM_PANIC_GDBSTUB is not set
|
||||||
CONFIG_ESP_SYSTEM_PANIC_REBOOT_DELAY_SECONDS=0
|
CONFIG_ESP_SYSTEM_PANIC_REBOOT_DELAY_SECONDS=2
|
||||||
CONFIG_ESP_SYSTEM_RTC_FAST_MEM_AS_HEAP_DEPCHECK=y
|
CONFIG_ESP_SYSTEM_RTC_FAST_MEM_AS_HEAP_DEPCHECK=y
|
||||||
CONFIG_ESP_SYSTEM_ALLOW_RTC_FAST_MEM_AS_HEAP=y
|
CONFIG_ESP_SYSTEM_ALLOW_RTC_FAST_MEM_AS_HEAP=y
|
||||||
|
|
||||||
@@ -1783,7 +1949,7 @@ CONFIG_ESP_SYSTEM_MEMPROT_FEATURE_LOCK=y
|
|||||||
|
|
||||||
CONFIG_ESP_SYSTEM_EVENT_QUEUE_SIZE=32
|
CONFIG_ESP_SYSTEM_EVENT_QUEUE_SIZE=32
|
||||||
CONFIG_ESP_SYSTEM_EVENT_TASK_STACK_SIZE=2304
|
CONFIG_ESP_SYSTEM_EVENT_TASK_STACK_SIZE=2304
|
||||||
CONFIG_ESP_MAIN_TASK_STACK_SIZE=3584
|
CONFIG_ESP_MAIN_TASK_STACK_SIZE=8192
|
||||||
CONFIG_ESP_MAIN_TASK_AFFINITY_CPU0=y
|
CONFIG_ESP_MAIN_TASK_AFFINITY_CPU0=y
|
||||||
# CONFIG_ESP_MAIN_TASK_AFFINITY_CPU1 is not set
|
# CONFIG_ESP_MAIN_TASK_AFFINITY_CPU1 is not set
|
||||||
# CONFIG_ESP_MAIN_TASK_AFFINITY_NO_AFFINITY is not set
|
# CONFIG_ESP_MAIN_TASK_AFFINITY_NO_AFFINITY is not set
|
||||||
@@ -1850,9 +2016,9 @@ CONFIG_ESP_WIFI_DYNAMIC_RX_BUFFER_NUM=32
|
|||||||
CONFIG_ESP_WIFI_DYNAMIC_TX_BUFFER=y
|
CONFIG_ESP_WIFI_DYNAMIC_TX_BUFFER=y
|
||||||
CONFIG_ESP_WIFI_TX_BUFFER_TYPE=1
|
CONFIG_ESP_WIFI_TX_BUFFER_TYPE=1
|
||||||
CONFIG_ESP_WIFI_DYNAMIC_TX_BUFFER_NUM=32
|
CONFIG_ESP_WIFI_DYNAMIC_TX_BUFFER_NUM=32
|
||||||
CONFIG_ESP_WIFI_STATIC_RX_MGMT_BUFFER=y
|
# CONFIG_ESP_WIFI_STATIC_RX_MGMT_BUFFER is not set
|
||||||
# CONFIG_ESP_WIFI_DYNAMIC_RX_MGMT_BUFFER is not set
|
CONFIG_ESP_WIFI_DYNAMIC_RX_MGMT_BUFFER=y
|
||||||
CONFIG_ESP_WIFI_DYNAMIC_RX_MGMT_BUF=0
|
CONFIG_ESP_WIFI_DYNAMIC_RX_MGMT_BUF=1
|
||||||
CONFIG_ESP_WIFI_RX_MGMT_BUF_NUM_DEF=5
|
CONFIG_ESP_WIFI_RX_MGMT_BUF_NUM_DEF=5
|
||||||
# CONFIG_ESP_WIFI_CSI_ENABLED is not set
|
# CONFIG_ESP_WIFI_CSI_ENABLED is not set
|
||||||
CONFIG_ESP_WIFI_AMPDU_TX_ENABLED=y
|
CONFIG_ESP_WIFI_AMPDU_TX_ENABLED=y
|
||||||
@@ -1860,8 +2026,8 @@ CONFIG_ESP_WIFI_TX_BA_WIN=6
|
|||||||
CONFIG_ESP_WIFI_AMPDU_RX_ENABLED=y
|
CONFIG_ESP_WIFI_AMPDU_RX_ENABLED=y
|
||||||
CONFIG_ESP_WIFI_RX_BA_WIN=6
|
CONFIG_ESP_WIFI_RX_BA_WIN=6
|
||||||
CONFIG_ESP_WIFI_NVS_ENABLED=y
|
CONFIG_ESP_WIFI_NVS_ENABLED=y
|
||||||
CONFIG_ESP_WIFI_TASK_PINNED_TO_CORE_0=y
|
# CONFIG_ESP_WIFI_TASK_PINNED_TO_CORE_0 is not set
|
||||||
# CONFIG_ESP_WIFI_TASK_PINNED_TO_CORE_1 is not set
|
CONFIG_ESP_WIFI_TASK_PINNED_TO_CORE_1=y
|
||||||
CONFIG_ESP_WIFI_SOFTAP_BEACON_MAX_LEN=752
|
CONFIG_ESP_WIFI_SOFTAP_BEACON_MAX_LEN=752
|
||||||
CONFIG_ESP_WIFI_MGMT_SBUF_NUM=32
|
CONFIG_ESP_WIFI_MGMT_SBUF_NUM=32
|
||||||
CONFIG_ESP_WIFI_IRAM_OPT=y
|
CONFIG_ESP_WIFI_IRAM_OPT=y
|
||||||
@@ -1978,12 +2144,12 @@ CONFIG_FATFS_DONT_TRUST_LAST_ALLOC=0
|
|||||||
#
|
#
|
||||||
# CONFIG_FREERTOS_SMP is not set
|
# CONFIG_FREERTOS_SMP is not set
|
||||||
# CONFIG_FREERTOS_UNICORE is not set
|
# CONFIG_FREERTOS_UNICORE is not set
|
||||||
CONFIG_FREERTOS_HZ=100
|
CONFIG_FREERTOS_HZ=1000
|
||||||
# CONFIG_FREERTOS_CHECK_STACKOVERFLOW_NONE is not set
|
# CONFIG_FREERTOS_CHECK_STACKOVERFLOW_NONE is not set
|
||||||
# CONFIG_FREERTOS_CHECK_STACKOVERFLOW_PTRVAL is not set
|
# CONFIG_FREERTOS_CHECK_STACKOVERFLOW_PTRVAL is not set
|
||||||
CONFIG_FREERTOS_CHECK_STACKOVERFLOW_CANARY=y
|
CONFIG_FREERTOS_CHECK_STACKOVERFLOW_CANARY=y
|
||||||
CONFIG_FREERTOS_THREAD_LOCAL_STORAGE_POINTERS=1
|
CONFIG_FREERTOS_THREAD_LOCAL_STORAGE_POINTERS=1
|
||||||
CONFIG_FREERTOS_IDLE_TASK_STACKSIZE=1536
|
CONFIG_FREERTOS_IDLE_TASK_STACKSIZE=2048
|
||||||
# CONFIG_FREERTOS_USE_IDLE_HOOK is not set
|
# CONFIG_FREERTOS_USE_IDLE_HOOK is not set
|
||||||
# CONFIG_FREERTOS_USE_TICK_HOOK is not set
|
# CONFIG_FREERTOS_USE_TICK_HOOK is not set
|
||||||
CONFIG_FREERTOS_MAX_TASK_NAME_LEN=16
|
CONFIG_FREERTOS_MAX_TASK_NAME_LEN=16
|
||||||
@@ -2156,8 +2322,7 @@ CONFIG_LWIP_GARP_TMR_INTERVAL=60
|
|||||||
CONFIG_LWIP_ESP_MLDV6_REPORT=y
|
CONFIG_LWIP_ESP_MLDV6_REPORT=y
|
||||||
CONFIG_LWIP_MLDV6_TMR_INTERVAL=40
|
CONFIG_LWIP_MLDV6_TMR_INTERVAL=40
|
||||||
CONFIG_LWIP_TCPIP_RECVMBOX_SIZE=32
|
CONFIG_LWIP_TCPIP_RECVMBOX_SIZE=32
|
||||||
CONFIG_LWIP_DHCP_DOES_ARP_CHECK=y
|
CONFIG_LWIP_DHCP_DOES_ACD_CHECK=y
|
||||||
# CONFIG_LWIP_DHCP_DOES_ACD_CHECK is not set
|
|
||||||
# CONFIG_LWIP_DHCP_DOES_NOT_CHECK_OFFERED_IP is not set
|
# CONFIG_LWIP_DHCP_DOES_NOT_CHECK_OFFERED_IP is not set
|
||||||
# CONFIG_LWIP_DHCP_DISABLE_CLIENT_ID is not set
|
# CONFIG_LWIP_DHCP_DISABLE_CLIENT_ID is not set
|
||||||
CONFIG_LWIP_DHCP_DISABLE_VENDOR_CLASS_ID=y
|
CONFIG_LWIP_DHCP_DISABLE_VENDOR_CLASS_ID=y
|
||||||
@@ -2176,13 +2341,16 @@ CONFIG_LWIP_DHCPS_STATIC_ENTRIES=y
|
|||||||
CONFIG_LWIP_DHCPS_ADD_DNS=y
|
CONFIG_LWIP_DHCPS_ADD_DNS=y
|
||||||
# end of DHCP server
|
# end of DHCP server
|
||||||
|
|
||||||
# CONFIG_LWIP_AUTOIP is not set
|
CONFIG_LWIP_AUTOIP=y
|
||||||
|
CONFIG_LWIP_AUTOIP_TRIES=2
|
||||||
|
CONFIG_LWIP_AUTOIP_MAX_CONFLICTS=9
|
||||||
|
CONFIG_LWIP_AUTOIP_RATE_LIMIT_INTERVAL=20
|
||||||
CONFIG_LWIP_IPV4=y
|
CONFIG_LWIP_IPV4=y
|
||||||
CONFIG_LWIP_IPV6=y
|
CONFIG_LWIP_IPV6=y
|
||||||
# CONFIG_LWIP_IPV6_AUTOCONFIG is not set
|
# CONFIG_LWIP_IPV6_AUTOCONFIG is not set
|
||||||
CONFIG_LWIP_IPV6_NUM_ADDRESSES=3
|
CONFIG_LWIP_IPV6_NUM_ADDRESSES=3
|
||||||
# CONFIG_LWIP_IPV6_FORWARD is not set
|
# CONFIG_LWIP_IPV6_FORWARD is not set
|
||||||
# CONFIG_LWIP_NETIF_STATUS_CALLBACK is not set
|
CONFIG_LWIP_NETIF_STATUS_CALLBACK=y
|
||||||
CONFIG_LWIP_NETIF_LOOPBACK=y
|
CONFIG_LWIP_NETIF_LOOPBACK=y
|
||||||
CONFIG_LWIP_LOOPBACK_MAX_PBUFS=8
|
CONFIG_LWIP_LOOPBACK_MAX_PBUFS=8
|
||||||
|
|
||||||
@@ -2312,9 +2480,9 @@ CONFIG_LWIP_HOOK_IP6_INPUT_DEFAULT=y
|
|||||||
#
|
#
|
||||||
# mbedTLS
|
# mbedTLS
|
||||||
#
|
#
|
||||||
CONFIG_MBEDTLS_INTERNAL_MEM_ALLOC=y
|
# CONFIG_MBEDTLS_INTERNAL_MEM_ALLOC is not set
|
||||||
# CONFIG_MBEDTLS_EXTERNAL_MEM_ALLOC is not set
|
# CONFIG_MBEDTLS_EXTERNAL_MEM_ALLOC is not set
|
||||||
# CONFIG_MBEDTLS_DEFAULT_MEM_ALLOC is not set
|
CONFIG_MBEDTLS_DEFAULT_MEM_ALLOC=y
|
||||||
# CONFIG_MBEDTLS_CUSTOM_MEM_ALLOC is not set
|
# CONFIG_MBEDTLS_CUSTOM_MEM_ALLOC is not set
|
||||||
CONFIG_MBEDTLS_ASYMMETRIC_CONTENT_LEN=y
|
CONFIG_MBEDTLS_ASYMMETRIC_CONTENT_LEN=y
|
||||||
CONFIG_MBEDTLS_SSL_IN_CONTENT_LEN=16384
|
CONFIG_MBEDTLS_SSL_IN_CONTENT_LEN=16384
|
||||||
@@ -2478,7 +2646,7 @@ CONFIG_STDATOMIC_S32C1I_SPIRAM_WORKAROUND=y
|
|||||||
# CONFIG_NVS_ENCRYPTION is not set
|
# CONFIG_NVS_ENCRYPTION is not set
|
||||||
# CONFIG_NVS_ASSERT_ERROR_CHECK is not set
|
# CONFIG_NVS_ASSERT_ERROR_CHECK is not set
|
||||||
# CONFIG_NVS_LEGACY_DUP_KEYS_COMPATIBILITY is not set
|
# CONFIG_NVS_LEGACY_DUP_KEYS_COMPATIBILITY is not set
|
||||||
# CONFIG_NVS_ALLOCATE_CACHE_IN_SPIRAM is not set
|
CONFIG_NVS_ALLOCATE_CACHE_IN_SPIRAM=y
|
||||||
# end of NVS
|
# end of NVS
|
||||||
|
|
||||||
#
|
#
|
||||||
@@ -2746,13 +2914,38 @@ CONFIG_WIFI_PROV_STA_ALL_CHANNEL_SCAN=y
|
|||||||
#
|
#
|
||||||
CONFIG_DALI_PHY_COUNT=16
|
CONFIG_DALI_PHY_COUNT=16
|
||||||
CONFIG_DALI_DEFAULT_BAUDRATE=1200
|
CONFIG_DALI_DEFAULT_BAUDRATE=1200
|
||||||
CONFIG_DALI_API_QUEUE_LEN=10
|
CONFIG_DALI_TIMER_RESOLUTION_HZ=3636363
|
||||||
CONFIG_DALI_TX_QUEUE_LEN=1
|
CONFIG_DALI_CUSTOM_HALF_BIT_TIME_X100_US=0
|
||||||
|
CONFIG_DALI_TX_STOP_CONDITION_US=0
|
||||||
|
CONFIG_DALI_RX_STOP_CONDITION_US=0
|
||||||
|
CONFIG_DALI_QUERY_RESPONSE_TIMEOUT_MS=30
|
||||||
|
CONFIG_DALI_DOUBLE_SEND_DELAY_MS=30
|
||||||
|
CONFIG_DALI_FORWARD_ACTIVITY_WAIT_MS=20
|
||||||
|
CONFIG_DALI_FORWARD_AFTER_BACKWARD_WAIT_MS=10
|
||||||
|
CONFIG_DALI_FORWARD_MAX_WAIT_MS=50
|
||||||
|
CONFIG_DALI_BACKWARD_IDLE_TIMEOUT_MS=10
|
||||||
|
CONFIG_DALI_BUS_POWER_CHECK_INTERVAL_MS=500
|
||||||
|
CONFIG_DALI_BUS_FAIL_EVENT_DELAY_MS=45
|
||||||
|
CONFIG_DALI_BUS_ABNORMAL_REPORT_INTERVAL_MS=3000
|
||||||
|
CONFIG_DALI_BUS_RESET_PULSE_MS=10
|
||||||
|
# CONFIG_DALI_LOG_LEVEL_NONE is not set
|
||||||
|
# CONFIG_DALI_LOG_LEVEL_ERROR is not set
|
||||||
|
# CONFIG_DALI_LOG_LEVEL_WARN is not set
|
||||||
|
# CONFIG_DALI_LOG_LEVEL_INFO is not set
|
||||||
|
CONFIG_DALI_LOG_LEVEL_DEBUG=y
|
||||||
|
# CONFIG_DALI_LOG_LEVEL_VERBOSE is not set
|
||||||
|
CONFIG_DALI_LOG_LEVEL=4
|
||||||
|
CONFIG_DALI_TX_ACTIVE_LOW=y
|
||||||
|
# CONFIG_DALI_TX_ACTIVE_HIGH is not set
|
||||||
|
CONFIG_DALI_RX_ACTIVE_LOW=y
|
||||||
|
# CONFIG_DALI_RX_ACTIVE_HIGH is not set
|
||||||
|
CONFIG_DALI_API_QUEUE_LEN=64
|
||||||
|
CONFIG_DALI_TX_QUEUE_LEN=4
|
||||||
CONFIG_DALI_TX_REPLY_QUEUE_LEN=4
|
CONFIG_DALI_TX_REPLY_QUEUE_LEN=4
|
||||||
CONFIG_DALI_RX_QUEUE_LEN=50
|
CONFIG_DALI_RX_QUEUE_LEN=50
|
||||||
CONFIG_DALI_DEBUG_QUEUE_LEN=100
|
CONFIG_DALI_DEBUG_QUEUE_LEN=100
|
||||||
# CONFIG_DALI_ENABLE_DEBUG_TASK is not set
|
CONFIG_DALI_ENABLE_DEBUG_TASK=y
|
||||||
CONFIG_DALI_DALI_TASK_STACK_SIZE=2048
|
CONFIG_DALI_DALI_TASK_STACK_SIZE=8192
|
||||||
CONFIG_DALI_DALI_TASK_PRIORITY=2
|
CONFIG_DALI_DALI_TASK_PRIORITY=2
|
||||||
CONFIG_DALI_DEBUG_TASK_STACK_SIZE=2048
|
CONFIG_DALI_DEBUG_TASK_STACK_SIZE=2048
|
||||||
CONFIG_DALI_DEBUG_TASK_PRIORITY=1
|
CONFIG_DALI_DEBUG_TASK_PRIORITY=1
|
||||||
@@ -2774,10 +2967,12 @@ CONFIG_MQTT_TRANSPORT_SSL=y
|
|||||||
CONFIG_MQTT_TRANSPORT_WEBSOCKET=y
|
CONFIG_MQTT_TRANSPORT_WEBSOCKET=y
|
||||||
CONFIG_MQTT_TRANSPORT_WEBSOCKET_SECURE=y
|
CONFIG_MQTT_TRANSPORT_WEBSOCKET_SECURE=y
|
||||||
# CONFIG_MQTT_MSG_ID_INCREMENTAL is not set
|
# CONFIG_MQTT_MSG_ID_INCREMENTAL is not set
|
||||||
# CONFIG_MQTT_SKIP_PUBLISH_IF_DISCONNECTED is not set
|
CONFIG_MQTT_SKIP_PUBLISH_IF_DISCONNECTED=y
|
||||||
# CONFIG_MQTT_REPORT_DELETED_MESSAGES is not set
|
# CONFIG_MQTT_REPORT_DELETED_MESSAGES is not set
|
||||||
# CONFIG_MQTT_USE_CUSTOM_CONFIG is not set
|
# CONFIG_MQTT_USE_CUSTOM_CONFIG is not set
|
||||||
# CONFIG_MQTT_TASK_CORE_SELECTION_ENABLED is not set
|
CONFIG_MQTT_TASK_CORE_SELECTION_ENABLED=y
|
||||||
|
# CONFIG_MQTT_USE_CORE_0 is not set
|
||||||
|
CONFIG_MQTT_USE_CORE_1=y
|
||||||
# CONFIG_MQTT_CUSTOM_OUTBOX is not set
|
# CONFIG_MQTT_CUSTOM_OUTBOX is not set
|
||||||
# end of ESP-MQTT Configurations
|
# end of ESP-MQTT Configurations
|
||||||
# end of Component config
|
# end of Component config
|
||||||
@@ -2821,12 +3016,12 @@ CONFIG_ESP32_APPTRACE_DEST_NONE=y
|
|||||||
CONFIG_ESP32_APPTRACE_LOCK_ENABLE=y
|
CONFIG_ESP32_APPTRACE_LOCK_ENABLE=y
|
||||||
# CONFIG_BLUEDROID_ENABLED is not set
|
# CONFIG_BLUEDROID_ENABLED is not set
|
||||||
CONFIG_NIMBLE_ENABLED=y
|
CONFIG_NIMBLE_ENABLED=y
|
||||||
CONFIG_NIMBLE_MEM_ALLOC_MODE_INTERNAL=y
|
# CONFIG_NIMBLE_MEM_ALLOC_MODE_INTERNAL is not set
|
||||||
# CONFIG_NIMBLE_MEM_ALLOC_MODE_EXTERNAL is not set
|
CONFIG_NIMBLE_MEM_ALLOC_MODE_EXTERNAL=y
|
||||||
# CONFIG_NIMBLE_MEM_ALLOC_MODE_DEFAULT is not set
|
# CONFIG_NIMBLE_MEM_ALLOC_MODE_DEFAULT is not set
|
||||||
CONFIG_NIMBLE_PINNED_TO_CORE=0
|
CONFIG_NIMBLE_PINNED_TO_CORE=1
|
||||||
CONFIG_NIMBLE_PINNED_TO_CORE_0=y
|
# CONFIG_NIMBLE_PINNED_TO_CORE_0 is not set
|
||||||
# CONFIG_NIMBLE_PINNED_TO_CORE_1 is not set
|
CONFIG_NIMBLE_PINNED_TO_CORE_1=y
|
||||||
CONFIG_NIMBLE_TASK_STACK_SIZE=4096
|
CONFIG_NIMBLE_TASK_STACK_SIZE=4096
|
||||||
CONFIG_BT_NIMBLE_TASK_STACK_SIZE=4096
|
CONFIG_BT_NIMBLE_TASK_STACK_SIZE=4096
|
||||||
CONFIG_NIMBLE_ROLE_CENTRAL=y
|
CONFIG_NIMBLE_ROLE_CENTRAL=y
|
||||||
@@ -2840,7 +3035,7 @@ CONFIG_BT_NIMBLE_SM_SC_LVL=0
|
|||||||
# CONFIG_NIMBLE_NVS_PERSIST is not set
|
# CONFIG_NIMBLE_NVS_PERSIST is not set
|
||||||
CONFIG_NIMBLE_MAX_BONDS=3
|
CONFIG_NIMBLE_MAX_BONDS=3
|
||||||
CONFIG_NIMBLE_RPA_TIMEOUT=900
|
CONFIG_NIMBLE_RPA_TIMEOUT=900
|
||||||
CONFIG_NIMBLE_MAX_CONNECTIONS=3
|
CONFIG_NIMBLE_MAX_CONNECTIONS=4
|
||||||
CONFIG_NIMBLE_MAX_CCCDS=8
|
CONFIG_NIMBLE_MAX_CCCDS=8
|
||||||
CONFIG_NIMBLE_CRYPTO_STACK_MBEDTLS=y
|
CONFIG_NIMBLE_CRYPTO_STACK_MBEDTLS=y
|
||||||
# CONFIG_NIMBLE_HS_FLOW_CTRL is not set
|
# CONFIG_NIMBLE_HS_FLOW_CTRL is not set
|
||||||
@@ -2863,7 +3058,7 @@ CONFIG_SW_COEXIST_ENABLE=y
|
|||||||
CONFIG_ESP32_WIFI_SW_COEXIST_ENABLE=y
|
CONFIG_ESP32_WIFI_SW_COEXIST_ENABLE=y
|
||||||
CONFIG_ESP_WIFI_SW_COEXIST_ENABLE=y
|
CONFIG_ESP_WIFI_SW_COEXIST_ENABLE=y
|
||||||
# CONFIG_CAM_CTLR_DVP_CAM_ISR_IRAM_SAFE is not set
|
# CONFIG_CAM_CTLR_DVP_CAM_ISR_IRAM_SAFE is not set
|
||||||
# CONFIG_GPTIMER_ISR_IRAM_SAFE is not set
|
CONFIG_GPTIMER_ISR_IRAM_SAFE=y
|
||||||
# CONFIG_MCPWM_ISR_IRAM_SAFE is not set
|
# CONFIG_MCPWM_ISR_IRAM_SAFE is not set
|
||||||
# CONFIG_EVENT_LOOP_PROFILING is not set
|
# CONFIG_EVENT_LOOP_PROFILING is not set
|
||||||
CONFIG_POST_EVENTS_FROM_ISR=y
|
CONFIG_POST_EVENTS_FROM_ISR=y
|
||||||
@@ -2910,12 +3105,12 @@ CONFIG_ESP32S3_SPIRAM_SUPPORT=y
|
|||||||
CONFIG_DEFAULT_PSRAM_CLK_IO=30
|
CONFIG_DEFAULT_PSRAM_CLK_IO=30
|
||||||
CONFIG_DEFAULT_PSRAM_CS_IO=26
|
CONFIG_DEFAULT_PSRAM_CS_IO=26
|
||||||
# CONFIG_ESP32S3_DEFAULT_CPU_FREQ_80 is not set
|
# CONFIG_ESP32S3_DEFAULT_CPU_FREQ_80 is not set
|
||||||
CONFIG_ESP32S3_DEFAULT_CPU_FREQ_160=y
|
# CONFIG_ESP32S3_DEFAULT_CPU_FREQ_160 is not set
|
||||||
# CONFIG_ESP32S3_DEFAULT_CPU_FREQ_240 is not set
|
CONFIG_ESP32S3_DEFAULT_CPU_FREQ_240=y
|
||||||
CONFIG_ESP32S3_DEFAULT_CPU_FREQ_MHZ=160
|
CONFIG_ESP32S3_DEFAULT_CPU_FREQ_MHZ=240
|
||||||
CONFIG_SYSTEM_EVENT_QUEUE_SIZE=32
|
CONFIG_SYSTEM_EVENT_QUEUE_SIZE=32
|
||||||
CONFIG_SYSTEM_EVENT_TASK_STACK_SIZE=2304
|
CONFIG_SYSTEM_EVENT_TASK_STACK_SIZE=2304
|
||||||
CONFIG_MAIN_TASK_STACK_SIZE=3584
|
CONFIG_MAIN_TASK_STACK_SIZE=8192
|
||||||
# CONFIG_CONSOLE_UART_DEFAULT is not set
|
# CONFIG_CONSOLE_UART_DEFAULT is not set
|
||||||
# CONFIG_CONSOLE_UART_CUSTOM is not set
|
# CONFIG_CONSOLE_UART_CUSTOM is not set
|
||||||
# CONFIG_CONSOLE_UART_NONE is not set
|
# CONFIG_CONSOLE_UART_NONE is not set
|
||||||
@@ -2947,8 +3142,8 @@ CONFIG_ESP32_WIFI_TX_BA_WIN=6
|
|||||||
CONFIG_ESP32_WIFI_AMPDU_RX_ENABLED=y
|
CONFIG_ESP32_WIFI_AMPDU_RX_ENABLED=y
|
||||||
CONFIG_ESP32_WIFI_RX_BA_WIN=6
|
CONFIG_ESP32_WIFI_RX_BA_WIN=6
|
||||||
CONFIG_ESP32_WIFI_NVS_ENABLED=y
|
CONFIG_ESP32_WIFI_NVS_ENABLED=y
|
||||||
CONFIG_ESP32_WIFI_TASK_PINNED_TO_CORE_0=y
|
# CONFIG_ESP32_WIFI_TASK_PINNED_TO_CORE_0 is not set
|
||||||
# CONFIG_ESP32_WIFI_TASK_PINNED_TO_CORE_1 is not set
|
CONFIG_ESP32_WIFI_TASK_PINNED_TO_CORE_1=y
|
||||||
CONFIG_ESP32_WIFI_SOFTAP_BEACON_MAX_LEN=752
|
CONFIG_ESP32_WIFI_SOFTAP_BEACON_MAX_LEN=752
|
||||||
CONFIG_ESP32_WIFI_MGMT_SBUF_NUM=32
|
CONFIG_ESP32_WIFI_MGMT_SBUF_NUM=32
|
||||||
CONFIG_ESP32_WIFI_IRAM_OPT=y
|
CONFIG_ESP32_WIFI_IRAM_OPT=y
|
||||||
|
|||||||
@@ -7,9 +7,15 @@ CONFIG_PARTITION_TABLE_FILENAME="partitions.csv"
|
|||||||
CONFIG_PARTITION_TABLE_OFFSET=0x8000
|
CONFIG_PARTITION_TABLE_OFFSET=0x8000
|
||||||
CONFIG_PARTITION_TABLE_MD5=y
|
CONFIG_PARTITION_TABLE_MD5=y
|
||||||
|
|
||||||
|
CONFIG_ESP_MAIN_TASK_STACK_SIZE=8192
|
||||||
|
|
||||||
CONFIG_BT_ENABLED=y
|
CONFIG_BT_ENABLED=y
|
||||||
CONFIG_BT_NIMBLE_ENABLED=y
|
CONFIG_BT_NIMBLE_ENABLED=y
|
||||||
|
|
||||||
CONFIG_ETH_ENABLED=y
|
CONFIG_ETH_ENABLED=y
|
||||||
CONFIG_ETH_USE_SPI_ETHERNET=y
|
CONFIG_ETH_USE_SPI_ETHERNET=y
|
||||||
CONFIG_ETH_SPI_ETHERNET_W5500=y
|
CONFIG_ETH_SPI_ETHERNET_W5500=y
|
||||||
|
CONFIG_GATEWAY_ETHERNET_SUPPORTED=y
|
||||||
|
CONFIG_GATEWAY_START_ETHERNET_ENABLED=y
|
||||||
|
CONFIG_GATEWAY_ETHERNET_IGNORE_INIT_FAILURE=y
|
||||||
|
CONFIG_GATEWAY_KNX_DATA_SECURE_SUPPORTED=y
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
+277
-85
@@ -596,56 +596,120 @@ CONFIG_PARTITION_TABLE_MD5=y
|
|||||||
#
|
#
|
||||||
# Gateway App
|
# Gateway App
|
||||||
#
|
#
|
||||||
CONFIG_GATEWAY_CHANNEL_COUNT=2
|
|
||||||
|
#
|
||||||
|
# DALI Settings
|
||||||
|
#
|
||||||
|
CONFIG_GATEWAY_CHANNEL_COUNT=1
|
||||||
|
|
||||||
#
|
#
|
||||||
# Gateway Channel 1
|
# Gateway Channel 1
|
||||||
#
|
#
|
||||||
CONFIG_GATEWAY_CHANNEL1_GW_ID=3
|
CONFIG_GATEWAY_CHANNEL1_GW_ID=0
|
||||||
# CONFIG_GATEWAY_CHANNEL1_PHY_DISABLED is not set
|
# CONFIG_GATEWAY_CHANNEL1_PHY_DISABLED is not set
|
||||||
# CONFIG_GATEWAY_CHANNEL1_PHY_NATIVE is not set
|
CONFIG_GATEWAY_CHANNEL1_PHY_NATIVE=y
|
||||||
CONFIG_GATEWAY_CHANNEL1_PHY_UART1=y
|
# CONFIG_GATEWAY_CHANNEL1_PHY_UART1 is not set
|
||||||
# CONFIG_GATEWAY_CHANNEL1_PHY_UART2 is not set
|
# CONFIG_GATEWAY_CHANNEL1_PHY_UART2 is not set
|
||||||
CONFIG_GATEWAY_CHANNEL1_SERIAL_TX_PIN=1
|
CONFIG_GATEWAY_CHANNEL1_NATIVE_BUS_ID=0
|
||||||
CONFIG_GATEWAY_CHANNEL1_SERIAL_RX_PIN=2
|
CONFIG_GATEWAY_CHANNEL1_NATIVE_TX_PIN=2
|
||||||
CONFIG_GATEWAY_CHANNEL1_SERIAL_BAUDRATE=9600
|
CONFIG_GATEWAY_CHANNEL1_NATIVE_RX_PIN=1
|
||||||
CONFIG_GATEWAY_CHANNEL1_SERIAL_RX_BUFFER=512
|
CONFIG_GATEWAY_CHANNEL1_NATIVE_BAUDRATE=1200
|
||||||
CONFIG_GATEWAY_CHANNEL1_SERIAL_TX_BUFFER=512
|
|
||||||
CONFIG_GATEWAY_CHANNEL1_SERIAL_QUERY_TIMEOUT_MS=100
|
|
||||||
# end of Gateway Channel 1
|
# end of Gateway Channel 1
|
||||||
|
|
||||||
#
|
#
|
||||||
# Gateway Channel 2
|
# Gateway Channel 2
|
||||||
#
|
#
|
||||||
CONFIG_GATEWAY_CHANNEL2_GW_ID=4
|
|
||||||
# CONFIG_GATEWAY_CHANNEL2_PHY_DISABLED is not set
|
|
||||||
# CONFIG_GATEWAY_CHANNEL2_PHY_NATIVE is not set
|
|
||||||
# CONFIG_GATEWAY_CHANNEL2_PHY_UART1 is not set
|
|
||||||
CONFIG_GATEWAY_CHANNEL2_PHY_UART2=y
|
|
||||||
CONFIG_GATEWAY_CHANNEL2_SERIAL_TX_PIN=6
|
|
||||||
CONFIG_GATEWAY_CHANNEL2_SERIAL_RX_PIN=7
|
|
||||||
CONFIG_GATEWAY_CHANNEL2_SERIAL_BAUDRATE=9600
|
|
||||||
CONFIG_GATEWAY_CHANNEL2_SERIAL_RX_BUFFER=512
|
|
||||||
CONFIG_GATEWAY_CHANNEL2_SERIAL_TX_BUFFER=512
|
|
||||||
CONFIG_GATEWAY_CHANNEL2_SERIAL_QUERY_TIMEOUT_MS=100
|
|
||||||
# end of Gateway Channel 2
|
# end of Gateway Channel 2
|
||||||
|
|
||||||
|
#
|
||||||
|
# Gateway Channel 3
|
||||||
|
#
|
||||||
|
# end of Gateway Channel 3
|
||||||
|
|
||||||
|
#
|
||||||
|
# Gateway Channel 4
|
||||||
|
#
|
||||||
|
# end of Gateway Channel 4
|
||||||
|
|
||||||
|
#
|
||||||
|
# Gateway Channel 5
|
||||||
|
#
|
||||||
|
# end of Gateway Channel 5
|
||||||
|
|
||||||
|
#
|
||||||
|
# Gateway Channel 6
|
||||||
|
#
|
||||||
|
# end of Gateway Channel 6
|
||||||
|
|
||||||
|
#
|
||||||
|
# Gateway Channel 7
|
||||||
|
#
|
||||||
|
# end of Gateway Channel 7
|
||||||
|
|
||||||
|
#
|
||||||
|
# Gateway Channel 8
|
||||||
|
#
|
||||||
|
# end of Gateway Channel 8
|
||||||
|
|
||||||
|
#
|
||||||
|
# Gateway Channel 9
|
||||||
|
#
|
||||||
|
# end of Gateway Channel 9
|
||||||
|
|
||||||
|
#
|
||||||
|
# Gateway Channel 10
|
||||||
|
#
|
||||||
|
# end of Gateway Channel 10
|
||||||
|
|
||||||
|
#
|
||||||
|
# Gateway Channel 11
|
||||||
|
#
|
||||||
|
# end of Gateway Channel 11
|
||||||
|
|
||||||
|
#
|
||||||
|
# Gateway Channel 12
|
||||||
|
#
|
||||||
|
# end of Gateway Channel 12
|
||||||
|
|
||||||
|
#
|
||||||
|
# Gateway Channel 13
|
||||||
|
#
|
||||||
|
# end of Gateway Channel 13
|
||||||
|
|
||||||
|
#
|
||||||
|
# Gateway Channel 14
|
||||||
|
#
|
||||||
|
# end of Gateway Channel 14
|
||||||
|
|
||||||
|
#
|
||||||
|
# Gateway Channel 15
|
||||||
|
#
|
||||||
|
# end of Gateway Channel 15
|
||||||
|
|
||||||
|
#
|
||||||
|
# Gateway Channel 16
|
||||||
|
#
|
||||||
|
# end of Gateway Channel 16
|
||||||
|
|
||||||
#
|
#
|
||||||
# Gateway Cache
|
# Gateway Cache
|
||||||
#
|
#
|
||||||
CONFIG_GATEWAY_CACHE_SUPPORTED=y
|
CONFIG_GATEWAY_CACHE_SUPPORTED=y
|
||||||
CONFIG_GATEWAY_CACHE_START_ENABLED=y
|
CONFIG_GATEWAY_CACHE_START_ENABLED=y
|
||||||
CONFIG_GATEWAY_CACHE_RECONCILIATION_ENABLED=y
|
CONFIG_GATEWAY_CACHE_RECONCILIATION_ENABLED=y
|
||||||
# CONFIG_GATEWAY_CACHE_FULL_STATE_MIRROR is not set
|
CONFIG_GATEWAY_CACHE_FULL_STATE_MIRROR=y
|
||||||
CONFIG_GATEWAY_CACHE_FLUSH_INTERVAL_MS=5000
|
CONFIG_GATEWAY_CACHE_FLUSH_INTERVAL_MS=600000
|
||||||
|
CONFIG_GATEWAY_CACHE_REFRESH_INTERVAL_MS=120000
|
||||||
CONFIG_GATEWAY_CACHE_OUTSIDE_BUS_FIRST=y
|
CONFIG_GATEWAY_CACHE_OUTSIDE_BUS_FIRST=y
|
||||||
# CONFIG_GATEWAY_CACHE_LOCAL_GATEWAY_FIRST is not set
|
# CONFIG_GATEWAY_CACHE_LOCAL_GATEWAY_FIRST is not set
|
||||||
# end of Gateway Cache
|
# end of Gateway Cache
|
||||||
|
|
||||||
# CONFIG_GATEWAY_ENABLE_DALI_BUS is not set
|
# CONFIG_GATEWAY_ENABLE_DALI_BUS is not set
|
||||||
|
CONFIG_GATEWAY_CONTROLLER_TASK_STACK_SIZE=12288
|
||||||
|
# end of DALI Settings
|
||||||
|
|
||||||
#
|
#
|
||||||
# Gateway Startup Services
|
# Connectivity Startup
|
||||||
#
|
#
|
||||||
CONFIG_GATEWAY_BLE_SUPPORTED=y
|
CONFIG_GATEWAY_BLE_SUPPORTED=y
|
||||||
CONFIG_GATEWAY_START_BLE_ENABLED=y
|
CONFIG_GATEWAY_START_BLE_ENABLED=y
|
||||||
@@ -656,7 +720,36 @@ CONFIG_GATEWAY_SMARTCONFIG_SUPPORTED=y
|
|||||||
# CONFIG_GATEWAY_START_ESPNOW_SETUP_ENABLED is not set
|
# CONFIG_GATEWAY_START_ESPNOW_SETUP_ENABLED is not set
|
||||||
# CONFIG_GATEWAY_START_SMARTCONFIG_ENABLED is not set
|
# CONFIG_GATEWAY_START_SMARTCONFIG_ENABLED is not set
|
||||||
CONFIG_GATEWAY_SMARTCONFIG_TIMEOUT_SEC=60
|
CONFIG_GATEWAY_SMARTCONFIG_TIMEOUT_SEC=60
|
||||||
|
CONFIG_GATEWAY_ETHERNET_SUPPORTED=y
|
||||||
|
CONFIG_GATEWAY_START_ETHERNET_ENABLED=y
|
||||||
|
CONFIG_GATEWAY_ETHERNET_IGNORE_INIT_FAILURE=y
|
||||||
|
# end of Connectivity Startup
|
||||||
|
|
||||||
|
#
|
||||||
|
# Gateway Wired Ethernet
|
||||||
|
#
|
||||||
|
CONFIG_GATEWAY_ETHERNET_W5500_SPI_HOST=2
|
||||||
|
CONFIG_GATEWAY_ETHERNET_W5500_SCLK_GPIO=48
|
||||||
|
CONFIG_GATEWAY_ETHERNET_W5500_MOSI_GPIO=47
|
||||||
|
CONFIG_GATEWAY_ETHERNET_W5500_MISO_GPIO=33
|
||||||
|
CONFIG_GATEWAY_ETHERNET_W5500_CS_GPIO=34
|
||||||
|
CONFIG_GATEWAY_ETHERNET_W5500_INT_GPIO=36
|
||||||
|
CONFIG_GATEWAY_ETHERNET_W5500_POLL_PERIOD_MS=0
|
||||||
|
CONFIG_GATEWAY_ETHERNET_W5500_CLOCK_MHZ=20
|
||||||
|
CONFIG_GATEWAY_ETHERNET_PHY_RESET_GPIO=-1
|
||||||
|
CONFIG_GATEWAY_ETHERNET_PHY_ADDR=1
|
||||||
|
CONFIG_GATEWAY_ETHERNET_RX_TASK_STACK_SIZE=4096
|
||||||
|
# end of Gateway Wired Ethernet
|
||||||
|
|
||||||
|
#
|
||||||
|
# Bridge Runtime
|
||||||
|
#
|
||||||
CONFIG_GATEWAY_BRIDGE_SUPPORTED=y
|
CONFIG_GATEWAY_BRIDGE_SUPPORTED=y
|
||||||
|
# end of Bridge Runtime
|
||||||
|
|
||||||
|
#
|
||||||
|
# Modbus Settings
|
||||||
|
#
|
||||||
CONFIG_GATEWAY_MODBUS_BRIDGE_SUPPORTED=y
|
CONFIG_GATEWAY_MODBUS_BRIDGE_SUPPORTED=y
|
||||||
# CONFIG_GATEWAY_START_MODBUS_BRIDGE_ENABLED is not set
|
# CONFIG_GATEWAY_START_MODBUS_BRIDGE_ENABLED is not set
|
||||||
CONFIG_GATEWAY_MODBUS_DEFAULT_TRANSPORT_TCP=y
|
CONFIG_GATEWAY_MODBUS_DEFAULT_TRANSPORT_TCP=y
|
||||||
@@ -664,27 +757,99 @@ CONFIG_GATEWAY_MODBUS_DEFAULT_TRANSPORT_TCP=y
|
|||||||
# CONFIG_GATEWAY_MODBUS_DEFAULT_TRANSPORT_ASCII is not set
|
# CONFIG_GATEWAY_MODBUS_DEFAULT_TRANSPORT_ASCII is not set
|
||||||
CONFIG_GATEWAY_MODBUS_TCP_PORT=1502
|
CONFIG_GATEWAY_MODBUS_TCP_PORT=1502
|
||||||
CONFIG_GATEWAY_MODBUS_UNIT_ID=1
|
CONFIG_GATEWAY_MODBUS_UNIT_ID=1
|
||||||
|
# end of Modbus Settings
|
||||||
|
|
||||||
|
#
|
||||||
|
# BACnet Settings
|
||||||
|
#
|
||||||
CONFIG_GATEWAY_BACNET_BRIDGE_SUPPORTED=y
|
CONFIG_GATEWAY_BACNET_BRIDGE_SUPPORTED=y
|
||||||
# CONFIG_GATEWAY_START_BACNET_BRIDGE_ENABLED is not set
|
# CONFIG_GATEWAY_START_BACNET_BRIDGE_ENABLED is not set
|
||||||
|
# end of BACnet Settings
|
||||||
|
|
||||||
|
#
|
||||||
|
# KNX Settings
|
||||||
|
#
|
||||||
|
CONFIG_GATEWAY_KNX_INSTANCE_COUNT=1
|
||||||
|
CONFIG_GATEWAY_KNX_BRIDGE_SUPPORTED=y
|
||||||
|
CONFIG_GATEWAY_START_KNX_BRIDGE_ENABLED=y
|
||||||
|
CONFIG_GATEWAY_KNX_DATA_SECURE_SUPPORTED=y
|
||||||
|
CONFIG_GATEWAY_KNX_IP_SECURE_SUPPORTED=y
|
||||||
|
CONFIG_GATEWAY_KNX_SECURITY_DEV_ENDPOINTS=y
|
||||||
|
CONFIG_GATEWAY_KNX_SECURITY_PLAIN_NVS=y
|
||||||
|
CONFIG_GATEWAY_KNX_OEM_MANUFACTURER_ID=0x01e5
|
||||||
|
CONFIG_GATEWAY_KNX_OEM_HARDWARE_ID=0xa401
|
||||||
|
CONFIG_GATEWAY_KNX_OEM_APPLICATION_NUMBER=0x0001
|
||||||
|
CONFIG_GATEWAY_KNX_OEM_APPLICATION_VERSION=0x08
|
||||||
|
CONFIG_GATEWAY_KNX_MAIN_GROUP=0
|
||||||
|
CONFIG_GATEWAY_KNX_DALI_BUS_ID=0
|
||||||
|
# CONFIG_GATEWAY_KNX_DEBUG_DUMP_MEMORY is not set
|
||||||
|
CONFIG_GATEWAY_KNX_TUNNEL_ENABLED=y
|
||||||
|
CONFIG_GATEWAY_KNX_MULTICAST_ENABLED=y
|
||||||
|
CONFIG_GATEWAY_KNX_UDP_PORT=3671
|
||||||
|
CONFIG_GATEWAY_KNX_MULTICAST_ADDRESS="224.0.23.12"
|
||||||
|
CONFIG_GATEWAY_KNX_IP_INTERFACE_INDIVIDUAL_ADDRESS=65281
|
||||||
|
CONFIG_GATEWAY_KNX_INDIVIDUAL_ADDRESS=65534
|
||||||
|
CONFIG_GATEWAY_KNX_OAM_ROUTER_SUPPORTED=y
|
||||||
|
CONFIG_GATEWAY_KNX_OAM_ROUTER_ENABLED=y
|
||||||
|
CONFIG_GATEWAY_KNX_OAM_ROUTER_OEM_MANUFACTURER_ID=0x00FA
|
||||||
|
CONFIG_GATEWAY_KNX_OAM_ROUTER_HARDWARE_ID=0x0001
|
||||||
|
CONFIG_GATEWAY_KNX_OAM_ROUTER_APPLICATION_NUMBER=0xA11F
|
||||||
|
CONFIG_GATEWAY_KNX_OAM_ROUTER_APPLICATION_VERSION=0x07
|
||||||
|
CONFIG_GATEWAY_KNX_OAM_ROUTER_INDIVIDUAL_ADDRESS=65282
|
||||||
|
CONFIG_GATEWAY_KNX_OAM_ROUTER_TUNNEL_ADDRESS_BASE=65296
|
||||||
|
CONFIG_GATEWAY_KNX_OAM_PROGRAMMING_BUTTON_GPIO=-1
|
||||||
|
CONFIG_GATEWAY_KNX_OAM_PROGRAMMING_LED_GPIO=-1
|
||||||
|
CONFIG_GATEWAY_KNX_PROGRAMMING_BUTTON_GPIO=0
|
||||||
|
CONFIG_GATEWAY_KNX_PROGRAMMING_BUTTON_ACTIVE_LOW=y
|
||||||
|
CONFIG_GATEWAY_KNX_PROGRAMMING_LED_GPIO=10
|
||||||
|
# CONFIG_GATEWAY_KNX_PROGRAMMING_LED_ACTIVE_HIGH is not set
|
||||||
|
CONFIG_GATEWAY_KNX_TP_UART_PORT=0
|
||||||
|
CONFIG_GATEWAY_KNX_TP_TX_PIN=-1
|
||||||
|
CONFIG_GATEWAY_KNX_TP_RX_PIN=-1
|
||||||
|
CONFIG_GATEWAY_KNX_TP_BAUDRATE=19200
|
||||||
|
CONFIG_GATEWAY_KNX_TP_STARTUP_TIMEOUT_MS=2000
|
||||||
|
CONFIG_GATEWAY_KNX_TP_UART_9BIT_MODE=y
|
||||||
|
CONFIG_GATEWAY_KNX_TP_FULL_IP_FORWARD=y
|
||||||
|
CONFIG_GATEWAY_BRIDGE_KNX_TASK_STACK_SIZE=12288
|
||||||
|
CONFIG_GATEWAY_BRIDGE_KNX_TASK_PRIORITY=5
|
||||||
|
# end of KNX Settings
|
||||||
|
|
||||||
|
#
|
||||||
|
# Cloud Settings
|
||||||
|
#
|
||||||
CONFIG_GATEWAY_CLOUD_BRIDGE_SUPPORTED=y
|
CONFIG_GATEWAY_CLOUD_BRIDGE_SUPPORTED=y
|
||||||
# CONFIG_GATEWAY_START_CLOUD_BRIDGE_ENABLED is not set
|
# CONFIG_GATEWAY_START_CLOUD_BRIDGE_ENABLED is not set
|
||||||
|
CONFIG_GATEWAY_CLOUD_TOPIC_PREFIX="devices"
|
||||||
|
CONFIG_GATEWAY_CLOUD_CEMI_TRANSPORT_MQTT=y
|
||||||
|
# CONFIG_GATEWAY_CLOUD_CEMI_TRANSPORT_LTE_UART is not set
|
||||||
|
# CONFIG_GATEWAY_CLOUD_CEMI_TRANSPORT_MQTT_AND_LTE_UART is not set
|
||||||
|
CONFIG_GATEWAY_CLOUD_LTE_UART_PORT=-1
|
||||||
|
CONFIG_GATEWAY_CLOUD_LTE_UART_TX_PIN=-1
|
||||||
|
CONFIG_GATEWAY_CLOUD_LTE_UART_RX_PIN=-1
|
||||||
|
CONFIG_GATEWAY_CLOUD_LTE_UART_BAUDRATE=115200
|
||||||
|
# end of Cloud Settings
|
||||||
|
|
||||||
|
#
|
||||||
|
# Bridge Task Settings
|
||||||
|
#
|
||||||
CONFIG_GATEWAY_BRIDGE_MODBUS_TASK_STACK_SIZE=6144
|
CONFIG_GATEWAY_BRIDGE_MODBUS_TASK_STACK_SIZE=6144
|
||||||
CONFIG_GATEWAY_BRIDGE_MODBUS_TASK_PRIORITY=4
|
CONFIG_GATEWAY_BRIDGE_MODBUS_TASK_PRIORITY=4
|
||||||
CONFIG_GATEWAY_BRIDGE_BACNET_TASK_STACK_SIZE=8192
|
CONFIG_GATEWAY_BRIDGE_BACNET_TASK_STACK_SIZE=8192
|
||||||
CONFIG_GATEWAY_BRIDGE_BACNET_TASK_PRIORITY=5
|
CONFIG_GATEWAY_BRIDGE_BACNET_TASK_PRIORITY=5
|
||||||
|
# end of Bridge Task Settings
|
||||||
|
|
||||||
|
#
|
||||||
|
# USB Setup
|
||||||
|
#
|
||||||
CONFIG_GATEWAY_USB_STARTUP_DEBUG_JTAG=y
|
CONFIG_GATEWAY_USB_STARTUP_DEBUG_JTAG=y
|
||||||
# CONFIG_GATEWAY_USB_STARTUP_SETUP_SERIAL is not set
|
# CONFIG_GATEWAY_USB_STARTUP_SETUP_SERIAL is not set
|
||||||
CONFIG_GATEWAY_485_CONTROL_ENABLED=y
|
# end of USB Setup
|
||||||
CONFIG_GATEWAY_485_CONTROL_BAUDRATE=9600
|
|
||||||
CONFIG_GATEWAY_485_CONTROL_TX_PIN=-1
|
#
|
||||||
CONFIG_GATEWAY_485_CONTROL_RX_PIN=-1
|
# UART0 Control
|
||||||
CONFIG_GATEWAY_485_CONTROL_RX_BUFFER=256
|
#
|
||||||
CONFIG_GATEWAY_485_CONTROL_TX_BUFFER=256
|
# CONFIG_GATEWAY_485_CONTROL_ENABLED is not set
|
||||||
CONFIG_GATEWAY_485_CONTROL_READ_TIMEOUT_MS=20
|
# end of UART0 Control
|
||||||
CONFIG_GATEWAY_485_CONTROL_WRITE_TIMEOUT_MS=20
|
|
||||||
CONFIG_GATEWAY_485_CONTROL_TASK_STACK_SIZE=4096
|
|
||||||
CONFIG_GATEWAY_485_CONTROL_TASK_PRIORITY=4
|
|
||||||
# end of Gateway Startup Services
|
|
||||||
|
|
||||||
#
|
#
|
||||||
# Gateway Network Services
|
# Gateway Network Services
|
||||||
@@ -697,6 +862,8 @@ CONFIG_GATEWAY_STATUS_LED_GPIO=-1
|
|||||||
CONFIG_GATEWAY_BOOT_BUTTON_GPIO=0
|
CONFIG_GATEWAY_BOOT_BUTTON_GPIO=0
|
||||||
CONFIG_GATEWAY_BOOT_BUTTON_ACTIVE_LOW=y
|
CONFIG_GATEWAY_BOOT_BUTTON_ACTIVE_LOW=y
|
||||||
CONFIG_GATEWAY_BOOT_BUTTON_LONG_PRESS_MS=3000
|
CONFIG_GATEWAY_BOOT_BUTTON_LONG_PRESS_MS=3000
|
||||||
|
CONFIG_GATEWAY_SETUP_AP_BUTTON_GPIO=-1
|
||||||
|
CONFIG_GATEWAY_BUTTON_TASK_STACK_SIZE=8192
|
||||||
# end of Gateway Network Services
|
# end of Gateway Network Services
|
||||||
# end of Gateway App
|
# end of Gateway App
|
||||||
|
|
||||||
@@ -744,6 +911,7 @@ CONFIG_COMPILER_ORPHAN_SECTIONS_WARNING=y
|
|||||||
#
|
#
|
||||||
# CONFIG_APPTRACE_DEST_JTAG is not set
|
# CONFIG_APPTRACE_DEST_JTAG is not set
|
||||||
CONFIG_APPTRACE_DEST_NONE=y
|
CONFIG_APPTRACE_DEST_NONE=y
|
||||||
|
# CONFIG_APPTRACE_DEST_UART0 is not set
|
||||||
# CONFIG_APPTRACE_DEST_UART1 is not set
|
# CONFIG_APPTRACE_DEST_UART1 is not set
|
||||||
# CONFIG_APPTRACE_DEST_UART2 is not set
|
# CONFIG_APPTRACE_DEST_UART2 is not set
|
||||||
# CONFIG_APPTRACE_DEST_USB_CDC is not set
|
# CONFIG_APPTRACE_DEST_USB_CDC is not set
|
||||||
@@ -769,12 +937,12 @@ CONFIG_BT_CONTROLLER_ENABLED=y
|
|||||||
#
|
#
|
||||||
# General
|
# General
|
||||||
#
|
#
|
||||||
CONFIG_BT_NIMBLE_MEM_ALLOC_MODE_INTERNAL=y
|
# CONFIG_BT_NIMBLE_MEM_ALLOC_MODE_INTERNAL is not set
|
||||||
# CONFIG_BT_NIMBLE_MEM_ALLOC_MODE_EXTERNAL is not set
|
CONFIG_BT_NIMBLE_MEM_ALLOC_MODE_EXTERNAL=y
|
||||||
# CONFIG_BT_NIMBLE_MEM_ALLOC_MODE_DEFAULT is not set
|
# CONFIG_BT_NIMBLE_MEM_ALLOC_MODE_DEFAULT is not set
|
||||||
CONFIG_BT_NIMBLE_PINNED_TO_CORE=0
|
CONFIG_BT_NIMBLE_PINNED_TO_CORE=1
|
||||||
CONFIG_BT_NIMBLE_PINNED_TO_CORE_0=y
|
# CONFIG_BT_NIMBLE_PINNED_TO_CORE_0 is not set
|
||||||
# CONFIG_BT_NIMBLE_PINNED_TO_CORE_1 is not set
|
CONFIG_BT_NIMBLE_PINNED_TO_CORE_1=y
|
||||||
CONFIG_BT_NIMBLE_HOST_TASK_STACK_SIZE=4096
|
CONFIG_BT_NIMBLE_HOST_TASK_STACK_SIZE=4096
|
||||||
CONFIG_BT_NIMBLE_LEGACY_VHCI_ENABLE=y
|
CONFIG_BT_NIMBLE_LEGACY_VHCI_ENABLE=y
|
||||||
# end of General
|
# end of General
|
||||||
@@ -816,7 +984,7 @@ CONFIG_BT_NIMBLE_MAX_CONN_REATTEMPT=3
|
|||||||
CONFIG_BT_NIMBLE_HS_PVCY=y
|
CONFIG_BT_NIMBLE_HS_PVCY=y
|
||||||
# CONFIG_BT_NIMBLE_HOST_ALLOW_CONNECT_WITH_SCAN is not set
|
# CONFIG_BT_NIMBLE_HOST_ALLOW_CONNECT_WITH_SCAN is not set
|
||||||
# CONFIG_BT_NIMBLE_HOST_QUEUE_CONG_CHECK is not set
|
# CONFIG_BT_NIMBLE_HOST_QUEUE_CONG_CHECK is not set
|
||||||
CONFIG_BT_NIMBLE_MAX_CONNECTIONS=3
|
CONFIG_BT_NIMBLE_MAX_CONNECTIONS=4
|
||||||
CONFIG_BT_NIMBLE_MAX_CCCDS=8
|
CONFIG_BT_NIMBLE_MAX_CCCDS=8
|
||||||
CONFIG_BT_NIMBLE_CRYPTO_STACK_MBEDTLS=y
|
CONFIG_BT_NIMBLE_CRYPTO_STACK_MBEDTLS=y
|
||||||
CONFIG_BT_NIMBLE_HS_STOP_TIMEOUT_MS=2000
|
CONFIG_BT_NIMBLE_HS_STOP_TIMEOUT_MS=2000
|
||||||
@@ -979,10 +1147,10 @@ CONFIG_BT_NIMBLE_HCI_UART_CTS_PIN=23
|
|||||||
# CONFIG_BT_NIMBLE_MEM_DEBUG is not set
|
# CONFIG_BT_NIMBLE_MEM_DEBUG is not set
|
||||||
# CONFIG_BT_NIMBLE_LOG_LEVEL_NONE is not set
|
# CONFIG_BT_NIMBLE_LOG_LEVEL_NONE is not set
|
||||||
# CONFIG_BT_NIMBLE_LOG_LEVEL_ERROR is not set
|
# CONFIG_BT_NIMBLE_LOG_LEVEL_ERROR is not set
|
||||||
# CONFIG_BT_NIMBLE_LOG_LEVEL_WARNING is not set
|
CONFIG_BT_NIMBLE_LOG_LEVEL_WARNING=y
|
||||||
CONFIG_BT_NIMBLE_LOG_LEVEL_INFO=y
|
# CONFIG_BT_NIMBLE_LOG_LEVEL_INFO is not set
|
||||||
# CONFIG_BT_NIMBLE_LOG_LEVEL_DEBUG is not set
|
# CONFIG_BT_NIMBLE_LOG_LEVEL_DEBUG is not set
|
||||||
CONFIG_BT_NIMBLE_LOG_LEVEL=1
|
CONFIG_BT_NIMBLE_LOG_LEVEL=2
|
||||||
CONFIG_BT_NIMBLE_PRINT_ERR_NAME=y
|
CONFIG_BT_NIMBLE_PRINT_ERR_NAME=y
|
||||||
# CONFIG_BT_NIMBLE_DEBUG is not set
|
# CONFIG_BT_NIMBLE_DEBUG is not set
|
||||||
# CONFIG_BT_NIMBLE_TEST_THROUGHPUT_TEST is not set
|
# CONFIG_BT_NIMBLE_TEST_THROUGHPUT_TEST is not set
|
||||||
@@ -1011,9 +1179,9 @@ CONFIG_BT_CTRL_MODE_EFF=1
|
|||||||
CONFIG_BT_CTRL_BLE_MAX_ACT=6
|
CONFIG_BT_CTRL_BLE_MAX_ACT=6
|
||||||
CONFIG_BT_CTRL_BLE_MAX_ACT_EFF=6
|
CONFIG_BT_CTRL_BLE_MAX_ACT_EFF=6
|
||||||
CONFIG_BT_CTRL_BLE_STATIC_ACL_TX_BUF_NB=0
|
CONFIG_BT_CTRL_BLE_STATIC_ACL_TX_BUF_NB=0
|
||||||
CONFIG_BT_CTRL_PINNED_TO_CORE_0=y
|
# CONFIG_BT_CTRL_PINNED_TO_CORE_0 is not set
|
||||||
# CONFIG_BT_CTRL_PINNED_TO_CORE_1 is not set
|
CONFIG_BT_CTRL_PINNED_TO_CORE_1=y
|
||||||
CONFIG_BT_CTRL_PINNED_TO_CORE=0
|
CONFIG_BT_CTRL_PINNED_TO_CORE=1
|
||||||
CONFIG_BT_CTRL_HCI_MODE_VHCI=y
|
CONFIG_BT_CTRL_HCI_MODE_VHCI=y
|
||||||
# CONFIG_BT_CTRL_HCI_MODE_UART_H4 is not set
|
# CONFIG_BT_CTRL_HCI_MODE_UART_H4 is not set
|
||||||
CONFIG_BT_CTRL_HCI_TL=1
|
CONFIG_BT_CTRL_HCI_TL=1
|
||||||
@@ -1276,15 +1444,15 @@ CONFIG_ESP_ERR_TO_NAME_LOOKUP=y
|
|||||||
#
|
#
|
||||||
# ESP-Driver:GPIO Configurations
|
# ESP-Driver:GPIO Configurations
|
||||||
#
|
#
|
||||||
# CONFIG_GPIO_CTRL_FUNC_IN_IRAM is not set
|
CONFIG_GPIO_CTRL_FUNC_IN_IRAM=y
|
||||||
# end of ESP-Driver:GPIO Configurations
|
# end of ESP-Driver:GPIO Configurations
|
||||||
|
|
||||||
#
|
#
|
||||||
# ESP-Driver:GPTimer Configurations
|
# ESP-Driver:GPTimer Configurations
|
||||||
#
|
#
|
||||||
CONFIG_GPTIMER_ISR_HANDLER_IN_IRAM=y
|
CONFIG_GPTIMER_ISR_HANDLER_IN_IRAM=y
|
||||||
# CONFIG_GPTIMER_CTRL_FUNC_IN_IRAM is not set
|
CONFIG_GPTIMER_CTRL_FUNC_IN_IRAM=y
|
||||||
# CONFIG_GPTIMER_ISR_CACHE_SAFE is not set
|
CONFIG_GPTIMER_ISR_CACHE_SAFE=y
|
||||||
CONFIG_GPTIMER_OBJ_CACHE_SAFE=y
|
CONFIG_GPTIMER_OBJ_CACHE_SAFE=y
|
||||||
# CONFIG_GPTIMER_ENABLE_DEBUG_LOG is not set
|
# CONFIG_GPTIMER_ENABLE_DEBUG_LOG is not set
|
||||||
# end of ESP-Driver:GPTimer Configurations
|
# end of ESP-Driver:GPTimer Configurations
|
||||||
@@ -1617,7 +1785,7 @@ CONFIG_ESP_NETIF_TCPIP_LWIP=y
|
|||||||
# CONFIG_ESP_NETIF_LOOPBACK is not set
|
# CONFIG_ESP_NETIF_LOOPBACK is not set
|
||||||
CONFIG_ESP_NETIF_USES_TCPIP_WITH_BSD_API=y
|
CONFIG_ESP_NETIF_USES_TCPIP_WITH_BSD_API=y
|
||||||
CONFIG_ESP_NETIF_REPORT_DATA_TRAFFIC=y
|
CONFIG_ESP_NETIF_REPORT_DATA_TRAFFIC=y
|
||||||
# CONFIG_ESP_NETIF_RECEIVE_REPORT_ERRORS is not set
|
CONFIG_ESP_NETIF_RECEIVE_REPORT_ERRORS=y
|
||||||
# CONFIG_ESP_NETIF_L2_TAP is not set
|
# CONFIG_ESP_NETIF_L2_TAP is not set
|
||||||
# CONFIG_ESP_NETIF_BRIDGE_EN is not set
|
# CONFIG_ESP_NETIF_BRIDGE_EN is not set
|
||||||
# CONFIG_ESP_NETIF_SET_DNS_PER_DEFAULT_NETIF is not set
|
# CONFIG_ESP_NETIF_SET_DNS_PER_DEFAULT_NETIF is not set
|
||||||
@@ -1693,7 +1861,7 @@ CONFIG_SPIRAM_USE_MALLOC=y
|
|||||||
CONFIG_SPIRAM_MEMTEST=y
|
CONFIG_SPIRAM_MEMTEST=y
|
||||||
CONFIG_SPIRAM_MALLOC_ALWAYSINTERNAL=16384
|
CONFIG_SPIRAM_MALLOC_ALWAYSINTERNAL=16384
|
||||||
CONFIG_SPIRAM_TRY_ALLOCATE_WIFI_LWIP=y
|
CONFIG_SPIRAM_TRY_ALLOCATE_WIFI_LWIP=y
|
||||||
CONFIG_SPIRAM_MALLOC_RESERVE_INTERNAL=32768
|
CONFIG_SPIRAM_MALLOC_RESERVE_INTERNAL=65535
|
||||||
# CONFIG_SPIRAM_ALLOW_BSS_SEG_EXTERNAL_MEMORY is not set
|
# CONFIG_SPIRAM_ALLOW_BSS_SEG_EXTERNAL_MEMORY is not set
|
||||||
# CONFIG_SPIRAM_ALLOW_NOINIT_SEG_EXTERNAL_MEMORY is not set
|
# CONFIG_SPIRAM_ALLOW_NOINIT_SEG_EXTERNAL_MEMORY is not set
|
||||||
# end of SPI RAM config
|
# end of SPI RAM config
|
||||||
@@ -1720,9 +1888,9 @@ CONFIG_ESP_ROM_PRINT_IN_IRAM=y
|
|||||||
# ESP System Settings
|
# ESP System Settings
|
||||||
#
|
#
|
||||||
# CONFIG_ESP_DEFAULT_CPU_FREQ_MHZ_80 is not set
|
# CONFIG_ESP_DEFAULT_CPU_FREQ_MHZ_80 is not set
|
||||||
CONFIG_ESP_DEFAULT_CPU_FREQ_MHZ_160=y
|
# CONFIG_ESP_DEFAULT_CPU_FREQ_MHZ_160 is not set
|
||||||
# CONFIG_ESP_DEFAULT_CPU_FREQ_MHZ_240 is not set
|
CONFIG_ESP_DEFAULT_CPU_FREQ_MHZ_240=y
|
||||||
CONFIG_ESP_DEFAULT_CPU_FREQ_MHZ=160
|
CONFIG_ESP_DEFAULT_CPU_FREQ_MHZ=240
|
||||||
|
|
||||||
#
|
#
|
||||||
# Cache config
|
# Cache config
|
||||||
@@ -1768,7 +1936,7 @@ CONFIG_ESP_SYSTEM_IN_IRAM=y
|
|||||||
CONFIG_ESP_SYSTEM_PANIC_PRINT_REBOOT=y
|
CONFIG_ESP_SYSTEM_PANIC_PRINT_REBOOT=y
|
||||||
# CONFIG_ESP_SYSTEM_PANIC_SILENT_REBOOT is not set
|
# CONFIG_ESP_SYSTEM_PANIC_SILENT_REBOOT is not set
|
||||||
# CONFIG_ESP_SYSTEM_PANIC_GDBSTUB is not set
|
# CONFIG_ESP_SYSTEM_PANIC_GDBSTUB is not set
|
||||||
CONFIG_ESP_SYSTEM_PANIC_REBOOT_DELAY_SECONDS=0
|
CONFIG_ESP_SYSTEM_PANIC_REBOOT_DELAY_SECONDS=2
|
||||||
CONFIG_ESP_SYSTEM_RTC_FAST_MEM_AS_HEAP_DEPCHECK=y
|
CONFIG_ESP_SYSTEM_RTC_FAST_MEM_AS_HEAP_DEPCHECK=y
|
||||||
CONFIG_ESP_SYSTEM_ALLOW_RTC_FAST_MEM_AS_HEAP=y
|
CONFIG_ESP_SYSTEM_ALLOW_RTC_FAST_MEM_AS_HEAP=y
|
||||||
|
|
||||||
@@ -1781,24 +1949,21 @@ CONFIG_ESP_SYSTEM_MEMPROT_FEATURE_LOCK=y
|
|||||||
|
|
||||||
CONFIG_ESP_SYSTEM_EVENT_QUEUE_SIZE=32
|
CONFIG_ESP_SYSTEM_EVENT_QUEUE_SIZE=32
|
||||||
CONFIG_ESP_SYSTEM_EVENT_TASK_STACK_SIZE=2304
|
CONFIG_ESP_SYSTEM_EVENT_TASK_STACK_SIZE=2304
|
||||||
CONFIG_ESP_MAIN_TASK_STACK_SIZE=3584
|
CONFIG_ESP_MAIN_TASK_STACK_SIZE=8192
|
||||||
CONFIG_ESP_MAIN_TASK_AFFINITY_CPU0=y
|
CONFIG_ESP_MAIN_TASK_AFFINITY_CPU0=y
|
||||||
# CONFIG_ESP_MAIN_TASK_AFFINITY_CPU1 is not set
|
# CONFIG_ESP_MAIN_TASK_AFFINITY_CPU1 is not set
|
||||||
# CONFIG_ESP_MAIN_TASK_AFFINITY_NO_AFFINITY is not set
|
# CONFIG_ESP_MAIN_TASK_AFFINITY_NO_AFFINITY is not set
|
||||||
CONFIG_ESP_MAIN_TASK_AFFINITY=0x0
|
CONFIG_ESP_MAIN_TASK_AFFINITY=0x0
|
||||||
CONFIG_ESP_MINIMAL_SHARED_STACK_SIZE=2048
|
CONFIG_ESP_MINIMAL_SHARED_STACK_SIZE=2048
|
||||||
CONFIG_ESP_CONSOLE_UART_DEFAULT=y
|
# CONFIG_ESP_CONSOLE_UART_DEFAULT is not set
|
||||||
# CONFIG_ESP_CONSOLE_USB_CDC is not set
|
# CONFIG_ESP_CONSOLE_USB_CDC is not set
|
||||||
# CONFIG_ESP_CONSOLE_USB_SERIAL_JTAG is not set
|
CONFIG_ESP_CONSOLE_USB_SERIAL_JTAG=y
|
||||||
# CONFIG_ESP_CONSOLE_UART_CUSTOM is not set
|
# CONFIG_ESP_CONSOLE_UART_CUSTOM is not set
|
||||||
# CONFIG_ESP_CONSOLE_NONE is not set
|
# CONFIG_ESP_CONSOLE_NONE is not set
|
||||||
# CONFIG_ESP_CONSOLE_SECONDARY_NONE is not set
|
CONFIG_ESP_CONSOLE_SECONDARY_NONE=y
|
||||||
CONFIG_ESP_CONSOLE_SECONDARY_USB_SERIAL_JTAG=y
|
|
||||||
CONFIG_ESP_CONSOLE_USB_SERIAL_JTAG_ENABLED=y
|
CONFIG_ESP_CONSOLE_USB_SERIAL_JTAG_ENABLED=y
|
||||||
CONFIG_ESP_CONSOLE_UART=y
|
CONFIG_ESP_CONSOLE_UART_NUM=-1
|
||||||
CONFIG_ESP_CONSOLE_UART_NUM=0
|
CONFIG_ESP_CONSOLE_ROM_SERIAL_PORT_NUM=4
|
||||||
CONFIG_ESP_CONSOLE_ROM_SERIAL_PORT_NUM=0
|
|
||||||
CONFIG_ESP_CONSOLE_UART_BAUDRATE=115200
|
|
||||||
CONFIG_ESP_INT_WDT=y
|
CONFIG_ESP_INT_WDT=y
|
||||||
CONFIG_ESP_INT_WDT_TIMEOUT_MS=300
|
CONFIG_ESP_INT_WDT_TIMEOUT_MS=300
|
||||||
CONFIG_ESP_INT_WDT_CHECK_CPU1=y
|
CONFIG_ESP_INT_WDT_CHECK_CPU1=y
|
||||||
@@ -1851,9 +2016,9 @@ CONFIG_ESP_WIFI_DYNAMIC_RX_BUFFER_NUM=32
|
|||||||
CONFIG_ESP_WIFI_DYNAMIC_TX_BUFFER=y
|
CONFIG_ESP_WIFI_DYNAMIC_TX_BUFFER=y
|
||||||
CONFIG_ESP_WIFI_TX_BUFFER_TYPE=1
|
CONFIG_ESP_WIFI_TX_BUFFER_TYPE=1
|
||||||
CONFIG_ESP_WIFI_DYNAMIC_TX_BUFFER_NUM=32
|
CONFIG_ESP_WIFI_DYNAMIC_TX_BUFFER_NUM=32
|
||||||
CONFIG_ESP_WIFI_STATIC_RX_MGMT_BUFFER=y
|
# CONFIG_ESP_WIFI_STATIC_RX_MGMT_BUFFER is not set
|
||||||
# CONFIG_ESP_WIFI_DYNAMIC_RX_MGMT_BUFFER is not set
|
CONFIG_ESP_WIFI_DYNAMIC_RX_MGMT_BUFFER=y
|
||||||
CONFIG_ESP_WIFI_DYNAMIC_RX_MGMT_BUF=0
|
CONFIG_ESP_WIFI_DYNAMIC_RX_MGMT_BUF=1
|
||||||
CONFIG_ESP_WIFI_RX_MGMT_BUF_NUM_DEF=5
|
CONFIG_ESP_WIFI_RX_MGMT_BUF_NUM_DEF=5
|
||||||
# CONFIG_ESP_WIFI_CSI_ENABLED is not set
|
# CONFIG_ESP_WIFI_CSI_ENABLED is not set
|
||||||
CONFIG_ESP_WIFI_AMPDU_TX_ENABLED=y
|
CONFIG_ESP_WIFI_AMPDU_TX_ENABLED=y
|
||||||
@@ -1861,8 +2026,8 @@ CONFIG_ESP_WIFI_TX_BA_WIN=6
|
|||||||
CONFIG_ESP_WIFI_AMPDU_RX_ENABLED=y
|
CONFIG_ESP_WIFI_AMPDU_RX_ENABLED=y
|
||||||
CONFIG_ESP_WIFI_RX_BA_WIN=6
|
CONFIG_ESP_WIFI_RX_BA_WIN=6
|
||||||
CONFIG_ESP_WIFI_NVS_ENABLED=y
|
CONFIG_ESP_WIFI_NVS_ENABLED=y
|
||||||
CONFIG_ESP_WIFI_TASK_PINNED_TO_CORE_0=y
|
# CONFIG_ESP_WIFI_TASK_PINNED_TO_CORE_0 is not set
|
||||||
# CONFIG_ESP_WIFI_TASK_PINNED_TO_CORE_1 is not set
|
CONFIG_ESP_WIFI_TASK_PINNED_TO_CORE_1=y
|
||||||
CONFIG_ESP_WIFI_SOFTAP_BEACON_MAX_LEN=752
|
CONFIG_ESP_WIFI_SOFTAP_BEACON_MAX_LEN=752
|
||||||
CONFIG_ESP_WIFI_MGMT_SBUF_NUM=32
|
CONFIG_ESP_WIFI_MGMT_SBUF_NUM=32
|
||||||
CONFIG_ESP_WIFI_IRAM_OPT=y
|
CONFIG_ESP_WIFI_IRAM_OPT=y
|
||||||
@@ -1979,12 +2144,12 @@ CONFIG_FATFS_DONT_TRUST_LAST_ALLOC=0
|
|||||||
#
|
#
|
||||||
# CONFIG_FREERTOS_SMP is not set
|
# CONFIG_FREERTOS_SMP is not set
|
||||||
# CONFIG_FREERTOS_UNICORE is not set
|
# CONFIG_FREERTOS_UNICORE is not set
|
||||||
CONFIG_FREERTOS_HZ=100
|
CONFIG_FREERTOS_HZ=1000
|
||||||
# CONFIG_FREERTOS_CHECK_STACKOVERFLOW_NONE is not set
|
# CONFIG_FREERTOS_CHECK_STACKOVERFLOW_NONE is not set
|
||||||
# CONFIG_FREERTOS_CHECK_STACKOVERFLOW_PTRVAL is not set
|
# CONFIG_FREERTOS_CHECK_STACKOVERFLOW_PTRVAL is not set
|
||||||
CONFIG_FREERTOS_CHECK_STACKOVERFLOW_CANARY=y
|
CONFIG_FREERTOS_CHECK_STACKOVERFLOW_CANARY=y
|
||||||
CONFIG_FREERTOS_THREAD_LOCAL_STORAGE_POINTERS=1
|
CONFIG_FREERTOS_THREAD_LOCAL_STORAGE_POINTERS=1
|
||||||
CONFIG_FREERTOS_IDLE_TASK_STACKSIZE=1536
|
CONFIG_FREERTOS_IDLE_TASK_STACKSIZE=2048
|
||||||
# CONFIG_FREERTOS_USE_IDLE_HOOK is not set
|
# CONFIG_FREERTOS_USE_IDLE_HOOK is not set
|
||||||
# CONFIG_FREERTOS_USE_TICK_HOOK is not set
|
# CONFIG_FREERTOS_USE_TICK_HOOK is not set
|
||||||
CONFIG_FREERTOS_MAX_TASK_NAME_LEN=16
|
CONFIG_FREERTOS_MAX_TASK_NAME_LEN=16
|
||||||
@@ -2157,8 +2322,7 @@ CONFIG_LWIP_GARP_TMR_INTERVAL=60
|
|||||||
CONFIG_LWIP_ESP_MLDV6_REPORT=y
|
CONFIG_LWIP_ESP_MLDV6_REPORT=y
|
||||||
CONFIG_LWIP_MLDV6_TMR_INTERVAL=40
|
CONFIG_LWIP_MLDV6_TMR_INTERVAL=40
|
||||||
CONFIG_LWIP_TCPIP_RECVMBOX_SIZE=32
|
CONFIG_LWIP_TCPIP_RECVMBOX_SIZE=32
|
||||||
CONFIG_LWIP_DHCP_DOES_ARP_CHECK=y
|
CONFIG_LWIP_DHCP_DOES_ACD_CHECK=y
|
||||||
# CONFIG_LWIP_DHCP_DOES_ACD_CHECK is not set
|
|
||||||
# CONFIG_LWIP_DHCP_DOES_NOT_CHECK_OFFERED_IP is not set
|
# CONFIG_LWIP_DHCP_DOES_NOT_CHECK_OFFERED_IP is not set
|
||||||
# CONFIG_LWIP_DHCP_DISABLE_CLIENT_ID is not set
|
# CONFIG_LWIP_DHCP_DISABLE_CLIENT_ID is not set
|
||||||
CONFIG_LWIP_DHCP_DISABLE_VENDOR_CLASS_ID=y
|
CONFIG_LWIP_DHCP_DISABLE_VENDOR_CLASS_ID=y
|
||||||
@@ -2177,13 +2341,16 @@ CONFIG_LWIP_DHCPS_STATIC_ENTRIES=y
|
|||||||
CONFIG_LWIP_DHCPS_ADD_DNS=y
|
CONFIG_LWIP_DHCPS_ADD_DNS=y
|
||||||
# end of DHCP server
|
# end of DHCP server
|
||||||
|
|
||||||
# CONFIG_LWIP_AUTOIP is not set
|
CONFIG_LWIP_AUTOIP=y
|
||||||
|
CONFIG_LWIP_AUTOIP_TRIES=2
|
||||||
|
CONFIG_LWIP_AUTOIP_MAX_CONFLICTS=9
|
||||||
|
CONFIG_LWIP_AUTOIP_RATE_LIMIT_INTERVAL=20
|
||||||
CONFIG_LWIP_IPV4=y
|
CONFIG_LWIP_IPV4=y
|
||||||
CONFIG_LWIP_IPV6=y
|
CONFIG_LWIP_IPV6=y
|
||||||
# CONFIG_LWIP_IPV6_AUTOCONFIG is not set
|
# CONFIG_LWIP_IPV6_AUTOCONFIG is not set
|
||||||
CONFIG_LWIP_IPV6_NUM_ADDRESSES=3
|
CONFIG_LWIP_IPV6_NUM_ADDRESSES=3
|
||||||
# CONFIG_LWIP_IPV6_FORWARD is not set
|
# CONFIG_LWIP_IPV6_FORWARD is not set
|
||||||
# CONFIG_LWIP_NETIF_STATUS_CALLBACK is not set
|
CONFIG_LWIP_NETIF_STATUS_CALLBACK=y
|
||||||
CONFIG_LWIP_NETIF_LOOPBACK=y
|
CONFIG_LWIP_NETIF_LOOPBACK=y
|
||||||
CONFIG_LWIP_LOOPBACK_MAX_PBUFS=8
|
CONFIG_LWIP_LOOPBACK_MAX_PBUFS=8
|
||||||
|
|
||||||
@@ -2313,9 +2480,9 @@ CONFIG_LWIP_HOOK_IP6_INPUT_DEFAULT=y
|
|||||||
#
|
#
|
||||||
# mbedTLS
|
# mbedTLS
|
||||||
#
|
#
|
||||||
CONFIG_MBEDTLS_INTERNAL_MEM_ALLOC=y
|
# CONFIG_MBEDTLS_INTERNAL_MEM_ALLOC is not set
|
||||||
# CONFIG_MBEDTLS_EXTERNAL_MEM_ALLOC is not set
|
# CONFIG_MBEDTLS_EXTERNAL_MEM_ALLOC is not set
|
||||||
# CONFIG_MBEDTLS_DEFAULT_MEM_ALLOC is not set
|
CONFIG_MBEDTLS_DEFAULT_MEM_ALLOC=y
|
||||||
# CONFIG_MBEDTLS_CUSTOM_MEM_ALLOC is not set
|
# CONFIG_MBEDTLS_CUSTOM_MEM_ALLOC is not set
|
||||||
CONFIG_MBEDTLS_ASYMMETRIC_CONTENT_LEN=y
|
CONFIG_MBEDTLS_ASYMMETRIC_CONTENT_LEN=y
|
||||||
CONFIG_MBEDTLS_SSL_IN_CONTENT_LEN=16384
|
CONFIG_MBEDTLS_SSL_IN_CONTENT_LEN=16384
|
||||||
@@ -2479,7 +2646,7 @@ CONFIG_STDATOMIC_S32C1I_SPIRAM_WORKAROUND=y
|
|||||||
# CONFIG_NVS_ENCRYPTION is not set
|
# CONFIG_NVS_ENCRYPTION is not set
|
||||||
# CONFIG_NVS_ASSERT_ERROR_CHECK is not set
|
# CONFIG_NVS_ASSERT_ERROR_CHECK is not set
|
||||||
# CONFIG_NVS_LEGACY_DUP_KEYS_COMPATIBILITY is not set
|
# CONFIG_NVS_LEGACY_DUP_KEYS_COMPATIBILITY is not set
|
||||||
# CONFIG_NVS_ALLOCATE_CACHE_IN_SPIRAM is not set
|
CONFIG_NVS_ALLOCATE_CACHE_IN_SPIRAM=y
|
||||||
# end of NVS
|
# end of NVS
|
||||||
|
|
||||||
#
|
#
|
||||||
@@ -2747,13 +2914,36 @@ CONFIG_WIFI_PROV_STA_ALL_CHANNEL_SCAN=y
|
|||||||
#
|
#
|
||||||
CONFIG_DALI_PHY_COUNT=16
|
CONFIG_DALI_PHY_COUNT=16
|
||||||
CONFIG_DALI_DEFAULT_BAUDRATE=1200
|
CONFIG_DALI_DEFAULT_BAUDRATE=1200
|
||||||
CONFIG_DALI_API_QUEUE_LEN=10
|
CONFIG_DALI_TIMER_RESOLUTION_HZ=3636363
|
||||||
CONFIG_DALI_TX_QUEUE_LEN=1
|
CONFIG_DALI_CUSTOM_HALF_BIT_TIME_X100_US=0
|
||||||
|
CONFIG_DALI_TX_STOP_CONDITION_US=0
|
||||||
|
CONFIG_DALI_RX_STOP_CONDITION_US=0
|
||||||
|
CONFIG_DALI_QUERY_RESPONSE_TIMEOUT_MS=30
|
||||||
|
CONFIG_DALI_DOUBLE_SEND_DELAY_MS=20
|
||||||
|
CONFIG_DALI_FORWARD_ACTIVITY_WAIT_MS=20
|
||||||
|
CONFIG_DALI_FORWARD_AFTER_BACKWARD_WAIT_MS=10
|
||||||
|
CONFIG_DALI_FORWARD_MAX_WAIT_MS=50
|
||||||
|
CONFIG_DALI_BACKWARD_IDLE_TIMEOUT_MS=10
|
||||||
|
CONFIG_DALI_BUS_POWER_CHECK_INTERVAL_MS=500
|
||||||
|
CONFIG_DALI_BUS_ABNORMAL_REPORT_INTERVAL_MS=3000
|
||||||
|
# CONFIG_DALI_LOG_LEVEL_NONE is not set
|
||||||
|
# CONFIG_DALI_LOG_LEVEL_ERROR is not set
|
||||||
|
# CONFIG_DALI_LOG_LEVEL_WARN is not set
|
||||||
|
# CONFIG_DALI_LOG_LEVEL_INFO is not set
|
||||||
|
CONFIG_DALI_LOG_LEVEL_DEBUG=y
|
||||||
|
# CONFIG_DALI_LOG_LEVEL_VERBOSE is not set
|
||||||
|
CONFIG_DALI_LOG_LEVEL=4
|
||||||
|
CONFIG_DALI_TX_ACTIVE_LOW=y
|
||||||
|
# CONFIG_DALI_TX_ACTIVE_HIGH is not set
|
||||||
|
CONFIG_DALI_RX_ACTIVE_LOW=y
|
||||||
|
# CONFIG_DALI_RX_ACTIVE_HIGH is not set
|
||||||
|
CONFIG_DALI_API_QUEUE_LEN=64
|
||||||
|
CONFIG_DALI_TX_QUEUE_LEN=4
|
||||||
CONFIG_DALI_TX_REPLY_QUEUE_LEN=4
|
CONFIG_DALI_TX_REPLY_QUEUE_LEN=4
|
||||||
CONFIG_DALI_RX_QUEUE_LEN=50
|
CONFIG_DALI_RX_QUEUE_LEN=50
|
||||||
CONFIG_DALI_DEBUG_QUEUE_LEN=100
|
CONFIG_DALI_DEBUG_QUEUE_LEN=100
|
||||||
# CONFIG_DALI_ENABLE_DEBUG_TASK is not set
|
CONFIG_DALI_ENABLE_DEBUG_TASK=y
|
||||||
CONFIG_DALI_DALI_TASK_STACK_SIZE=2048
|
CONFIG_DALI_DALI_TASK_STACK_SIZE=8192
|
||||||
CONFIG_DALI_DALI_TASK_PRIORITY=2
|
CONFIG_DALI_DALI_TASK_PRIORITY=2
|
||||||
CONFIG_DALI_DEBUG_TASK_STACK_SIZE=2048
|
CONFIG_DALI_DEBUG_TASK_STACK_SIZE=2048
|
||||||
CONFIG_DALI_DEBUG_TASK_PRIORITY=1
|
CONFIG_DALI_DEBUG_TASK_PRIORITY=1
|
||||||
@@ -2775,10 +2965,12 @@ CONFIG_MQTT_TRANSPORT_SSL=y
|
|||||||
CONFIG_MQTT_TRANSPORT_WEBSOCKET=y
|
CONFIG_MQTT_TRANSPORT_WEBSOCKET=y
|
||||||
CONFIG_MQTT_TRANSPORT_WEBSOCKET_SECURE=y
|
CONFIG_MQTT_TRANSPORT_WEBSOCKET_SECURE=y
|
||||||
# CONFIG_MQTT_MSG_ID_INCREMENTAL is not set
|
# CONFIG_MQTT_MSG_ID_INCREMENTAL is not set
|
||||||
# CONFIG_MQTT_SKIP_PUBLISH_IF_DISCONNECTED is not set
|
CONFIG_MQTT_SKIP_PUBLISH_IF_DISCONNECTED=y
|
||||||
# CONFIG_MQTT_REPORT_DELETED_MESSAGES is not set
|
# CONFIG_MQTT_REPORT_DELETED_MESSAGES is not set
|
||||||
# CONFIG_MQTT_USE_CUSTOM_CONFIG is not set
|
# CONFIG_MQTT_USE_CUSTOM_CONFIG is not set
|
||||||
# CONFIG_MQTT_TASK_CORE_SELECTION_ENABLED is not set
|
CONFIG_MQTT_TASK_CORE_SELECTION_ENABLED=y
|
||||||
|
# CONFIG_MQTT_USE_CORE_0 is not set
|
||||||
|
CONFIG_MQTT_USE_CORE_1=y
|
||||||
# CONFIG_MQTT_CUSTOM_OUTBOX is not set
|
# CONFIG_MQTT_CUSTOM_OUTBOX is not set
|
||||||
# end of ESP-MQTT Configurations
|
# end of ESP-MQTT Configurations
|
||||||
# end of Component config
|
# end of Component config
|
||||||
|
|||||||
+187
-1
@@ -14,6 +14,192 @@ config DALI_DEFAULT_BAUDRATE
|
|||||||
help
|
help
|
||||||
Default baudrate used during initialization.
|
Default baudrate used during initialization.
|
||||||
|
|
||||||
|
config DALI_TIMER_RESOLUTION_HZ
|
||||||
|
int "Native DALI timer resolution Hz"
|
||||||
|
range 1000000 8000000
|
||||||
|
default 3636363
|
||||||
|
help
|
||||||
|
GPTimer resolution for native DALI Manchester timing. The default
|
||||||
|
3.636363 MHz timing matches the gateway's tuned 1200 bps behavior for
|
||||||
|
older control gear that needs more recovery margin between commands.
|
||||||
|
|
||||||
|
config DALI_CUSTOM_HALF_BIT_TIME_X100_US
|
||||||
|
int "Custom native DALI half-bit time x100 us"
|
||||||
|
range 0 500000
|
||||||
|
default 0
|
||||||
|
help
|
||||||
|
Development override for the native DALI half-bit period, expressed in
|
||||||
|
1/100 us. Set to 0 to derive the value from the configured baudrate.
|
||||||
|
Standard 1200 bps DALI is 41667, meaning 416.67 us.
|
||||||
|
|
||||||
|
config DALI_TX_STOP_CONDITION_US
|
||||||
|
int "Custom TX stop condition us"
|
||||||
|
range 0 10000
|
||||||
|
default 0
|
||||||
|
help
|
||||||
|
Development override for the native TX stop-condition wait. Set to 0 to
|
||||||
|
use the scaled standard timing.
|
||||||
|
|
||||||
|
config DALI_RX_STOP_CONDITION_US
|
||||||
|
int "Custom RX stop condition us"
|
||||||
|
range 0 10000
|
||||||
|
default 0
|
||||||
|
help
|
||||||
|
Development override for the native RX stop-condition wait. Set to 0 to
|
||||||
|
use the scaled standard timing.
|
||||||
|
|
||||||
|
config DALI_QUERY_RESPONSE_TIMEOUT_MS
|
||||||
|
int "DALI query response timeout ms"
|
||||||
|
range 10 100
|
||||||
|
default 30
|
||||||
|
help
|
||||||
|
Time to wait for a complete backward frame after a forward query has
|
||||||
|
finished transmitting. DALI backward frames start 5.5-10.5 ms after the
|
||||||
|
forward frame and last about 9.95 ms, so 25 ms leaves margin without the
|
||||||
|
legacy 50 ms no-response delay.
|
||||||
|
|
||||||
|
config DALI_DOUBLE_SEND_DELAY_MS
|
||||||
|
int "Double-send delay ms"
|
||||||
|
range 0 100
|
||||||
|
default 20
|
||||||
|
help
|
||||||
|
Delay between the two frames sent by dali_send_double(), measured after
|
||||||
|
the first frame has completed. Exposed for development tuning.
|
||||||
|
|
||||||
|
config DALI_FORWARD_ACTIVITY_WAIT_MS
|
||||||
|
int "Forward-frame wait after bus activity ms"
|
||||||
|
range 0 1000
|
||||||
|
default 20
|
||||||
|
help
|
||||||
|
Minimum delay before sending a 2- to 4-byte forward frame after normal
|
||||||
|
bus activity. This is the native queue anti-collision wait.
|
||||||
|
|
||||||
|
config DALI_FORWARD_AFTER_BACKWARD_WAIT_MS
|
||||||
|
int "Forward-frame wait after backward frame ms"
|
||||||
|
range 0 1000
|
||||||
|
default 10
|
||||||
|
help
|
||||||
|
Minimum delay before sending a 2- to 4-byte forward frame after the last
|
||||||
|
valid 1-byte backward frame received by the native bus.
|
||||||
|
|
||||||
|
config DALI_FORWARD_MAX_WAIT_MS
|
||||||
|
int "Forward-frame maximum queue wait ms"
|
||||||
|
range 0 5000
|
||||||
|
default 50
|
||||||
|
help
|
||||||
|
Maximum time the native queue waits for a forward-frame send window. If
|
||||||
|
no valid send window is reached before this timeout, the frame is
|
||||||
|
dropped with an error status.
|
||||||
|
|
||||||
|
config DALI_BACKWARD_IDLE_TIMEOUT_MS
|
||||||
|
int "Backward-frame idle wait timeout ms"
|
||||||
|
range 0 1000
|
||||||
|
default 10
|
||||||
|
help
|
||||||
|
Time a 1-byte backward frame waits for an idle bus before being sent
|
||||||
|
anyway. Backward frame sends are not echo-verified because collisions
|
||||||
|
during addressing responses are valid DALI behavior.
|
||||||
|
|
||||||
|
config DALI_BUS_POWER_CHECK_INTERVAL_MS
|
||||||
|
int "Bus power-down check interval ms"
|
||||||
|
range 10 5000
|
||||||
|
default 500
|
||||||
|
help
|
||||||
|
Interval used to resample the RX pin while the native DALI bus is marked
|
||||||
|
power-down. This lets the HAL recover when the bus was already powered
|
||||||
|
before gateway startup and no RX edge is generated.
|
||||||
|
|
||||||
|
config DALI_BUS_FAIL_EVENT_DELAY_MS
|
||||||
|
int "Bus fail event delay ms"
|
||||||
|
range 1 60000
|
||||||
|
default 45
|
||||||
|
help
|
||||||
|
Continuous low-bus duration required before publishing the legacy FF FD
|
||||||
|
bus-abnormal raw frame for the first time. Repeat reports are controlled
|
||||||
|
separately by DALI_BUS_ABNORMAL_REPORT_INTERVAL_MS.
|
||||||
|
|
||||||
|
config DALI_BUS_ABNORMAL_REPORT_INTERVAL_MS
|
||||||
|
int "Legacy bus abnormal report interval ms"
|
||||||
|
range 0 60000
|
||||||
|
default 3000
|
||||||
|
help
|
||||||
|
Repeat interval for publishing the legacy two-byte FF FD bus-abnormal raw
|
||||||
|
frame while the native DALI bus remains failed. Set to 0 to disable both
|
||||||
|
the first and repeated reports.
|
||||||
|
|
||||||
|
config DALI_BUS_RESET_PULSE_MS
|
||||||
|
int "Bus reset low pulse ms"
|
||||||
|
range 1 1000
|
||||||
|
default 10
|
||||||
|
help
|
||||||
|
Default duration for the native physical DALI bus reset pulse. The USB
|
||||||
|
setup bridge uses this value for short command 01 00 00.
|
||||||
|
|
||||||
|
choice DALI_LOG_LEVEL_CHOICE
|
||||||
|
prompt "DALI log level"
|
||||||
|
default DALI_LOG_LEVEL_WARN
|
||||||
|
help
|
||||||
|
Runtime log level applied to the native DALI HAL ESP-IDF log tag.
|
||||||
|
|
||||||
|
config DALI_LOG_LEVEL_NONE
|
||||||
|
bool "No output"
|
||||||
|
|
||||||
|
config DALI_LOG_LEVEL_ERROR
|
||||||
|
bool "Error"
|
||||||
|
|
||||||
|
config DALI_LOG_LEVEL_WARN
|
||||||
|
bool "Warning"
|
||||||
|
|
||||||
|
config DALI_LOG_LEVEL_INFO
|
||||||
|
bool "Info"
|
||||||
|
|
||||||
|
config DALI_LOG_LEVEL_DEBUG
|
||||||
|
bool "Debug"
|
||||||
|
|
||||||
|
config DALI_LOG_LEVEL_VERBOSE
|
||||||
|
bool "Verbose"
|
||||||
|
|
||||||
|
endchoice
|
||||||
|
|
||||||
|
config DALI_LOG_LEVEL
|
||||||
|
int
|
||||||
|
default 0 if DALI_LOG_LEVEL_NONE
|
||||||
|
default 1 if DALI_LOG_LEVEL_ERROR
|
||||||
|
default 2 if DALI_LOG_LEVEL_WARN
|
||||||
|
default 3 if DALI_LOG_LEVEL_INFO
|
||||||
|
default 4 if DALI_LOG_LEVEL_DEBUG
|
||||||
|
default 5 if DALI_LOG_LEVEL_VERBOSE
|
||||||
|
|
||||||
|
choice DALI_TX_ACTIVE_LEVEL
|
||||||
|
prompt "DALI TX pin active level"
|
||||||
|
default DALI_TX_ACTIVE_LOW
|
||||||
|
help
|
||||||
|
Select the physical GPIO level that drives the DALI bus active. The
|
||||||
|
native gateway default is TX active low.
|
||||||
|
|
||||||
|
config DALI_TX_ACTIVE_LOW
|
||||||
|
bool "Active low"
|
||||||
|
|
||||||
|
config DALI_TX_ACTIVE_HIGH
|
||||||
|
bool "Active high"
|
||||||
|
|
||||||
|
endchoice
|
||||||
|
|
||||||
|
choice DALI_RX_ACTIVE_LEVEL
|
||||||
|
prompt "DALI RX pin active level"
|
||||||
|
default DALI_RX_ACTIVE_HIGH
|
||||||
|
help
|
||||||
|
Select the physical GPIO level read when the DALI bus is active. The
|
||||||
|
native gateway default is RX active high.
|
||||||
|
|
||||||
|
config DALI_RX_ACTIVE_LOW
|
||||||
|
bool "Active low"
|
||||||
|
|
||||||
|
config DALI_RX_ACTIVE_HIGH
|
||||||
|
bool "Active high"
|
||||||
|
|
||||||
|
endchoice
|
||||||
|
|
||||||
config DALI_API_QUEUE_LEN
|
config DALI_API_QUEUE_LEN
|
||||||
int "Global API queue length"
|
int "Global API queue length"
|
||||||
range 1 64
|
range 1 64
|
||||||
@@ -48,7 +234,7 @@ config DALI_ENABLE_DEBUG_TASK
|
|||||||
config DALI_DALI_TASK_STACK_SIZE
|
config DALI_DALI_TASK_STACK_SIZE
|
||||||
int "DALI task stack size"
|
int "DALI task stack size"
|
||||||
range 1024 8192
|
range 1024 8192
|
||||||
default 2048
|
default 4096
|
||||||
|
|
||||||
config DALI_DALI_TASK_PRIORITY
|
config DALI_DALI_TASK_PRIORITY
|
||||||
int "DALI task priority"
|
int "DALI task priority"
|
||||||
|
|||||||
@@ -41,10 +41,39 @@ void app_main(void) {
|
|||||||
Use `menuconfig` under `DALI Component` to configure:
|
Use `menuconfig` under `DALI Component` to configure:
|
||||||
|
|
||||||
- Bus count and default baudrate.
|
- Bus count and default baudrate.
|
||||||
|
- Native timing values for development, including timer resolution, half-bit period,
|
||||||
|
TX/RX stop conditions, query response timeout, double-send delay, and TX queue
|
||||||
|
arbitration waits.
|
||||||
|
- TX/RX active polarity. The native gateway default is TX active low and RX active high.
|
||||||
|
- Native bus power-down polling, first bus-fail event delay, legacy `FF FD`
|
||||||
|
bus-abnormal raw-frame repeat interval, and physical bus reset pulse duration.
|
||||||
|
- Native DALI HAL log level for the `dali_hal` ESP-IDF log tag.
|
||||||
- Queue sizes.
|
- Queue sizes.
|
||||||
- Task stack sizes and priorities.
|
- Task stack sizes and priorities.
|
||||||
- Optional debug task.
|
- Optional debug task.
|
||||||
|
|
||||||
|
The native bus monitor uses `CONFIG_DALI_BUS_POWER_CHECK_INTERVAL_MS` to resample RX while
|
||||||
|
power-down, `CONFIG_DALI_BUS_FAIL_EVENT_DELAY_MS` to publish the first legacy `FF FD`
|
||||||
|
raw frame after a continuous low-bus failure, and
|
||||||
|
`CONFIG_DALI_BUS_ABNORMAL_REPORT_INTERVAL_MS` for repeat reports while the bus remains
|
||||||
|
failed. The first delay defaults to 45 ms and the repeat interval defaults to 3000 ms;
|
||||||
|
set the repeat interval to 0 to disable the compatibility report. USB setup command
|
||||||
|
`01 00 00` uses `CONFIG_DALI_BUS_RESET_PULSE_MS` to drive the bus low intentionally for
|
||||||
|
a physical reset pulse, defaulting to 10 ms.
|
||||||
|
|
||||||
|
Native timing defaults target standard 1200 bps DALI: a 416.67 us half-bit period is
|
||||||
|
generated by the default 3.636363 MHz timer. `CONFIG_DALI_CUSTOM_HALF_BIT_TIME_X100_US`
|
||||||
|
can override the half-bit period for development; keep it at 0 for baudrate-derived timing.
|
||||||
|
Query no-response timeout defaults to 30 ms, which covers the 5.5-10.5 ms backward-frame
|
||||||
|
start window plus the approximately 9.95 ms backward frame duration.
|
||||||
|
|
||||||
|
Native TX queue arbitration uses frame length as the frame type signal. Two- to four-byte
|
||||||
|
forward frames wait up to `CONFIG_DALI_FORWARD_MAX_WAIT_MS` for a valid send window,
|
||||||
|
using `CONFIG_DALI_FORWARD_ACTIVITY_WAIT_MS` after normal bus activity and
|
||||||
|
`CONFIG_DALI_FORWARD_AFTER_BACKWARD_WAIT_MS` after a valid backward frame. One-byte
|
||||||
|
backward frames wait up to `CONFIG_DALI_BACKWARD_IDLE_TIMEOUT_MS` for idle, then are
|
||||||
|
sent without echo verification because addressing-phase collisions are valid.
|
||||||
|
|
||||||
## API Note
|
## API Note
|
||||||
|
|
||||||
The global TX response queue symbol was renamed:
|
The global TX response queue symbol was renamed:
|
||||||
|
|||||||
@@ -6,6 +6,14 @@
|
|||||||
#include <memory.h> // for memset
|
#include <memory.h> // for memset
|
||||||
#include "freertos/semphr.h"
|
#include "freertos/semphr.h"
|
||||||
|
|
||||||
|
#ifndef CONFIG_DALI_QUERY_RESPONSE_TIMEOUT_MS
|
||||||
|
#define CONFIG_DALI_QUERY_RESPONSE_TIMEOUT_MS 30
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef CONFIG_DALI_DOUBLE_SEND_DELAY_MS
|
||||||
|
#define CONFIG_DALI_DOUBLE_SEND_DELAY_MS 20
|
||||||
|
#endif
|
||||||
|
|
||||||
static SemaphoreHandle_t s_dali_core_lock;
|
static SemaphoreHandle_t s_dali_core_lock;
|
||||||
|
|
||||||
static SemaphoreHandle_t dali_core_mutex(void)
|
static SemaphoreHandle_t dali_core_mutex(void)
|
||||||
@@ -31,6 +39,20 @@ static inline void dali_core_unlock(void)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static UBaseType_t drain_rx_queue(QueueHandle_t rx_q)
|
||||||
|
{
|
||||||
|
if (rx_q == NULL) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
Dali_msg_t stale = {0};
|
||||||
|
UBaseType_t drained = 0;
|
||||||
|
while (xQueueReceive(rx_q, &stale, 0) == pdTRUE) {
|
||||||
|
drained++;
|
||||||
|
}
|
||||||
|
return drained;
|
||||||
|
}
|
||||||
|
|
||||||
Dali_msg_t dali_msg_new_generic(uint8_t bit_length, uint8_t address, uint8_t cmd1, uint8_t cmd2, uint8_t cmd3) {
|
Dali_msg_t dali_msg_new_generic(uint8_t bit_length, uint8_t address, uint8_t cmd1, uint8_t cmd2, uint8_t cmd3) {
|
||||||
Dali_msg_t dali_msg;
|
Dali_msg_t dali_msg;
|
||||||
dali_msg.id = 0;
|
dali_msg.id = 0;
|
||||||
@@ -90,7 +112,7 @@ void dali_send_double(Dali_msg_t *dali_msg) {
|
|||||||
dali_send_locked(dali_msg);
|
dali_send_locked(dali_msg);
|
||||||
// TODO check status
|
// TODO check status
|
||||||
dali_msg->id++; // increment message ID
|
dali_msg->id++; // increment message ID
|
||||||
dali_delay_ms(10); // delay 13ms 101.8.1.2: 13.5 - 75ms
|
dali_delay_ms(CONFIG_DALI_DOUBLE_SEND_DELAY_MS);
|
||||||
dali_send_locked(dali_msg);
|
dali_send_locked(dali_msg);
|
||||||
// TODO check status
|
// TODO check status
|
||||||
dali_core_unlock();
|
dali_core_unlock();
|
||||||
@@ -110,17 +132,16 @@ int dali_query(Dali_msg_t *tx_msg, Dali_msg_t *rx_msg) {
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO check empty queue
|
dali_core_lock();
|
||||||
if(xQueueReceive(rx_q, rx_msg, 0) == pdTRUE) {
|
UBaseType_t drained = drain_rx_queue(rx_q);
|
||||||
printf("Queue not empty\n");
|
if (drained > 0) {
|
||||||
return -1;
|
printf("dali_query: dropped %u stale RX frame(s)\n", (unsigned)drained);
|
||||||
}
|
}
|
||||||
// printf("check A tx=%d tm=%d[ms] st=%d len=%d d0=0x%X\n", ret, tx_msg->type, tx_msg->status, tx_msg->length, tx_msg->data[0]);
|
// printf("check A tx=%d tm=%d[ms] st=%d len=%d d0=0x%X\n", ret, tx_msg->type, tx_msg->status, tx_msg->length, tx_msg->data[0]);
|
||||||
|
|
||||||
dali_core_lock();
|
|
||||||
dali_send_locked(tx_msg);
|
dali_send_locked(tx_msg);
|
||||||
// receive message from DALI task
|
// receive message from DALI task
|
||||||
ret = xQueueReceive(rx_q, rx_msg, pdMS_TO_TICKS(50));
|
ret = xQueueReceive(rx_q, rx_msg, pdMS_TO_TICKS(CONFIG_DALI_QUERY_RESPONSE_TIMEOUT_MS));
|
||||||
dali_core_unlock();
|
dali_core_unlock();
|
||||||
// printf("B rx=%d tm=%d[ms] st=%d len=%d d0=0x%X\n", ret, rx_msg->type, rx_msg->status, rx_msg->length, rx_msg->data[0]);
|
// printf("B rx=%d tm=%d[ms] st=%d len=%d d0=0x%X\n", ret, rx_msg->type, rx_msg->status, rx_msg->length, rx_msg->data[0]);
|
||||||
return ret;
|
return ret;
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -3,6 +3,10 @@
|
|||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include "dali_hal.h"
|
#include "dali_hal.h"
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Addressing: 102.7.2.1
|
Addressing: 102.7.2.1
|
||||||
0AAA AAAx - short address AAAAAA 0-63
|
0AAA AAAx - short address AAAAAA 0-63
|
||||||
@@ -18,6 +22,7 @@ Dali_msg_t dali_msg_new_generic(uint8_t bit_length, uint8_t address, uint8_t cmd
|
|||||||
|
|
||||||
// create standard DALI message: 16,24,32 bits
|
// create standard DALI message: 16,24,32 bits
|
||||||
Dali_msg_t dali_msg_new(uint8_t address, uint8_t cmd1);
|
Dali_msg_t dali_msg_new(uint8_t address, uint8_t cmd1);
|
||||||
|
Dali_msg_t dali_msg_new_1B(uint8_t data);
|
||||||
Dali_msg_t dali_msg_new_3B(uint8_t address, uint8_t cmd1, uint8_t cmd2);
|
Dali_msg_t dali_msg_new_3B(uint8_t address, uint8_t cmd1, uint8_t cmd2);
|
||||||
Dali_msg_t dali_msg_new_4B(uint8_t address, uint8_t cmd1, uint8_t cmd2, uint8_t cmd3);
|
Dali_msg_t dali_msg_new_4B(uint8_t address, uint8_t cmd1, uint8_t cmd2, uint8_t cmd3);
|
||||||
|
|
||||||
@@ -77,5 +82,8 @@ void dali_set_search_addr24(uint32_t addr24);
|
|||||||
uint32_t dali_binary_search();
|
uint32_t dali_binary_search();
|
||||||
void dali_change_short_address(int addr1, int addr2);
|
void dali_change_short_address(int addr1, int addr2);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -8,6 +8,10 @@
|
|||||||
#include "freertos/task.h"
|
#include "freertos/task.h"
|
||||||
#include "freertos/queue.h"
|
#include "freertos/queue.h"
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef CONFIG_DALI_PHY_COUNT
|
#ifdef CONFIG_DALI_PHY_COUNT
|
||||||
#define DALI_PHY_COUNT CONFIG_DALI_PHY_COUNT
|
#define DALI_PHY_COUNT CONFIG_DALI_PHY_COUNT
|
||||||
#else
|
#else
|
||||||
@@ -182,13 +186,22 @@ typedef struct Dali_msg Dali_msg_t;
|
|||||||
|
|
||||||
// define HW DALI for gpio functions
|
// define HW DALI for gpio functions
|
||||||
#ifndef DALI_HW_PINS
|
#ifndef DALI_HW_PINS
|
||||||
// define HW DALI for gpio functions
|
// Physical GPIO levels for logical DALI idle/high and active/low bus states.
|
||||||
// - what we should write to pin to get HIGH/LOW
|
#ifdef CONFIG_DALI_TX_ACTIVE_HIGH
|
||||||
#define DALI_TX_HIGH 1 // idle state
|
#define DALI_TX_HIGH 0 // idle state
|
||||||
#define DALI_TX_LOW 0 // active state
|
#define DALI_TX_LOW 1 // active state
|
||||||
// - what we should read from pin to get HIGH/LOW
|
#else
|
||||||
#define DALI_RX_HIGH 1 // idle state
|
#define DALI_TX_HIGH 1 // idle state
|
||||||
#define DALI_RX_LOW 0 // active state
|
#define DALI_TX_LOW 0 // active state
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef CONFIG_DALI_RX_ACTIVE_LOW
|
||||||
|
#define DALI_RX_HIGH 1 // idle state
|
||||||
|
#define DALI_RX_LOW 0 // active state
|
||||||
|
#else
|
||||||
|
#define DALI_RX_HIGH 0 // idle state
|
||||||
|
#define DALI_RX_LOW 1 // active state
|
||||||
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// LED onboard - debug
|
// LED onboard - debug
|
||||||
@@ -225,6 +238,10 @@ esp_err_t dali_hal_set_baudrate(uint32_t baudrate);
|
|||||||
uint32_t dali_hal_get_baudrate(void);
|
uint32_t dali_hal_get_baudrate(void);
|
||||||
size_t dali_hal_get_inited_buses(uint8_t *ids, size_t max_ids);
|
size_t dali_hal_get_inited_buses(uint8_t *ids, size_t max_ids);
|
||||||
esp_err_t dali_hal_get_bus_info(uint8_t bus_id, dali_hal_bus_info_t *info);
|
esp_err_t dali_hal_get_bus_info(uint8_t bus_id, dali_hal_bus_info_t *info);
|
||||||
|
esp_err_t dali_hal_pulse_bus_low(uint8_t bus_id, uint32_t duration_ms);
|
||||||
QueueHandle_t dali_hal_raw_receive_queue(void);
|
QueueHandle_t dali_hal_raw_receive_queue(void);
|
||||||
void dali_task(void *pvParameters);
|
void dali_task(void *pvParameters);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|||||||
@@ -13,6 +13,7 @@
|
|||||||
|
|
||||||
#include "esp_err.h"
|
#include "esp_err.h"
|
||||||
#include "freertos/FreeRTOS.h"
|
#include "freertos/FreeRTOS.h"
|
||||||
|
#include "freertos/queue.h"
|
||||||
#include "freertos/semphr.h"
|
#include "freertos/semphr.h"
|
||||||
#include "freertos/task.h"
|
#include "freertos/task.h"
|
||||||
|
|
||||||
@@ -68,6 +69,7 @@ struct DaliChannelInfo {
|
|||||||
uint8_t gateway_id{0};
|
uint8_t gateway_id{0};
|
||||||
DaliPhyKind phy_kind{DaliPhyKind::kCustom};
|
DaliPhyKind phy_kind{DaliPhyKind::kCustom};
|
||||||
std::string name;
|
std::string name;
|
||||||
|
std::optional<uint8_t> native_bus_id;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct DaliRawFrame {
|
struct DaliRawFrame {
|
||||||
@@ -81,6 +83,8 @@ enum class DaliDt8SceneColorMode {
|
|||||||
kDisabled,
|
kDisabled,
|
||||||
kColorTemperature,
|
kColorTemperature,
|
||||||
kRgb,
|
kRgb,
|
||||||
|
kRgbw,
|
||||||
|
kRgbcw,
|
||||||
};
|
};
|
||||||
|
|
||||||
struct DaliDomainSnapshot {
|
struct DaliDomainSnapshot {
|
||||||
@@ -125,15 +129,29 @@ class DaliDomainService {
|
|||||||
void addRawFrameSink(std::function<void(const DaliRawFrame& frame)> sink);
|
void addRawFrameSink(std::function<void(const DaliRawFrame& frame)> sink);
|
||||||
|
|
||||||
bool resetBus(uint8_t gateway_id) const;
|
bool resetBus(uint8_t gateway_id) const;
|
||||||
|
bool pulseBusLow(uint8_t gateway_id, uint32_t duration_ms) const;
|
||||||
|
bool isBusIdle(uint8_t gateway_id, uint32_t quiet_ms) const;
|
||||||
|
void markHostActivity(uint8_t gateway_id) const;
|
||||||
|
void markHostCommandFrame(uint8_t gateway_id, uint8_t raw_addr, uint8_t command) const;
|
||||||
|
bool hasRecentHostActivity(uint8_t gateway_id, uint32_t window_ms) const;
|
||||||
|
bool matchesRecentHostCommandFrame(uint8_t gateway_id, uint8_t raw_addr, uint8_t command,
|
||||||
|
uint32_t window_ms) const;
|
||||||
bool writeBridgeFrame(uint8_t gateway_id, const uint8_t* data, size_t len) const;
|
bool writeBridgeFrame(uint8_t gateway_id, const uint8_t* data, size_t len) const;
|
||||||
std::vector<uint8_t> transactBridgeFrame(uint8_t gateway_id, const uint8_t* data,
|
std::vector<uint8_t> transactBridgeFrame(uint8_t gateway_id, const uint8_t* data,
|
||||||
size_t len) const;
|
size_t len) const;
|
||||||
bool sendRaw(uint8_t gateway_id, uint8_t raw_addr, uint8_t command) const;
|
bool sendRaw(uint8_t gateway_id, uint8_t raw_addr, uint8_t command) const;
|
||||||
bool sendExtRaw(uint8_t gateway_id, uint8_t raw_addr, uint8_t command) const;
|
bool sendExtRaw(uint8_t gateway_id, uint8_t raw_addr, uint8_t command) const;
|
||||||
std::optional<uint8_t> queryRaw(uint8_t gateway_id, uint8_t raw_addr, uint8_t command) const;
|
std::optional<uint8_t> queryRaw(uint8_t gateway_id, uint8_t raw_addr, uint8_t command) const;
|
||||||
|
bool sendControlDeviceRaw(uint8_t gateway_id, uint8_t byte0, uint8_t byte1, uint8_t byte2,
|
||||||
|
bool send_twice = false) const;
|
||||||
|
std::optional<uint8_t> queryControlDeviceRaw(uint8_t gateway_id, uint8_t byte0,
|
||||||
|
uint8_t byte1, uint8_t byte2) const;
|
||||||
|
bool sendBackwardFrame(uint8_t gateway_id, uint8_t value) const;
|
||||||
std::optional<DaliDomainSnapshot> discoverDeviceTypes(
|
std::optional<DaliDomainSnapshot> discoverDeviceTypes(
|
||||||
uint8_t gateway_id, int short_address, const std::vector<int>& fallback_types = {},
|
uint8_t gateway_id, int short_address, const std::vector<int>& fallback_types = {},
|
||||||
int max_next_types = 16) const;
|
int max_next_types = 16) const;
|
||||||
|
std::optional<uint8_t> readMemoryLocation(uint8_t gateway_id, int short_address, uint8_t bank,
|
||||||
|
uint8_t location) const;
|
||||||
std::optional<DaliDomainSnapshot> baseStatusSnapshot(uint8_t gateway_id,
|
std::optional<DaliDomainSnapshot> baseStatusSnapshot(uint8_t gateway_id,
|
||||||
int short_address) const;
|
int short_address) const;
|
||||||
std::optional<DaliDomainSnapshot> dt1Snapshot(uint8_t gateway_id, int short_address) const;
|
std::optional<DaliDomainSnapshot> dt1Snapshot(uint8_t gateway_id, int short_address) const;
|
||||||
@@ -151,17 +169,25 @@ class DaliDomainService {
|
|||||||
bool storeDt8SceneSnapshot(uint8_t gateway_id, int short_address, int scene, int brightness,
|
bool storeDt8SceneSnapshot(uint8_t gateway_id, int short_address, int scene, int brightness,
|
||||||
DaliDt8SceneColorMode color_mode = DaliDt8SceneColorMode::kDisabled,
|
DaliDt8SceneColorMode color_mode = DaliDt8SceneColorMode::kDisabled,
|
||||||
int color_temperature = 0, int red = 0, int green = 0,
|
int color_temperature = 0, int red = 0, int green = 0,
|
||||||
int blue = 0) const;
|
int blue = 0, int white = 0, int amber = 0,
|
||||||
|
int freecolour = 255, int rgbwaf_control = -1) const;
|
||||||
bool storeDt8PowerOnLevelSnapshot(uint8_t gateway_id, int short_address, int level) const;
|
bool storeDt8PowerOnLevelSnapshot(uint8_t gateway_id, int short_address, int level) const;
|
||||||
bool storeDt8SystemFailureLevelSnapshot(uint8_t gateway_id, int short_address, int level) const;
|
bool storeDt8SystemFailureLevelSnapshot(uint8_t gateway_id, int short_address, int level) const;
|
||||||
bool setBright(uint8_t gateway_id, int short_address, int brightness) const;
|
bool setBright(uint8_t gateway_id, int short_address, int brightness,
|
||||||
|
bool logarithmic_curve = false) const;
|
||||||
bool setColTempRaw(uint8_t gateway_id, int short_address, int mirek) const;
|
bool setColTempRaw(uint8_t gateway_id, int short_address, int mirek) const;
|
||||||
bool setColTemp(uint8_t gateway_id, int short_address, int kelvin) const;
|
bool setColTemp(uint8_t gateway_id, int short_address, int kelvin) const;
|
||||||
bool setColourRaw(uint8_t gateway_id, int raw_addr, int x, int y) const;
|
bool setColourRaw(uint8_t gateway_id, int raw_addr, int x, int y) const;
|
||||||
bool setColourRGB(uint8_t gateway_id, int short_address, int r, int g, int b) const;
|
bool setColourRGB(uint8_t gateway_id, int short_address, int r, int g, int b) const;
|
||||||
|
bool setColourRGBW(uint8_t gateway_id, int short_address, int r, int g, int b, int w) const;
|
||||||
|
bool setColourRGBCW(uint8_t gateway_id, int short_address, int r, int g, int b,
|
||||||
|
int cool_white, int warm_white) const;
|
||||||
|
bool setColourRGBWAF(uint8_t gateway_id, int short_address, int r, int g, int b, int w,
|
||||||
|
int amber, int freecolour, int control = -1) const;
|
||||||
bool on(uint8_t gateway_id, int short_address) const;
|
bool on(uint8_t gateway_id, int short_address) const;
|
||||||
bool off(uint8_t gateway_id, int short_address) const;
|
bool off(uint8_t gateway_id, int short_address) const;
|
||||||
bool off(int short_address) const;
|
bool off(int short_address) const;
|
||||||
|
std::optional<uint8_t> queryActualLevel(uint8_t gateway_id, int short_address) const;
|
||||||
std::optional<uint16_t> queryGroupMask(uint8_t gateway_id, int short_address) const;
|
std::optional<uint16_t> queryGroupMask(uint8_t gateway_id, int short_address) const;
|
||||||
std::optional<uint8_t> querySceneLevel(uint8_t gateway_id, int short_address, int scene) const;
|
std::optional<uint8_t> querySceneLevel(uint8_t gateway_id, int short_address, int scene) const;
|
||||||
std::optional<DaliAddressSettingsSnapshot> queryAddressSettings(uint8_t gateway_id,
|
std::optional<DaliAddressSettingsSnapshot> queryAddressSettings(uint8_t gateway_id,
|
||||||
@@ -171,6 +197,8 @@ class DaliDomainService {
|
|||||||
std::optional<uint8_t> level) const;
|
std::optional<uint8_t> level) const;
|
||||||
bool applyAddressSettings(uint8_t gateway_id, int short_address,
|
bool applyAddressSettings(uint8_t gateway_id, int short_address,
|
||||||
const DaliAddressSettingsSnapshot& settings) const;
|
const DaliAddressSettingsSnapshot& settings) const;
|
||||||
|
std::optional<uint8_t> gatewayIdForChannelIndex(uint8_t channel_index) const;
|
||||||
|
bool updateChannelGatewayId(uint8_t channel_index, uint8_t gateway_id);
|
||||||
bool updateChannelName(uint8_t gateway_id, std::string_view name);
|
bool updateChannelName(uint8_t gateway_id, std::string_view name);
|
||||||
bool allocateAllAddr(uint8_t gateway_id, int start_address = 0) const;
|
bool allocateAllAddr(uint8_t gateway_id, int start_address = 0) const;
|
||||||
void stopAllocAddr(uint8_t gateway_id) const;
|
void stopAllocAddr(uint8_t gateway_id) const;
|
||||||
@@ -181,23 +209,42 @@ class DaliDomainService {
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
struct DaliChannel;
|
struct DaliChannel;
|
||||||
|
struct RecentHostCommandFrame {
|
||||||
|
uint8_t raw_addr{0};
|
||||||
|
uint8_t command{0};
|
||||||
|
TickType_t tick{0};
|
||||||
|
bool valid{false};
|
||||||
|
};
|
||||||
|
|
||||||
DaliChannel* findChannelByGateway(uint8_t gateway_id);
|
DaliChannel* findChannelByGateway(uint8_t gateway_id);
|
||||||
const DaliChannel* findChannelByGateway(uint8_t gateway_id) const;
|
const DaliChannel* findChannelByGateway(uint8_t gateway_id) const;
|
||||||
DaliChannel* findChannelByIndex(uint8_t channel_index);
|
DaliChannel* findChannelByIndex(uint8_t channel_index);
|
||||||
|
const DaliChannel* findChannelByIndex(uint8_t channel_index) const;
|
||||||
const DaliChannel* findChannelByHardwareBus(uint8_t bus_id) const;
|
const DaliChannel* findChannelByHardwareBus(uint8_t bus_id) const;
|
||||||
bool hasSerialPort(int uart_port) const;
|
bool hasSerialPort(int uart_port) const;
|
||||||
esp_err_t startSerialRxTask(DaliChannel& channel);
|
esp_err_t startSerialRxTask(DaliChannel& channel);
|
||||||
static void SerialRxTaskEntry(void* arg);
|
static void SerialRxTaskEntry(void* arg);
|
||||||
void serialRxTaskLoop(DaliChannel* channel);
|
void serialRxTaskLoop(DaliChannel* channel);
|
||||||
|
esp_err_t startRawFrameDispatchTask();
|
||||||
|
static void RawFrameDispatchTaskEntry(void* arg);
|
||||||
|
void rawFrameDispatchTaskLoop();
|
||||||
esp_err_t startRawFrameTask();
|
esp_err_t startRawFrameTask();
|
||||||
static void RawFrameTaskEntry(void* arg);
|
static void RawFrameTaskEntry(void* arg);
|
||||||
void rawFrameTaskLoop();
|
void rawFrameTaskLoop();
|
||||||
|
void queueRawFrame(const DaliChannel& channel, const uint8_t* data, size_t len);
|
||||||
void notifyRawFrameSinks(const DaliRawFrame& frame);
|
void notifyRawFrameSinks(const DaliRawFrame& frame);
|
||||||
|
void markBusActivity(uint8_t gateway_id) const;
|
||||||
|
|
||||||
std::vector<std::unique_ptr<DaliChannel>> channels_;
|
std::vector<std::unique_ptr<DaliChannel>> channels_;
|
||||||
std::vector<std::function<void(const DaliRawFrame& frame)>> raw_frame_sinks_;
|
std::vector<std::function<void(const DaliRawFrame& frame)>> raw_frame_sinks_;
|
||||||
SemaphoreHandle_t raw_frame_sink_lock_{nullptr};
|
SemaphoreHandle_t raw_frame_sink_lock_{nullptr};
|
||||||
|
mutable SemaphoreHandle_t bus_activity_lock_{nullptr};
|
||||||
|
mutable std::map<uint8_t, TickType_t> last_bus_activity_ticks_;
|
||||||
|
mutable SemaphoreHandle_t host_activity_lock_{nullptr};
|
||||||
|
mutable std::map<uint8_t, TickType_t> last_host_activity_ticks_;
|
||||||
|
mutable std::map<uint8_t, RecentHostCommandFrame> recent_host_command_frames_;
|
||||||
|
QueueHandle_t raw_frame_dispatch_queue_{nullptr};
|
||||||
|
TaskHandle_t raw_frame_dispatch_task_handle_{nullptr};
|
||||||
TaskHandle_t raw_frame_task_handle_{nullptr};
|
TaskHandle_t raw_frame_task_handle_{nullptr};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -18,6 +18,7 @@ namespace gateway {
|
|||||||
struct GatewayBacnetServerConfig {
|
struct GatewayBacnetServerConfig {
|
||||||
uint32_t device_instance{4194303};
|
uint32_t device_instance{4194303};
|
||||||
std::string device_name{"DALI Gateway"};
|
std::string device_name{"DALI Gateway"};
|
||||||
|
std::string channel_name;
|
||||||
std::string local_address;
|
std::string local_address;
|
||||||
uint16_t udp_port{47808};
|
uint16_t udp_port{47808};
|
||||||
uint32_t task_stack_size{8192};
|
uint32_t task_stack_size{8192};
|
||||||
|
|||||||
@@ -48,6 +48,8 @@ bool gateway_bacnet_stack_start(
|
|||||||
|
|
||||||
void gateway_bacnet_stack_cleanup(void);
|
void gateway_bacnet_stack_cleanup(void);
|
||||||
|
|
||||||
|
bool gateway_bacnet_stack_set_device_name(const char* device_name);
|
||||||
|
|
||||||
bool gateway_bacnet_stack_upsert_object(
|
bool gateway_bacnet_stack_upsert_object(
|
||||||
gateway_bacnet_object_kind_t object_kind,
|
gateway_bacnet_object_kind_t object_kind,
|
||||||
uint32_t object_instance,
|
uint32_t object_instance,
|
||||||
|
|||||||
@@ -251,6 +251,11 @@ esp_err_t GatewayBacnetServer::registerChannel(
|
|||||||
return ESP_ERR_INVALID_ARG;
|
return ESP_ERR_INVALID_ARG;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
GatewayBacnetServerConfig effective_config = config;
|
||||||
|
if (effective_config.device_name.empty()) {
|
||||||
|
effective_config.device_name = "DALI Gateway";
|
||||||
|
}
|
||||||
|
|
||||||
bindings.erase(std::remove_if(bindings.begin(), bindings.end(), [](const auto& binding) {
|
bindings.erase(std::remove_if(bindings.begin(), bindings.end(), [](const auto& binding) {
|
||||||
return !IsSupportedObjectType(binding.object_type) ||
|
return !IsSupportedObjectType(binding.object_type) ||
|
||||||
binding.object_instance > kMaxBacnetInstance;
|
binding.object_instance > kMaxBacnetInstance;
|
||||||
@@ -258,7 +263,7 @@ esp_err_t GatewayBacnetServer::registerChannel(
|
|||||||
bindings.end());
|
bindings.end());
|
||||||
|
|
||||||
LockGuard guard(lock_);
|
LockGuard guard(lock_);
|
||||||
if (started_ && !configCompatible(config)) {
|
if (started_ && !configCompatible(effective_config)) {
|
||||||
return ESP_ERR_INVALID_STATE;
|
return ESP_ERR_INVALID_STATE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -268,7 +273,15 @@ esp_err_t GatewayBacnetServer::registerChannel(
|
|||||||
if (bindings.empty() && !started_ && channel == channels_.end()) {
|
if (bindings.empty() && !started_ && channel == channels_.end()) {
|
||||||
return ESP_ERR_NOT_FOUND;
|
return ESP_ERR_NOT_FOUND;
|
||||||
}
|
}
|
||||||
ChannelRegistration registration{gateway_id, config, std::move(bindings),
|
if (started_ && active_config_.device_name != effective_config.device_name) {
|
||||||
|
if (!gateway_bacnet_stack_set_device_name(effective_config.device_name.c_str())) {
|
||||||
|
return ESP_FAIL;
|
||||||
|
}
|
||||||
|
active_config_.device_name = effective_config.device_name;
|
||||||
|
gateway_bacnet_stack_send_i_am();
|
||||||
|
}
|
||||||
|
|
||||||
|
ChannelRegistration registration{gateway_id, effective_config, std::move(bindings),
|
||||||
std::move(write_callback), std::move(read_callback)};
|
std::move(write_callback), std::move(read_callback)};
|
||||||
if (channel == channels_.end()) {
|
if (channel == channels_.end()) {
|
||||||
channels_.push_back(std::move(registration));
|
channels_.push_back(std::move(registration));
|
||||||
@@ -276,7 +289,7 @@ esp_err_t GatewayBacnetServer::registerChannel(
|
|||||||
*channel = std::move(registration);
|
*channel = std::move(registration);
|
||||||
}
|
}
|
||||||
|
|
||||||
esp_err_t err = startStackLocked(config);
|
esp_err_t err = startStackLocked(effective_config);
|
||||||
if (err != ESP_OK) {
|
if (err != ESP_OK) {
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
@@ -341,9 +354,16 @@ esp_err_t GatewayBacnetServer::rebuildObjectsLocked() {
|
|||||||
used_objects.insert(key);
|
used_objects.insert(key);
|
||||||
|
|
||||||
const std::string name = ObjectName(binding);
|
const std::string name = ObjectName(binding);
|
||||||
|
std::string description = channel.config.channel_name;
|
||||||
|
if (!binding.model_id.empty()) {
|
||||||
|
if (!description.empty()) {
|
||||||
|
description += " / ";
|
||||||
|
}
|
||||||
|
description += binding.model_id;
|
||||||
|
}
|
||||||
if (!gateway_bacnet_stack_upsert_object(ToBacnetKind(binding.object_type),
|
if (!gateway_bacnet_stack_upsert_object(ToBacnetKind(binding.object_type),
|
||||||
binding.object_instance, name.c_str(),
|
binding.object_instance, name.c_str(),
|
||||||
binding.model_id.c_str(),
|
description.c_str(),
|
||||||
binding.out_of_service,
|
binding.out_of_service,
|
||||||
binding.reliability)) {
|
binding.reliability)) {
|
||||||
return ESP_FAIL;
|
return ESP_FAIL;
|
||||||
|
|||||||
@@ -410,6 +410,14 @@ void gateway_bacnet_stack_cleanup(void)
|
|||||||
Write_Callback_Context = NULL;
|
Write_Callback_Context = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool gateway_bacnet_stack_set_device_name(const char* device_name)
|
||||||
|
{
|
||||||
|
if (!device_name || device_name[0] == '\0') {
|
||||||
|
device_name = "DALI Gateway";
|
||||||
|
}
|
||||||
|
return Device_Object_Name_ANSI_Init(device_name);
|
||||||
|
}
|
||||||
|
|
||||||
bool gateway_bacnet_stack_upsert_object(
|
bool gateway_bacnet_stack_upsert_object(
|
||||||
gateway_bacnet_object_kind_t object_kind,
|
gateway_bacnet_object_kind_t object_kind,
|
||||||
uint32_t object_instance,
|
uint32_t object_instance,
|
||||||
|
|||||||
@@ -4,6 +4,9 @@
|
|||||||
#include "gateway_controller.hpp"
|
#include "gateway_controller.hpp"
|
||||||
#include "gateway_runtime.hpp"
|
#include "gateway_runtime.hpp"
|
||||||
|
|
||||||
|
#include "freertos/FreeRTOS.h"
|
||||||
|
#include "freertos/task.h"
|
||||||
|
|
||||||
#include "esp_log.h"
|
#include "esp_log.h"
|
||||||
#include "esp_timer.h"
|
#include "esp_timer.h"
|
||||||
#include "host/ble_gap.h"
|
#include "host/ble_gap.h"
|
||||||
@@ -29,6 +32,8 @@ constexpr uint16_t kChannel2Uuid = 0xFFF2;
|
|||||||
constexpr uint16_t kGatewayUuid = 0xFFF3;
|
constexpr uint16_t kGatewayUuid = 0xFFF3;
|
||||||
constexpr int64_t kGenericDedupeWindowUs = 120000;
|
constexpr int64_t kGenericDedupeWindowUs = 120000;
|
||||||
constexpr size_t kGatewayCharacteristicIndex = 2;
|
constexpr size_t kGatewayCharacteristicIndex = 2;
|
||||||
|
constexpr int kGatewayNotifyAllocationAttempts = 6;
|
||||||
|
constexpr TickType_t kGatewayNotifyRetryDelayTicks = pdMS_TO_TICKS(20);
|
||||||
|
|
||||||
gateway::GatewayBleBridge* s_active_bridge = nullptr;
|
gateway::GatewayBleBridge* s_active_bridge = nullptr;
|
||||||
uint16_t s_value_handles[3] = {0, 0, 0};
|
uint16_t s_value_handles[3] = {0, 0, 0};
|
||||||
@@ -141,6 +146,13 @@ void RegisterGatt(struct ble_gatt_register_ctxt* ctxt, void* arg) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::vector<uint8_t> LegacyRawPayload(const std::vector<uint8_t>& data) {
|
||||||
|
if (data.size() == 1) {
|
||||||
|
return {0xBE, data[0]};
|
||||||
|
}
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
const struct ble_gatt_svc_def kGattServices[] = {
|
const struct ble_gatt_svc_def kGattServices[] = {
|
||||||
{
|
{
|
||||||
.type = BLE_GATT_SVC_TYPE_PRIMARY,
|
.type = BLE_GATT_SVC_TYPE_PRIMARY,
|
||||||
@@ -341,9 +353,25 @@ void GatewayBleBridge::notifyCharacteristic(size_t index, const std::vector<uint
|
|||||||
}
|
}
|
||||||
|
|
||||||
characteristic_values_[index] = payload;
|
characteristic_values_[index] = payload;
|
||||||
struct os_mbuf* buffer = ble_hs_mbuf_from_flat(payload.data(), payload.size());
|
const int allocation_attempts =
|
||||||
|
index == kGatewayCharacteristicIndex ? kGatewayNotifyAllocationAttempts : 1;
|
||||||
|
struct os_mbuf* buffer = nullptr;
|
||||||
|
for (int attempt = 0; attempt < allocation_attempts; ++attempt) {
|
||||||
|
if (conn_handle_ == kInvalidConnectionHandle || !notify_enabled_[index]) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
buffer = ble_hs_mbuf_from_flat(payload.data(), payload.size());
|
||||||
|
if (buffer != nullptr) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (attempt + 1 < allocation_attempts) {
|
||||||
|
vTaskDelay(kGatewayNotifyRetryDelayTicks);
|
||||||
|
}
|
||||||
|
}
|
||||||
if (buffer == nullptr) {
|
if (buffer == nullptr) {
|
||||||
ESP_LOGW(kTag, "failed to allocate notify mbuf idx=%u", static_cast<unsigned>(index));
|
ESP_LOGW(kTag, "failed to allocate notify mbuf idx=%u attempts=%d len=%u",
|
||||||
|
static_cast<unsigned>(index), allocation_attempts,
|
||||||
|
static_cast<unsigned>(payload.size()));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const int rc = ble_gatts_notify_custom(conn_handle_, s_value_handles[index], buffer);
|
const int rc = ble_gatts_notify_custom(conn_handle_, s_value_handles[index], buffer);
|
||||||
@@ -377,7 +405,14 @@ void GatewayBleBridge::handleDaliRawFrame(const DaliRawFrame& frame) {
|
|||||||
if (!enabled_ || conn_handle_ == kInvalidConnectionHandle || frame.data.empty()) {
|
if (!enabled_ || conn_handle_ == kInvalidConnectionHandle || frame.data.empty()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
notifyCharacteristic(frame.channel_index, frame.data);
|
if (!controller_.rawReportingEnabled(frame.gateway_id)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// Forward/control events are already published on FFF3 as structured 0x22 frames.
|
||||||
|
if (notify_enabled_[kGatewayCharacteristicIndex] && frame.data.size() != 1) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
notifyCharacteristic(frame.channel_index, LegacyRawPayload(frame.data));
|
||||||
}
|
}
|
||||||
|
|
||||||
void GatewayBleBridge::handleRawWrite(size_t channel_index, const std::vector<uint8_t>& payload) {
|
void GatewayBleBridge::handleRawWrite(size_t channel_index, const std::vector<uint8_t>& payload) {
|
||||||
@@ -448,6 +483,18 @@ int GatewayBleBridge::handleGapEvent(struct ble_gap_event* event) {
|
|||||||
notify_enabled_.fill(false);
|
notify_enabled_.fill(false);
|
||||||
last_notify_payload_.clear();
|
last_notify_payload_.clear();
|
||||||
last_notify_at_us_ = 0;
|
last_notify_at_us_ = 0;
|
||||||
|
struct ble_gap_upd_params params = {
|
||||||
|
.itvl_min = 15,
|
||||||
|
.itvl_max = 15,
|
||||||
|
.latency = 3,
|
||||||
|
.supervision_timeout = 1000,
|
||||||
|
.min_ce_len = 0,
|
||||||
|
.max_ce_len = 0,
|
||||||
|
};
|
||||||
|
int rc = ble_gap_update_params(event->connect.conn_handle, ¶ms);
|
||||||
|
if (rc != 0) {
|
||||||
|
ESP_LOGW(kTag, "ble_gap_update_params rc=%d", rc);
|
||||||
|
}
|
||||||
ESP_LOGI(kTag, "BLE client connected handle=%u", conn_handle_);
|
ESP_LOGI(kTag, "BLE client connected handle=%u", conn_handle_);
|
||||||
} else if (enabled_) {
|
} else if (enabled_) {
|
||||||
startAdvertising();
|
startAdvertising();
|
||||||
@@ -512,7 +559,8 @@ int GatewayBleBridge::handleAccess(uint16_t, uint16_t attr_handle,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (index == static_cast<int>(kGatewayCharacteristicIndex)) {
|
if (GatewayRuntime::isGatewayCommandFrame(payload) ||
|
||||||
|
index == static_cast<int>(kGatewayCharacteristicIndex)) {
|
||||||
handleGatewayWrite(payload);
|
handleGatewayWrite(payload);
|
||||||
} else {
|
} else {
|
||||||
handleRawWrite(static_cast<size_t>(index), payload);
|
handleRawWrite(static_cast<size_t>(index), payload);
|
||||||
|
|||||||
@@ -7,13 +7,16 @@ set(GATEWAY_BRIDGE_REQUIRES
|
|||||||
gateway_cache
|
gateway_cache
|
||||||
gateway_knx
|
gateway_knx
|
||||||
gateway_modbus
|
gateway_modbus
|
||||||
|
knx
|
||||||
log
|
log
|
||||||
lwip
|
lwip
|
||||||
nvs_flash
|
nvs_flash
|
||||||
)
|
)
|
||||||
|
|
||||||
idf_component_register(
|
idf_component_register(
|
||||||
SRCS "src/gateway_bridge.cpp"
|
SRCS
|
||||||
|
"src/gateway_bridge.cpp"
|
||||||
|
"src/security_storage.cpp"
|
||||||
INCLUDE_DIRS "include"
|
INCLUDE_DIRS "include"
|
||||||
REQUIRES ${GATEWAY_BRIDGE_REQUIRES}
|
REQUIRES ${GATEWAY_BRIDGE_REQUIRES}
|
||||||
PRIV_REQUIRES gateway_bacnet
|
PRIV_REQUIRES gateway_bacnet
|
||||||
|
|||||||
@@ -1,8 +1,11 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include <cstddef>
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
|
#include <functional>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <optional>
|
#include <optional>
|
||||||
|
#include <set>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
@@ -15,6 +18,7 @@
|
|||||||
namespace gateway {
|
namespace gateway {
|
||||||
|
|
||||||
class DaliDomainService;
|
class DaliDomainService;
|
||||||
|
struct DaliRawFrame;
|
||||||
class GatewayCache;
|
class GatewayCache;
|
||||||
|
|
||||||
struct GatewayBridgeServiceConfig {
|
struct GatewayBridgeServiceConfig {
|
||||||
@@ -31,12 +35,16 @@ struct GatewayBridgeServiceConfig {
|
|||||||
UBaseType_t modbus_task_priority{4};
|
UBaseType_t modbus_task_priority{4};
|
||||||
std::optional<GatewayModbusConfig> default_modbus_config;
|
std::optional<GatewayModbusConfig> default_modbus_config;
|
||||||
bool allow_modbus_uart0{false};
|
bool allow_modbus_uart0{false};
|
||||||
|
bool allow_knx_uart0{false};
|
||||||
std::vector<int> reserved_uart_ports;
|
std::vector<int> reserved_uart_ports;
|
||||||
uint32_t bacnet_task_stack_size{8192};
|
uint32_t bacnet_task_stack_size{8192};
|
||||||
UBaseType_t bacnet_task_priority{5};
|
UBaseType_t bacnet_task_priority{5};
|
||||||
uint32_t knx_task_stack_size{8192};
|
uint32_t knx_task_stack_size{12288};
|
||||||
UBaseType_t knx_task_priority{5};
|
UBaseType_t knx_task_priority{5};
|
||||||
std::optional<GatewayKnxConfig> default_knx_config;
|
std::optional<GatewayKnxConfig> default_knx_config;
|
||||||
|
std::function<std::string()> gateway_device_name_provider;
|
||||||
|
GatewayKnxGatewaySnapshotProvider knx_gateway_snapshot_provider;
|
||||||
|
GatewayKnxGatewayCommandTransactor knx_gateway_command_transactor;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct GatewayBridgeHttpResponse {
|
struct GatewayBridgeHttpResponse {
|
||||||
@@ -57,17 +65,34 @@ class GatewayBridgeService {
|
|||||||
const std::string& query = {});
|
const std::string& query = {});
|
||||||
GatewayBridgeHttpResponse handlePost(const std::string& action, int gateway_id,
|
GatewayBridgeHttpResponse handlePost(const std::string& action, int gateway_id,
|
||||||
const std::string& body);
|
const std::string& body);
|
||||||
|
std::string handleTransportRequest(uint8_t gateway_id, std::string_view request);
|
||||||
|
void handleGatewayNameChanged(uint8_t gateway_id);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
struct ChannelRuntime;
|
struct ChannelRuntime;
|
||||||
|
|
||||||
ChannelRuntime* findRuntime(uint8_t gateway_id);
|
ChannelRuntime* findRuntime(uint8_t gateway_id);
|
||||||
const ChannelRuntime* findRuntime(uint8_t gateway_id) const;
|
const ChannelRuntime* findRuntime(uint8_t gateway_id) const;
|
||||||
|
ChannelRuntime* selectKnxEndpointRuntime();
|
||||||
|
bool isKnxEndpointRuntime(const ChannelRuntime* runtime) const;
|
||||||
|
esp_err_t startKnxEndpoint(ChannelRuntime* requested_runtime,
|
||||||
|
std::set<int>* used_uarts = nullptr);
|
||||||
|
esp_err_t stopKnxEndpoint(ChannelRuntime* requested_runtime);
|
||||||
|
DaliBridgeResult routeKnxGroupWrite(uint16_t group_address, const uint8_t* data,
|
||||||
|
size_t len);
|
||||||
|
DaliBridgeResult routeKnxGroupObjectWrite(uint16_t group_object_number,
|
||||||
|
const uint8_t* data, size_t len);
|
||||||
|
void handleDaliRawFrame(const DaliRawFrame& frame);
|
||||||
|
void collectUsedRuntimeResources(uint8_t except_gateway_id,
|
||||||
|
std::set<uint16_t>* modbus_tcp_ports,
|
||||||
|
std::set<uint16_t>* knx_udp_ports,
|
||||||
|
std::set<int>* serial_uarts) const;
|
||||||
|
|
||||||
DaliDomainService& dali_domain_;
|
DaliDomainService& dali_domain_;
|
||||||
GatewayCache& cache_;
|
GatewayCache& cache_;
|
||||||
GatewayBridgeServiceConfig config_;
|
GatewayBridgeServiceConfig config_;
|
||||||
std::vector<std::unique_ptr<ChannelRuntime>> runtimes_;
|
std::vector<std::unique_ptr<ChannelRuntime>> runtimes_;
|
||||||
|
ChannelRuntime* knx_endpoint_runtime_{nullptr};
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace gateway
|
} // namespace gateway
|
||||||
|
|||||||
@@ -0,0 +1,69 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <cstddef>
|
||||||
|
#include <cstdint>
|
||||||
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
#include "gateway_knx.hpp"
|
||||||
|
|
||||||
|
namespace gateway::openknx {
|
||||||
|
|
||||||
|
struct FactoryFdskInfo {
|
||||||
|
bool available{false};
|
||||||
|
std::string serialNumber;
|
||||||
|
std::string label;
|
||||||
|
std::string qrCode;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct FactoryCertificatePayload {
|
||||||
|
bool available{false};
|
||||||
|
std::string productIdentity;
|
||||||
|
std::string manufacturerId;
|
||||||
|
std::string applicationNumber;
|
||||||
|
std::string applicationVersion;
|
||||||
|
std::string serialNumber;
|
||||||
|
std::string fdskLabel;
|
||||||
|
std::string fdskQrCode;
|
||||||
|
std::string storage;
|
||||||
|
std::string createdAt;
|
||||||
|
std::string checksum;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct IpSecureCredentialStatus {
|
||||||
|
bool activated{false};
|
||||||
|
bool backboneKeyAvailable{false};
|
||||||
|
bool deviceAuthenticationKeyAvailable{false};
|
||||||
|
uint8_t tunnelUserCount{0};
|
||||||
|
uint64_t routingSequence{0};
|
||||||
|
};
|
||||||
|
|
||||||
|
bool LoadFactoryFdsk(uint8_t* data, size_t len);
|
||||||
|
FactoryFdskInfo LoadFactoryFdskInfo();
|
||||||
|
bool LoadFactoryFdskForInstance(uint32_t instance_id, uint8_t* data, size_t len);
|
||||||
|
FactoryFdskInfo LoadFactoryFdskInfoForInstance(uint32_t instance_id);
|
||||||
|
bool GenerateFactoryFdsk(FactoryFdskInfo* info = nullptr);
|
||||||
|
bool WriteFactoryFdskHex(const std::string& hex_key, FactoryFdskInfo* info = nullptr);
|
||||||
|
bool ResetFactoryFdskCache(FactoryFdskInfo* info = nullptr);
|
||||||
|
bool ResetFactorySecurityForInstance(uint32_t instance_id, FactoryFdskInfo* info = nullptr);
|
||||||
|
FactoryCertificatePayload BuildFactoryCertificatePayload();
|
||||||
|
FactoryCertificatePayload BuildFactoryCertificatePayloadForInstance(uint32_t instance_id);
|
||||||
|
|
||||||
|
bool LoadOamFactoryFdsk(uint8_t* data, size_t len);
|
||||||
|
FactoryFdskInfo LoadOamFactoryFdskInfo();
|
||||||
|
bool GenerateOamFactoryFdsk(FactoryFdskInfo* info = nullptr);
|
||||||
|
bool WriteOamFactoryFdskHex(const std::string& hex_key,
|
||||||
|
FactoryFdskInfo* info = nullptr);
|
||||||
|
bool ResetOamFactoryFdskCache(FactoryFdskInfo* info = nullptr);
|
||||||
|
FactoryCertificatePayload BuildOamFactoryCertificatePayload();
|
||||||
|
|
||||||
|
IpSecureCredentialStatus LoadOamIpSecureCredentialStatus();
|
||||||
|
::gateway::GatewayKnxIpSecureCredentialMaterial LoadOamIpSecureCredentialMaterial();
|
||||||
|
bool WriteOamIpSecureKeyringHex(const std::string& backbone_key_hex,
|
||||||
|
const std::vector<std::string>& tunnel_user_key_hex,
|
||||||
|
const std::string& device_auth_key_hex,
|
||||||
|
bool activated);
|
||||||
|
bool StoreOamIpSecureRoutingSequence(uint64_t sequence);
|
||||||
|
bool ClearOamIpSecureKeyring();
|
||||||
|
|
||||||
|
} // namespace gateway::openknx
|
||||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,723 @@
|
|||||||
|
#include "security_storage.h"
|
||||||
|
|
||||||
|
#include "gateway_knx_internal.h"
|
||||||
|
|
||||||
|
#include "esp_log.h"
|
||||||
|
#include "esp_mac.h"
|
||||||
|
#include "esp_timer.h"
|
||||||
|
#include "mbedtls/sha256.h"
|
||||||
|
#include "nvs.h"
|
||||||
|
#include "nvs_flash.h"
|
||||||
|
|
||||||
|
#include <algorithm>
|
||||||
|
#include <array>
|
||||||
|
#include <cinttypes>
|
||||||
|
#include <cstddef>
|
||||||
|
#include <cstdio>
|
||||||
|
#include <cstdint>
|
||||||
|
#include <cstring>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
constexpr const char* kTag = "openknx_sec";
|
||||||
|
constexpr const char* kNamespace = "knx_sec";
|
||||||
|
constexpr const char* kOamNamespace = "knx_oam_sec";
|
||||||
|
constexpr const char* kFactoryFdskKey = "factory_fdsk";
|
||||||
|
constexpr const char* kIpSecureBackboneKey = "ipsec_backbone";
|
||||||
|
constexpr const char* kIpSecureDeviceAuthKey = "ipsec_dev_auth";
|
||||||
|
constexpr const char* kIpSecureTunnelCountKey = "ipsec_tunnels";
|
||||||
|
constexpr const char* kIpSecureActivatedKey = "ipsec_active";
|
||||||
|
constexpr const char* kIpSecureRoutingSeqKey = "ipsec_route_seq";
|
||||||
|
constexpr size_t kFdskSize = 16;
|
||||||
|
constexpr size_t kSerialSize = 6;
|
||||||
|
constexpr size_t kFdskQrSize = 36;
|
||||||
|
constexpr const char* kProductIdentity = "REG1-Dali";
|
||||||
|
constexpr const char* kOamProductIdentity = "OpenKNX-IP-Router";
|
||||||
|
constexpr const char* kDevelopmentStorage = "base_mac_derived_plain_nvs_development";
|
||||||
|
constexpr char kFdskDerivationLabel[] = "DaliMaster REG1-Dali deterministic FDSK v1";
|
||||||
|
constexpr char kOamFdskDerivationLabel[] = "DaliMaster OAM-IP-Router deterministic FDSK v1";
|
||||||
|
constexpr uint8_t kCrc4Tab[16] = {
|
||||||
|
0x0, 0x3, 0x6, 0x5, 0xc, 0xf, 0xa, 0x9,
|
||||||
|
0xb, 0x8, 0xd, 0xe, 0x7, 0x4, 0x1, 0x2,
|
||||||
|
};
|
||||||
|
constexpr char kBase32Alphabet[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ234567";
|
||||||
|
constexpr char kHexAlphabet[] = "0123456789ABCDEF";
|
||||||
|
|
||||||
|
struct FactoryFdskContext {
|
||||||
|
std::string nvsNamespace;
|
||||||
|
const char* productIdentity;
|
||||||
|
const char* derivationLabel;
|
||||||
|
uint16_t manufacturerId;
|
||||||
|
uint16_t applicationNumber;
|
||||||
|
uint8_t applicationVersion;
|
||||||
|
uint32_t serialMacIncrement;
|
||||||
|
bool clearOpenKnxCache;
|
||||||
|
};
|
||||||
|
|
||||||
|
const FactoryFdskContext kReg1Context{
|
||||||
|
kNamespace,
|
||||||
|
kProductIdentity,
|
||||||
|
kFdskDerivationLabel,
|
||||||
|
gateway::knx_internal::kReg1DaliManufacturerId,
|
||||||
|
gateway::knx_internal::kReg1DaliApplicationNumber,
|
||||||
|
gateway::knx_internal::kReg1DaliApplicationVersion,
|
||||||
|
gateway::knx_internal::kReg1DaliSerialMacIncrement,
|
||||||
|
true};
|
||||||
|
|
||||||
|
const FactoryFdskContext kOamContext{
|
||||||
|
kOamNamespace,
|
||||||
|
kOamProductIdentity,
|
||||||
|
kOamFdskDerivationLabel,
|
||||||
|
gateway::knx_internal::kOamRouterManufacturerId,
|
||||||
|
gateway::knx_internal::kOamRouterApplicationNumber,
|
||||||
|
gateway::knx_internal::kOamRouterApplicationVersion,
|
||||||
|
gateway::knx_internal::kOamRouterSerialMacIncrement,
|
||||||
|
false};
|
||||||
|
|
||||||
|
extern "C" void knx_platform_clear_cached_fdsk() __attribute__((weak));
|
||||||
|
|
||||||
|
FactoryFdskContext reg1ContextForInstance(uint32_t instance_id) {
|
||||||
|
FactoryFdskContext context = kReg1Context;
|
||||||
|
context.serialMacIncrement = gateway::knx_internal::kReg1DaliSerialMacIncrement + instance_id;
|
||||||
|
context.clearOpenKnxCache = instance_id == 0;
|
||||||
|
if (instance_id != 0) {
|
||||||
|
context.nvsNamespace = std::string(kNamespace) + "_" + std::to_string(instance_id);
|
||||||
|
}
|
||||||
|
return context;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string hexValue(uint32_t value, int width) {
|
||||||
|
std::array<char, 9> buffer{};
|
||||||
|
std::snprintf(buffer.data(), buffer.size(), "%0*" PRIX32, width, value);
|
||||||
|
return buffer.data();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ensureNvsReady() {
|
||||||
|
const esp_err_t err = nvs_flash_init();
|
||||||
|
if (err == ESP_ERR_NVS_NO_FREE_PAGES || err == ESP_ERR_NVS_NEW_VERSION_FOUND) {
|
||||||
|
if (nvs_flash_erase() != ESP_OK) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return nvs_flash_init() == ESP_OK;
|
||||||
|
}
|
||||||
|
return err == ESP_OK || err == ESP_ERR_INVALID_STATE;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool plausibleKey(const uint8_t* data) {
|
||||||
|
const bool all_zero = std::all_of(data, data + kFdskSize, [](uint8_t value) {
|
||||||
|
return value == 0x00;
|
||||||
|
});
|
||||||
|
const bool all_ff = std::all_of(data, data + kFdskSize, [](uint8_t value) {
|
||||||
|
return value == 0xff;
|
||||||
|
});
|
||||||
|
return !all_zero && !all_ff;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool readBaseMac(uint8_t* data) {
|
||||||
|
if (data == nullptr) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (esp_efuse_mac_get_default(data) == ESP_OK) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return esp_read_mac(data, ESP_MAC_WIFI_STA) == ESP_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
void clearOpenKnxFdskCache() {
|
||||||
|
if (knx_platform_clear_cached_fdsk != nullptr) {
|
||||||
|
knx_platform_clear_cached_fdsk();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int fromHexDigit(char value) {
|
||||||
|
if (value >= '0' && value <= '9') {
|
||||||
|
return value - '0';
|
||||||
|
}
|
||||||
|
if (value >= 'a' && value <= 'f') {
|
||||||
|
return value - 'a' + 10;
|
||||||
|
}
|
||||||
|
if (value >= 'A' && value <= 'F') {
|
||||||
|
return value - 'A' + 10;
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool parseHexKey(const std::string& value, uint8_t* out) {
|
||||||
|
std::string digits;
|
||||||
|
digits.reserve(value.size());
|
||||||
|
for (char ch : value) {
|
||||||
|
if (ch == ':' || ch == '-' || ch == ' ' || ch == '\t' || ch == '\n' || ch == '\r') {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (fromHexDigit(ch) < 0) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
digits.push_back(ch);
|
||||||
|
}
|
||||||
|
if (digits.size() != kFdskSize * 2U) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
for (size_t index = 0; index < kFdskSize; ++index) {
|
||||||
|
const int hi = fromHexDigit(digits[index * 2U]);
|
||||||
|
const int lo = fromHexDigit(digits[index * 2U + 1U]);
|
||||||
|
if (hi < 0 || lo < 0) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
out[index] = static_cast<uint8_t>((hi << 4) | lo);
|
||||||
|
}
|
||||||
|
return plausibleKey(out);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool loadKnxSerialNumber(const FactoryFdskContext& context, uint8_t* serial) {
|
||||||
|
if (serial == nullptr) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
std::array<uint8_t, kSerialSize> mac{};
|
||||||
|
if (!readBaseMac(mac.data())) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t suffix = (static_cast<uint32_t>(mac[2]) << 24) |
|
||||||
|
(static_cast<uint32_t>(mac[3]) << 16) |
|
||||||
|
(static_cast<uint32_t>(mac[4]) << 8) |
|
||||||
|
static_cast<uint32_t>(mac[5]);
|
||||||
|
suffix += context.serialMacIncrement;
|
||||||
|
|
||||||
|
serial[0] = static_cast<uint8_t>((context.manufacturerId >> 8) & 0xff);
|
||||||
|
serial[1] = static_cast<uint8_t>(context.manufacturerId & 0xff);
|
||||||
|
serial[2] = static_cast<uint8_t>((suffix >> 24) & 0xff);
|
||||||
|
serial[3] = static_cast<uint8_t>((suffix >> 16) & 0xff);
|
||||||
|
serial[4] = static_cast<uint8_t>((suffix >> 8) & 0xff);
|
||||||
|
serial[5] = static_cast<uint8_t>(suffix & 0xff);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool deriveFactoryFdskFromSerial(const FactoryFdskContext& context,
|
||||||
|
const uint8_t* serial, uint8_t* key) {
|
||||||
|
if (serial == nullptr || key == nullptr) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
const size_t label_len = std::strlen(context.derivationLabel);
|
||||||
|
std::vector<uint8_t> material(label_len + kSerialSize);
|
||||||
|
std::copy(context.derivationLabel, context.derivationLabel + label_len, material.begin());
|
||||||
|
std::copy(serial, serial + kSerialSize, material.begin() + label_len);
|
||||||
|
|
||||||
|
std::array<uint8_t, 32> digest{};
|
||||||
|
if (mbedtls_sha256(material.data(), material.size(), digest.data(), 0) != 0) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
std::copy(digest.begin(), digest.begin() + kFdskSize, key);
|
||||||
|
if (!plausibleKey(key)) {
|
||||||
|
key[kFdskSize - 1] ^= 0xA5;
|
||||||
|
}
|
||||||
|
return plausibleKey(key);
|
||||||
|
}
|
||||||
|
|
||||||
|
void syncFactoryFdskToNvs(const FactoryFdskContext& context, const uint8_t* data) {
|
||||||
|
if (data == nullptr || !plausibleKey(data) || !ensureNvsReady()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::array<uint8_t, kFdskSize> stored{};
|
||||||
|
size_t stored_size = stored.size();
|
||||||
|
|
||||||
|
nvs_handle_t handle = 0;
|
||||||
|
esp_err_t err = nvs_open(context.nvsNamespace.c_str(), NVS_READWRITE, &handle);
|
||||||
|
if (err != ESP_OK) {
|
||||||
|
ESP_LOGW(kTag, "failed to open KNX security NVS namespace: %s", esp_err_to_name(err));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
err = nvs_get_blob(handle, kFactoryFdskKey, stored.data(), &stored_size);
|
||||||
|
if (err == ESP_OK && stored_size == stored.size() &&
|
||||||
|
std::equal(stored.begin(), stored.end(), data)) {
|
||||||
|
nvs_close(handle);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
err = nvs_set_blob(handle, kFactoryFdskKey, data, kFdskSize);
|
||||||
|
if (err == ESP_OK) {
|
||||||
|
err = nvs_commit(handle);
|
||||||
|
}
|
||||||
|
nvs_close(handle);
|
||||||
|
if (err != ESP_OK) {
|
||||||
|
ESP_LOGW(kTag, "failed to mirror deterministic KNX factory FDSK: %s", esp_err_to_name(err));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (context.clearOpenKnxCache) {
|
||||||
|
clearOpenKnxFdskCache();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t crc4Array(const uint8_t* data, size_t len) {
|
||||||
|
uint8_t crc = 0;
|
||||||
|
for (size_t i = 0; i < len; ++i) {
|
||||||
|
crc = kCrc4Tab[crc ^ (data[i] >> 4)];
|
||||||
|
crc = kCrc4Tab[crc ^ (data[i] & 0x0f)];
|
||||||
|
}
|
||||||
|
return crc;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string toBase32NoPadding(const uint8_t* data, size_t len) {
|
||||||
|
std::string result;
|
||||||
|
result.reserve(((len * 8) + 4) / 5);
|
||||||
|
|
||||||
|
uint32_t buffer = 0;
|
||||||
|
int bits_left = 0;
|
||||||
|
for (size_t i = 0; i < len; ++i) {
|
||||||
|
buffer = (buffer << 8) | data[i];
|
||||||
|
bits_left += 8;
|
||||||
|
while (bits_left >= 5) {
|
||||||
|
const uint8_t index = static_cast<uint8_t>((buffer >> (bits_left - 5)) & 0x1f);
|
||||||
|
result.push_back(kBase32Alphabet[index]);
|
||||||
|
bits_left -= 5;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (bits_left > 0) {
|
||||||
|
const uint8_t index = static_cast<uint8_t>((buffer << (5 - bits_left)) & 0x1f);
|
||||||
|
result.push_back(kBase32Alphabet[index]);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string toHex(const uint8_t* data, size_t len) {
|
||||||
|
std::string result;
|
||||||
|
result.reserve(len * 2);
|
||||||
|
for (size_t i = 0; i < len; ++i) {
|
||||||
|
result.push_back(kHexAlphabet[(data[i] >> 4) & 0x0f]);
|
||||||
|
result.push_back(kHexAlphabet[data[i] & 0x0f]);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string generateFdskQrCode(const uint8_t* serial, const uint8_t* key) {
|
||||||
|
std::array<uint8_t, kSerialSize + kFdskSize + 1> buffer{};
|
||||||
|
std::copy(serial, serial + kSerialSize, buffer.begin());
|
||||||
|
std::copy(key, key + kFdskSize, buffer.begin() + kSerialSize);
|
||||||
|
buffer[kSerialSize + kFdskSize] = static_cast<uint8_t>((crc4Array(buffer.data(), buffer.size() - 1) << 4) & 0xff);
|
||||||
|
|
||||||
|
std::string encoded = toBase32NoPadding(buffer.data(), buffer.size());
|
||||||
|
if (encoded.size() > kFdskQrSize) {
|
||||||
|
encoded.resize(kFdskQrSize);
|
||||||
|
}
|
||||||
|
return encoded;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string formatFdskLabel(const std::string& qr_code) {
|
||||||
|
std::string label;
|
||||||
|
label.reserve(qr_code.size() + (qr_code.size() / 6));
|
||||||
|
for (size_t i = 0; i < qr_code.size(); ++i) {
|
||||||
|
if (i != 0 && (i % 6) == 0) {
|
||||||
|
label.push_back('-');
|
||||||
|
}
|
||||||
|
label.push_back(qr_code[i]);
|
||||||
|
}
|
||||||
|
return label;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string fnv1aHex(const std::string& value) {
|
||||||
|
uint32_t hash = 2166136261u;
|
||||||
|
for (unsigned char ch : value) {
|
||||||
|
hash ^= ch;
|
||||||
|
hash *= 16777619u;
|
||||||
|
}
|
||||||
|
std::array<uint8_t, 4> bytes{
|
||||||
|
static_cast<uint8_t>((hash >> 24) & 0xff),
|
||||||
|
static_cast<uint8_t>((hash >> 16) & 0xff),
|
||||||
|
static_cast<uint8_t>((hash >> 8) & 0xff),
|
||||||
|
static_cast<uint8_t>(hash & 0xff),
|
||||||
|
};
|
||||||
|
return toHex(bytes.data(), bytes.size());
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace
|
||||||
|
|
||||||
|
namespace gateway::openknx {
|
||||||
|
|
||||||
|
bool LoadFactoryFdskForContext(const FactoryFdskContext& context, uint8_t* data, size_t len) {
|
||||||
|
if (data == nullptr || len < kFdskSize) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::array<uint8_t, kSerialSize> serial{};
|
||||||
|
std::array<uint8_t, kFdskSize> key{};
|
||||||
|
if (!loadKnxSerialNumber(context, serial.data()) ||
|
||||||
|
!deriveFactoryFdskFromSerial(context, serial.data(), key.data())) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
std::memcpy(data, key.data(), kFdskSize);
|
||||||
|
syncFactoryFdskToNvs(context, key.data());
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
FactoryFdskInfo LoadFactoryFdskInfoForContext(const FactoryFdskContext& context) {
|
||||||
|
FactoryFdskInfo info;
|
||||||
|
std::array<uint8_t, kFdskSize> key{};
|
||||||
|
std::array<uint8_t, kSerialSize> serial{};
|
||||||
|
if (!loadKnxSerialNumber(context, serial.data()) ||
|
||||||
|
!LoadFactoryFdskForContext(context, key.data(), key.size())) {
|
||||||
|
return info;
|
||||||
|
}
|
||||||
|
|
||||||
|
info.available = true;
|
||||||
|
info.serialNumber = toHex(serial.data(), serial.size());
|
||||||
|
info.qrCode = generateFdskQrCode(serial.data(), key.data());
|
||||||
|
info.label = formatFdskLabel(info.qrCode);
|
||||||
|
return info;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool GenerateFactoryFdskForContext(const FactoryFdskContext& context,
|
||||||
|
FactoryFdskInfo* info) {
|
||||||
|
std::array<uint8_t, kFdskSize> key{};
|
||||||
|
const bool stored = LoadFactoryFdskForContext(context, key.data(), key.size());
|
||||||
|
std::fill(key.begin(), key.end(), 0);
|
||||||
|
if (!stored) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (info != nullptr) {
|
||||||
|
*info = LoadFactoryFdskInfoForContext(context);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool WriteFactoryFdskHexForContext(const FactoryFdskContext& context,
|
||||||
|
const std::string& hex_key,
|
||||||
|
FactoryFdskInfo* info) {
|
||||||
|
std::array<uint8_t, kFdskSize> key{};
|
||||||
|
if (!parseHexKey(hex_key, key.data())) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
std::array<uint8_t, kSerialSize> serial{};
|
||||||
|
std::array<uint8_t, kFdskSize> derived{};
|
||||||
|
const bool stored = loadKnxSerialNumber(context, serial.data()) &&
|
||||||
|
deriveFactoryFdskFromSerial(context, serial.data(), derived.data()) &&
|
||||||
|
std::equal(key.begin(), key.end(), derived.begin());
|
||||||
|
if (stored) {
|
||||||
|
syncFactoryFdskToNvs(context, derived.data());
|
||||||
|
}
|
||||||
|
std::fill(key.begin(), key.end(), 0);
|
||||||
|
std::fill(derived.begin(), derived.end(), 0);
|
||||||
|
if (!stored) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (info != nullptr) {
|
||||||
|
*info = LoadFactoryFdskInfoForContext(context);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ResetFactoryFdskCacheForContext(const FactoryFdskContext& context,
|
||||||
|
FactoryFdskInfo* info) {
|
||||||
|
if (context.clearOpenKnxCache) {
|
||||||
|
clearOpenKnxFdskCache();
|
||||||
|
}
|
||||||
|
const auto loaded = LoadFactoryFdskInfoForContext(context);
|
||||||
|
if (info != nullptr) {
|
||||||
|
*info = loaded;
|
||||||
|
}
|
||||||
|
return loaded.available;
|
||||||
|
}
|
||||||
|
|
||||||
|
FactoryCertificatePayload BuildFactoryCertificatePayloadForContext(
|
||||||
|
const FactoryFdskContext& context) {
|
||||||
|
FactoryCertificatePayload payload;
|
||||||
|
const auto info = LoadFactoryFdskInfoForContext(context);
|
||||||
|
if (!info.available) {
|
||||||
|
return payload;
|
||||||
|
}
|
||||||
|
payload.available = true;
|
||||||
|
payload.productIdentity = context.productIdentity;
|
||||||
|
payload.manufacturerId = hexValue(context.manufacturerId, 4);
|
||||||
|
payload.applicationNumber = hexValue(context.applicationNumber,
|
||||||
|
context.applicationNumber <= 0xff ? 2 : 4);
|
||||||
|
payload.applicationVersion = hexValue(context.applicationVersion, 2);
|
||||||
|
payload.serialNumber = info.serialNumber;
|
||||||
|
payload.fdskLabel = info.label;
|
||||||
|
payload.fdskQrCode = info.qrCode;
|
||||||
|
payload.storage = kDevelopmentStorage;
|
||||||
|
payload.createdAt = "uptime_us:" + std::to_string(esp_timer_get_time());
|
||||||
|
payload.checksum = fnv1aHex(payload.productIdentity + "|" + payload.manufacturerId + "|" +
|
||||||
|
payload.applicationNumber + "|" + payload.applicationVersion + "|" +
|
||||||
|
payload.serialNumber + "|" + payload.fdskLabel + "|" +
|
||||||
|
payload.fdskQrCode + "|" + payload.createdAt);
|
||||||
|
return payload;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string TunnelUserKeyName(uint8_t index) {
|
||||||
|
std::array<char, 18> buffer{};
|
||||||
|
std::snprintf(buffer.data(), buffer.size(), "ipsec_tunnel_%02u",
|
||||||
|
static_cast<unsigned>(index));
|
||||||
|
return buffer.data();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool BlobKeyAvailable(nvs_handle_t handle, const char* key) {
|
||||||
|
std::array<uint8_t, kFdskSize> data{};
|
||||||
|
size_t len = data.size();
|
||||||
|
return nvs_get_blob(handle, key, data.data(), &len) == ESP_OK && len == data.size() &&
|
||||||
|
plausibleKey(data.data());
|
||||||
|
}
|
||||||
|
|
||||||
|
bool SetOptionalHexBlob(nvs_handle_t handle, const char* key, const std::string& hex) {
|
||||||
|
if (hex.empty()) {
|
||||||
|
nvs_erase_key(handle, key);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
std::array<uint8_t, kFdskSize> data{};
|
||||||
|
if (!parseHexKey(hex, data.data())) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
const esp_err_t err = nvs_set_blob(handle, key, data.data(), data.size());
|
||||||
|
std::fill(data.begin(), data.end(), 0);
|
||||||
|
return err == ESP_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool LoadOptionalKey(nvs_handle_t handle, const char* key, std::array<uint8_t, kFdskSize>* out) {
|
||||||
|
if (out == nullptr) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
std::array<uint8_t, kFdskSize> data{};
|
||||||
|
size_t len = data.size();
|
||||||
|
if (nvs_get_blob(handle, key, data.data(), &len) != ESP_OK || len != data.size() ||
|
||||||
|
!plausibleKey(data.data())) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
*out = data;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool LoadFactoryFdsk(uint8_t* data, size_t len) {
|
||||||
|
return LoadFactoryFdskForContext(kReg1Context, data, len);
|
||||||
|
}
|
||||||
|
|
||||||
|
extern "C" bool knx_platform_get_fdsk_for_namespace(const char* nvs_namespace,
|
||||||
|
uint8_t* data,
|
||||||
|
size_t len) {
|
||||||
|
const std::string namespace_name = nvs_namespace == nullptr ? std::string() : nvs_namespace;
|
||||||
|
if (namespace_name.size() >= 4 && namespace_name.compare(namespace_name.size() - 4, 4, "_oam") == 0) {
|
||||||
|
return LoadFactoryFdskForContext(kOamContext, data, len);
|
||||||
|
}
|
||||||
|
return LoadFactoryFdsk(data, len);
|
||||||
|
}
|
||||||
|
|
||||||
|
FactoryFdskInfo LoadFactoryFdskInfo() {
|
||||||
|
return LoadFactoryFdskInfoForContext(kReg1Context);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool LoadFactoryFdskForInstance(uint32_t instance_id, uint8_t* data, size_t len) {
|
||||||
|
const auto context = reg1ContextForInstance(instance_id);
|
||||||
|
return LoadFactoryFdskForContext(context, data, len);
|
||||||
|
}
|
||||||
|
|
||||||
|
FactoryFdskInfo LoadFactoryFdskInfoForInstance(uint32_t instance_id) {
|
||||||
|
const auto context = reg1ContextForInstance(instance_id);
|
||||||
|
return LoadFactoryFdskInfoForContext(context);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool GenerateFactoryFdsk(FactoryFdskInfo* info) {
|
||||||
|
return GenerateFactoryFdskForContext(kReg1Context, info);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool WriteFactoryFdskHex(const std::string& hex_key, FactoryFdskInfo* info) {
|
||||||
|
return WriteFactoryFdskHexForContext(kReg1Context, hex_key, info);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ResetFactoryFdskCache(FactoryFdskInfo* info) {
|
||||||
|
return ResetFactoryFdskCacheForContext(kReg1Context, info);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ResetFactorySecurityForInstance(uint32_t instance_id, FactoryFdskInfo* info) {
|
||||||
|
const auto context = reg1ContextForInstance(instance_id);
|
||||||
|
if (ensureNvsReady()) {
|
||||||
|
nvs_handle_t handle = 0;
|
||||||
|
if (nvs_open(context.nvsNamespace.c_str(), NVS_READWRITE, &handle) == ESP_OK) {
|
||||||
|
nvs_erase_key(handle, kFactoryFdskKey);
|
||||||
|
nvs_commit(handle);
|
||||||
|
nvs_close(handle);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ResetFactoryFdskCacheForContext(context, info);
|
||||||
|
}
|
||||||
|
|
||||||
|
FactoryCertificatePayload BuildFactoryCertificatePayload() {
|
||||||
|
return BuildFactoryCertificatePayloadForContext(kReg1Context);
|
||||||
|
}
|
||||||
|
|
||||||
|
FactoryCertificatePayload BuildFactoryCertificatePayloadForInstance(uint32_t instance_id) {
|
||||||
|
const auto context = reg1ContextForInstance(instance_id);
|
||||||
|
return BuildFactoryCertificatePayloadForContext(context);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool LoadOamFactoryFdsk(uint8_t* data, size_t len) {
|
||||||
|
return LoadFactoryFdskForContext(kOamContext, data, len);
|
||||||
|
}
|
||||||
|
|
||||||
|
FactoryFdskInfo LoadOamFactoryFdskInfo() {
|
||||||
|
return LoadFactoryFdskInfoForContext(kOamContext);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool GenerateOamFactoryFdsk(FactoryFdskInfo* info) {
|
||||||
|
return GenerateFactoryFdskForContext(kOamContext, info);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool WriteOamFactoryFdskHex(const std::string& hex_key, FactoryFdskInfo* info) {
|
||||||
|
return WriteFactoryFdskHexForContext(kOamContext, hex_key, info);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ResetOamFactoryFdskCache(FactoryFdskInfo* info) {
|
||||||
|
return ResetFactoryFdskCacheForContext(kOamContext, info);
|
||||||
|
}
|
||||||
|
|
||||||
|
FactoryCertificatePayload BuildOamFactoryCertificatePayload() {
|
||||||
|
return BuildFactoryCertificatePayloadForContext(kOamContext);
|
||||||
|
}
|
||||||
|
|
||||||
|
IpSecureCredentialStatus LoadOamIpSecureCredentialStatus() {
|
||||||
|
IpSecureCredentialStatus status;
|
||||||
|
if (!ensureNvsReady()) {
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
nvs_handle_t handle = 0;
|
||||||
|
if (nvs_open(kOamNamespace, NVS_READONLY, &handle) != ESP_OK) {
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
uint8_t activated = 0;
|
||||||
|
if (nvs_get_u8(handle, kIpSecureActivatedKey, &activated) == ESP_OK) {
|
||||||
|
status.activated = activated != 0;
|
||||||
|
}
|
||||||
|
uint8_t tunnel_count = 0;
|
||||||
|
if (nvs_get_u8(handle, kIpSecureTunnelCountKey, &tunnel_count) == ESP_OK) {
|
||||||
|
status.tunnelUserCount = tunnel_count;
|
||||||
|
}
|
||||||
|
uint64_t routing_sequence = 0;
|
||||||
|
if (nvs_get_u64(handle, kIpSecureRoutingSeqKey, &routing_sequence) == ESP_OK) {
|
||||||
|
status.routingSequence = routing_sequence;
|
||||||
|
}
|
||||||
|
status.backboneKeyAvailable = BlobKeyAvailable(handle, kIpSecureBackboneKey);
|
||||||
|
status.deviceAuthenticationKeyAvailable = BlobKeyAvailable(handle, kIpSecureDeviceAuthKey);
|
||||||
|
nvs_close(handle);
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
::gateway::GatewayKnxIpSecureCredentialMaterial LoadOamIpSecureCredentialMaterial() {
|
||||||
|
::gateway::GatewayKnxIpSecureCredentialMaterial material;
|
||||||
|
if (!ensureNvsReady()) {
|
||||||
|
return material;
|
||||||
|
}
|
||||||
|
nvs_handle_t handle = 0;
|
||||||
|
if (nvs_open(kOamNamespace, NVS_READONLY, &handle) != ESP_OK) {
|
||||||
|
return material;
|
||||||
|
}
|
||||||
|
uint8_t activated = 0;
|
||||||
|
if (nvs_get_u8(handle, kIpSecureActivatedKey, &activated) == ESP_OK) {
|
||||||
|
material.activated = activated != 0;
|
||||||
|
}
|
||||||
|
material.backbone_key_available = LoadOptionalKey(handle, kIpSecureBackboneKey,
|
||||||
|
&material.backbone_key);
|
||||||
|
material.device_authentication_key_available =
|
||||||
|
LoadOptionalKey(handle, kIpSecureDeviceAuthKey,
|
||||||
|
&material.device_authentication_key);
|
||||||
|
uint8_t tunnel_count = 0;
|
||||||
|
if (nvs_get_u8(handle, kIpSecureTunnelCountKey, &tunnel_count) == ESP_OK) {
|
||||||
|
tunnel_count = std::min<uint8_t>(tunnel_count, 16);
|
||||||
|
material.tunnel_user_keys.reserve(tunnel_count);
|
||||||
|
for (uint8_t index = 0; index < tunnel_count; ++index) {
|
||||||
|
std::array<uint8_t, kFdskSize> key{};
|
||||||
|
const std::string key_name = TunnelUserKeyName(index);
|
||||||
|
if (LoadOptionalKey(handle, key_name.c_str(), &key)) {
|
||||||
|
material.tunnel_user_keys.push_back(key);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
uint64_t routing_sequence = 0;
|
||||||
|
if (nvs_get_u64(handle, kIpSecureRoutingSeqKey, &routing_sequence) == ESP_OK) {
|
||||||
|
material.routing_sequence = routing_sequence;
|
||||||
|
}
|
||||||
|
nvs_close(handle);
|
||||||
|
return material;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool WriteOamIpSecureKeyringHex(const std::string& backbone_key_hex,
|
||||||
|
const std::vector<std::string>& tunnel_user_key_hex,
|
||||||
|
const std::string& device_auth_key_hex,
|
||||||
|
bool activated) {
|
||||||
|
if (tunnel_user_key_hex.size() > 16 || !ensureNvsReady()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
nvs_handle_t handle = 0;
|
||||||
|
if (nvs_open(kOamNamespace, NVS_READWRITE, &handle) != ESP_OK) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
bool ok = SetOptionalHexBlob(handle, kIpSecureBackboneKey, backbone_key_hex) &&
|
||||||
|
SetOptionalHexBlob(handle, kIpSecureDeviceAuthKey, device_auth_key_hex);
|
||||||
|
for (uint8_t index = 0; index < 16; ++index) {
|
||||||
|
const std::string key = TunnelUserKeyName(index);
|
||||||
|
nvs_erase_key(handle, key.c_str());
|
||||||
|
}
|
||||||
|
if (ok) {
|
||||||
|
for (size_t index = 0; index < tunnel_user_key_hex.size(); ++index) {
|
||||||
|
const std::string key = TunnelUserKeyName(static_cast<uint8_t>(index));
|
||||||
|
ok = SetOptionalHexBlob(handle, key.c_str(), tunnel_user_key_hex[index]);
|
||||||
|
if (!ok) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (ok) {
|
||||||
|
ok = nvs_set_u8(handle, kIpSecureTunnelCountKey,
|
||||||
|
static_cast<uint8_t>(tunnel_user_key_hex.size())) == ESP_OK &&
|
||||||
|
nvs_set_u8(handle, kIpSecureActivatedKey, activated ? 1 : 0) == ESP_OK;
|
||||||
|
}
|
||||||
|
if (ok) {
|
||||||
|
uint64_t existing_sequence = 0;
|
||||||
|
if (nvs_get_u64(handle, kIpSecureRoutingSeqKey, &existing_sequence) != ESP_OK) {
|
||||||
|
ok = nvs_set_u64(handle, kIpSecureRoutingSeqKey, 0) == ESP_OK;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (ok) {
|
||||||
|
ok = nvs_commit(handle) == ESP_OK;
|
||||||
|
}
|
||||||
|
nvs_close(handle);
|
||||||
|
return ok;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool StoreOamIpSecureRoutingSequence(uint64_t sequence) {
|
||||||
|
if (!ensureNvsReady()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
nvs_handle_t handle = 0;
|
||||||
|
if (nvs_open(kOamNamespace, NVS_READWRITE, &handle) != ESP_OK) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
const bool ok = nvs_set_u64(handle, kIpSecureRoutingSeqKey, sequence) == ESP_OK &&
|
||||||
|
nvs_commit(handle) == ESP_OK;
|
||||||
|
nvs_close(handle);
|
||||||
|
return ok;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ClearOamIpSecureKeyring() {
|
||||||
|
if (!ensureNvsReady()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
nvs_handle_t handle = 0;
|
||||||
|
if (nvs_open(kOamNamespace, NVS_READWRITE, &handle) != ESP_OK) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
nvs_erase_key(handle, kIpSecureBackboneKey);
|
||||||
|
nvs_erase_key(handle, kIpSecureDeviceAuthKey);
|
||||||
|
nvs_erase_key(handle, kIpSecureTunnelCountKey);
|
||||||
|
nvs_erase_key(handle, kIpSecureActivatedKey);
|
||||||
|
nvs_erase_key(handle, kIpSecureRoutingSeqKey);
|
||||||
|
for (uint8_t index = 0; index < 16; ++index) {
|
||||||
|
const std::string key = TunnelUserKeyName(index);
|
||||||
|
nvs_erase_key(handle, key.c_str());
|
||||||
|
}
|
||||||
|
const bool ok = nvs_commit(handle) == ESP_OK;
|
||||||
|
nvs_close(handle);
|
||||||
|
return ok;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace gateway::openknx
|
||||||
|
|
||||||
|
extern "C" bool knx_platform_get_fdsk(uint8_t* data, size_t len) {
|
||||||
|
return gateway::openknx::LoadFactoryFdsk(data, len);
|
||||||
|
}
|
||||||
@@ -5,6 +5,7 @@
|
|||||||
#include <map>
|
#include <map>
|
||||||
#include <optional>
|
#include <optional>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
#include "esp_err.h"
|
#include "esp_err.h"
|
||||||
#include "freertos/FreeRTOS.h"
|
#include "freertos/FreeRTOS.h"
|
||||||
@@ -24,7 +25,8 @@ struct GatewayCacheConfig {
|
|||||||
bool cache_enabled{true};
|
bool cache_enabled{true};
|
||||||
bool reconciliation_enabled{true};
|
bool reconciliation_enabled{true};
|
||||||
bool full_state_mirror_enabled{false};
|
bool full_state_mirror_enabled{false};
|
||||||
uint32_t flush_interval_ms{5000};
|
uint32_t flush_interval_ms{10000};
|
||||||
|
uint32_t refresh_interval_ms{120000};
|
||||||
uint32_t task_stack_size{4096};
|
uint32_t task_stack_size{4096};
|
||||||
UBaseType_t task_priority{3};
|
UBaseType_t task_priority{3};
|
||||||
GatewayCachePriorityMode default_priority_mode{GatewayCachePriorityMode::kOutsideBusFirst};
|
GatewayCachePriorityMode default_priority_mode{GatewayCachePriorityMode::kOutsideBusFirst};
|
||||||
@@ -41,6 +43,12 @@ enum class GatewayCacheDaliTargetKind : uint8_t {
|
|||||||
kBroadcast = 2,
|
kBroadcast = 2,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum class GatewayCacheDaliPresence : uint8_t {
|
||||||
|
kUnknown = 0,
|
||||||
|
kOnline = 1,
|
||||||
|
kOffline = 2,
|
||||||
|
};
|
||||||
|
|
||||||
struct GatewayCacheDaliTarget {
|
struct GatewayCacheDaliTarget {
|
||||||
GatewayCacheDaliTargetKind kind{GatewayCacheDaliTargetKind::kShortAddress};
|
GatewayCacheDaliTargetKind kind{GatewayCacheDaliTargetKind::kShortAddress};
|
||||||
uint8_t value{0};
|
uint8_t value{0};
|
||||||
@@ -71,6 +79,7 @@ struct GatewayCacheDaliRuntimeStatus {
|
|||||||
std::optional<uint8_t> actual_level;
|
std::optional<uint8_t> actual_level;
|
||||||
std::optional<uint8_t> scene_id;
|
std::optional<uint8_t> scene_id;
|
||||||
bool use_min_level{false};
|
bool use_min_level{false};
|
||||||
|
bool stale{false};
|
||||||
uint32_t revision{0};
|
uint32_t revision{0};
|
||||||
|
|
||||||
bool anyKnown() const {
|
bool anyKnown() const {
|
||||||
@@ -136,6 +145,12 @@ class GatewayCache {
|
|||||||
GatewayCacheChannelFlags channelFlags(uint8_t gateway_id);
|
GatewayCacheChannelFlags channelFlags(uint8_t gateway_id);
|
||||||
GatewayCacheChannelFlags pendingChannelFlags(uint8_t gateway_id);
|
GatewayCacheChannelFlags pendingChannelFlags(uint8_t gateway_id);
|
||||||
GatewayCacheDaliAddressState daliAddressState(uint8_t gateway_id, uint8_t short_address);
|
GatewayCacheDaliAddressState daliAddressState(uint8_t gateway_id, uint8_t short_address);
|
||||||
|
GatewayCacheDaliPresence daliAddressPresence(uint8_t gateway_id, uint8_t short_address);
|
||||||
|
void markDaliAddressPresence(uint8_t gateway_id, uint8_t short_address,
|
||||||
|
GatewayCacheDaliPresence presence);
|
||||||
|
std::optional<GatewayCacheDaliTarget> decodeDaliTarget(uint8_t raw_addr);
|
||||||
|
std::vector<uint8_t> reconciliationAddresses(
|
||||||
|
uint8_t gateway_id, std::optional<GatewayCacheDaliTarget> target);
|
||||||
GatewayCacheDaliRuntimeStatus daliGroupStatus(uint8_t gateway_id, uint8_t group_id);
|
GatewayCacheDaliRuntimeStatus daliGroupStatus(uint8_t gateway_id, uint8_t group_id);
|
||||||
GatewayCacheDaliRuntimeStatus daliBroadcastStatus(uint8_t gateway_id);
|
GatewayCacheDaliRuntimeStatus daliBroadcastStatus(uint8_t gateway_id);
|
||||||
bool setDaliGroupMask(uint8_t gateway_id, uint8_t short_address,
|
bool setDaliGroupMask(uint8_t gateway_id, uint8_t short_address,
|
||||||
@@ -144,6 +159,8 @@ class GatewayCache {
|
|||||||
std::optional<uint8_t> level);
|
std::optional<uint8_t> level);
|
||||||
bool setDaliSettings(uint8_t gateway_id, uint8_t short_address,
|
bool setDaliSettings(uint8_t gateway_id, uint8_t short_address,
|
||||||
std::optional<GatewayCacheDaliSettingsSnapshot> settings);
|
std::optional<GatewayCacheDaliSettingsSnapshot> settings);
|
||||||
|
bool setDaliActualLevel(uint8_t gateway_id, uint8_t short_address,
|
||||||
|
std::optional<uint8_t> level);
|
||||||
bool clearChannelFlagsIfMatched(uint8_t gateway_id, const GatewayCacheChannelFlags& flags);
|
bool clearChannelFlagsIfMatched(uint8_t gateway_id, const GatewayCacheChannelFlags& flags);
|
||||||
void markGroupUpdateNeeded(uint8_t gateway_id, bool needed = true);
|
void markGroupUpdateNeeded(uint8_t gateway_id, bool needed = true);
|
||||||
void markSceneUpdateNeeded(uint8_t gateway_id, bool needed = true);
|
void markSceneUpdateNeeded(uint8_t gateway_id, bool needed = true);
|
||||||
@@ -174,9 +191,13 @@ class GatewayCache {
|
|||||||
void closeStorageLocked();
|
void closeStorageLocked();
|
||||||
bool persistSceneLocked(uint8_t gateway_id, uint8_t scene_id, const SceneEntry& scene);
|
bool persistSceneLocked(uint8_t gateway_id, uint8_t scene_id, const SceneEntry& scene);
|
||||||
bool persistGroupLocked(uint8_t gateway_id, uint8_t group_id, const GroupEntry& group);
|
bool persistGroupLocked(uint8_t gateway_id, uint8_t group_id, const GroupEntry& group);
|
||||||
|
bool persistDaliAddressStateLocked(uint8_t gateway_id, uint8_t short_address,
|
||||||
|
const GatewayCacheDaliAddressState& state);
|
||||||
bool commitStorageLocked();
|
bool commitStorageLocked();
|
||||||
bool shouldTrackUpdateFlagsLocked() const;
|
bool shouldTrackUpdateFlagsLocked() const;
|
||||||
uint32_t nextDaliRuntimeRevisionLocked();
|
uint32_t nextDaliRuntimeRevisionLocked();
|
||||||
|
void markDaliAddressPresenceLocked(uint8_t gateway_id, uint8_t short_address,
|
||||||
|
GatewayCacheDaliPresence presence);
|
||||||
bool mirrorDaliCommandLocked(uint8_t gateway_id, uint8_t raw_addr, uint8_t command);
|
bool mirrorDaliCommandLocked(uint8_t gateway_id, uint8_t raw_addr, uint8_t command);
|
||||||
void clearDaliTargetStateLocked(uint8_t gateway_id, const GatewayCacheDaliTarget& target,
|
void clearDaliTargetStateLocked(uint8_t gateway_id, const GatewayCacheDaliTarget& target,
|
||||||
uint32_t revision);
|
uint32_t revision);
|
||||||
@@ -205,6 +226,8 @@ class GatewayCache {
|
|||||||
GroupStore& ensureGroupStoreLocked(uint8_t gateway_id);
|
GroupStore& ensureGroupStoreLocked(uint8_t gateway_id);
|
||||||
void loadSceneStoreLocked(uint8_t gateway_id, SceneStore& scenes);
|
void loadSceneStoreLocked(uint8_t gateway_id, SceneStore& scenes);
|
||||||
void loadGroupStoreLocked(uint8_t gateway_id, GroupStore& groups);
|
void loadGroupStoreLocked(uint8_t gateway_id, GroupStore& groups);
|
||||||
|
void loadDaliStateStoreLocked(uint8_t gateway_id,
|
||||||
|
std::array<GatewayCacheDaliAddressState, 64>& states);
|
||||||
std::string readStringLocked(std::string_view key);
|
std::string readStringLocked(std::string_view key);
|
||||||
bool writeStringLocked(std::string_view key, std::string_view value);
|
bool writeStringLocked(std::string_view key, std::string_view value);
|
||||||
bool eraseKeyLocked(std::string_view key);
|
bool eraseKeyLocked(std::string_view key);
|
||||||
@@ -217,6 +240,7 @@ class GatewayCache {
|
|||||||
std::map<uint8_t, SceneStore> scenes_;
|
std::map<uint8_t, SceneStore> scenes_;
|
||||||
std::map<uint8_t, GroupStore> groups_;
|
std::map<uint8_t, GroupStore> groups_;
|
||||||
std::map<uint8_t, std::array<GatewayCacheDaliAddressState, 64>> dali_states_;
|
std::map<uint8_t, std::array<GatewayCacheDaliAddressState, 64>> dali_states_;
|
||||||
|
std::map<uint8_t, std::array<GatewayCacheDaliPresence, 64>> dali_presence_;
|
||||||
std::map<uint8_t, std::array<GatewayCacheDaliRuntimeStatus, 16>> dali_group_status_;
|
std::map<uint8_t, std::array<GatewayCacheDaliRuntimeStatus, 16>> dali_group_status_;
|
||||||
std::map<uint8_t, GatewayCacheDaliRuntimeStatus> dali_broadcast_status_;
|
std::map<uint8_t, GatewayCacheDaliRuntimeStatus> dali_broadcast_status_;
|
||||||
std::map<uint8_t, DtrState> dtr_states_;
|
std::map<uint8_t, DtrState> dtr_states_;
|
||||||
|
|||||||
@@ -43,6 +43,18 @@ constexpr uint8_t kDaliCmdDt8StoreDtrAsColorX = 0xE0;
|
|||||||
constexpr uint8_t kDaliCmdDt8StoreDtrAsColorY = 0xE1;
|
constexpr uint8_t kDaliCmdDt8StoreDtrAsColorY = 0xE1;
|
||||||
constexpr uint8_t kDaliCmdDt8StorePrimaryMin = 0xF0;
|
constexpr uint8_t kDaliCmdDt8StorePrimaryMin = 0xF0;
|
||||||
constexpr uint8_t kDaliCmdDt8StartAutoCalibration = 0xF6;
|
constexpr uint8_t kDaliCmdDt8StartAutoCalibration = 0xF6;
|
||||||
|
constexpr int kDaliStatePayloadVersion = 1;
|
||||||
|
constexpr uint32_t kDaliStateGroupMaskKnown = 1U << 0;
|
||||||
|
constexpr uint32_t kDaliStateActualKnown = 1U << 1;
|
||||||
|
constexpr uint32_t kDaliStateSceneKnown = 1U << 2;
|
||||||
|
constexpr uint32_t kDaliStateUseMinLevel = 1U << 3;
|
||||||
|
constexpr uint32_t kDaliStateStatusStale = 1U << 4;
|
||||||
|
constexpr uint32_t kDaliStatePowerOnKnown = 1U << 5;
|
||||||
|
constexpr uint32_t kDaliStateSystemFailureKnown = 1U << 6;
|
||||||
|
constexpr uint32_t kDaliStateMinKnown = 1U << 7;
|
||||||
|
constexpr uint32_t kDaliStateMaxKnown = 1U << 8;
|
||||||
|
constexpr uint32_t kDaliStateFadeTimeKnown = 1U << 9;
|
||||||
|
constexpr uint32_t kDaliStateFadeRateKnown = 1U << 10;
|
||||||
|
|
||||||
class LockGuard {
|
class LockGuard {
|
||||||
public:
|
public:
|
||||||
@@ -134,6 +146,18 @@ bool ShouldMirrorObservedMutation(GatewayCacheRawFrameOrigin origin,
|
|||||||
priority_mode == GatewayCachePriorityMode::kOutsideBusFirst;
|
priority_mode == GatewayCachePriorityMode::kOutsideBusFirst;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool ShouldAlwaysMirrorObservedStatus(uint8_t raw_addr, uint8_t command) {
|
||||||
|
if (!DecodeDaliTarget(raw_addr).has_value()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if ((raw_addr & 0x01) == 0) {
|
||||||
|
return command <= 254;
|
||||||
|
}
|
||||||
|
return command == kDaliCmdOff || command == kDaliCmdRecallMax ||
|
||||||
|
command == kDaliCmdRecallMin ||
|
||||||
|
(command >= kDaliCmdGoToSceneMin && command <= kDaliCmdGoToSceneMax);
|
||||||
|
}
|
||||||
|
|
||||||
void ClearDaliState(GatewayCacheDaliAddressState& state) {
|
void ClearDaliState(GatewayCacheDaliAddressState& state) {
|
||||||
state.group_mask_known = false;
|
state.group_mask_known = false;
|
||||||
state.group_mask = 0;
|
state.group_mask = 0;
|
||||||
@@ -215,6 +239,139 @@ std::string BuildGroupPayload(const GatewayCache::GroupEntry& group) {
|
|||||||
return std::string(payload);
|
return std::string(payload);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint8_t ByteValue(int value) {
|
||||||
|
return static_cast<uint8_t>(std::clamp(value, 0, 255));
|
||||||
|
}
|
||||||
|
|
||||||
|
uint16_t WordValue(int value) {
|
||||||
|
return static_cast<uint16_t>(std::clamp(value, 0, 0xffff));
|
||||||
|
}
|
||||||
|
|
||||||
|
uint16_t SceneKnownMask(const GatewayCacheDaliAddressState& state) {
|
||||||
|
uint16_t mask = 0;
|
||||||
|
for (size_t index = 0; index < state.scene_levels.size(); ++index) {
|
||||||
|
if (state.scene_levels[index].has_value()) {
|
||||||
|
mask |= static_cast<uint16_t>(1U << index);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return mask;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool IsDefaultDaliAddressState(const GatewayCacheDaliAddressState& state) {
|
||||||
|
return !state.group_mask_known && state.group_mask == 0 && SceneKnownMask(state) == 0 &&
|
||||||
|
!state.settings.anyKnown() && !state.status.anyKnown();
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t DaliStateFlags(const GatewayCacheDaliAddressState& state) {
|
||||||
|
uint32_t flags = 0;
|
||||||
|
if (state.group_mask_known) {
|
||||||
|
flags |= kDaliStateGroupMaskKnown;
|
||||||
|
}
|
||||||
|
if (state.status.actual_level.has_value()) {
|
||||||
|
flags |= kDaliStateActualKnown;
|
||||||
|
}
|
||||||
|
if (state.status.scene_id.has_value()) {
|
||||||
|
flags |= kDaliStateSceneKnown;
|
||||||
|
}
|
||||||
|
if (state.status.use_min_level) {
|
||||||
|
flags |= kDaliStateUseMinLevel;
|
||||||
|
}
|
||||||
|
if (state.status.stale) {
|
||||||
|
flags |= kDaliStateStatusStale;
|
||||||
|
}
|
||||||
|
if (state.settings.power_on_level.has_value()) {
|
||||||
|
flags |= kDaliStatePowerOnKnown;
|
||||||
|
}
|
||||||
|
if (state.settings.system_failure_level.has_value()) {
|
||||||
|
flags |= kDaliStateSystemFailureKnown;
|
||||||
|
}
|
||||||
|
if (state.settings.min_level.has_value()) {
|
||||||
|
flags |= kDaliStateMinKnown;
|
||||||
|
}
|
||||||
|
if (state.settings.max_level.has_value()) {
|
||||||
|
flags |= kDaliStateMaxKnown;
|
||||||
|
}
|
||||||
|
if (state.settings.fade_time.has_value()) {
|
||||||
|
flags |= kDaliStateFadeTimeKnown;
|
||||||
|
}
|
||||||
|
if (state.settings.fade_rate.has_value()) {
|
||||||
|
flags |= kDaliStateFadeRateKnown;
|
||||||
|
}
|
||||||
|
return flags;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string BuildDaliStatePayload(const GatewayCacheDaliAddressState& state) {
|
||||||
|
const uint16_t scene_known_mask = SceneKnownMask(state);
|
||||||
|
std::string payload = std::to_string(kDaliStatePayloadVersion);
|
||||||
|
payload += "," + std::to_string(DaliStateFlags(state));
|
||||||
|
payload += "," + std::to_string(state.status.revision);
|
||||||
|
payload += "," + std::to_string(state.group_mask);
|
||||||
|
payload += "," + std::to_string(state.status.actual_level.value_or(0));
|
||||||
|
payload += "," + std::to_string(state.status.scene_id.value_or(0));
|
||||||
|
payload += "," + std::to_string(state.settings.power_on_level.value_or(0));
|
||||||
|
payload += "," + std::to_string(state.settings.system_failure_level.value_or(0));
|
||||||
|
payload += "," + std::to_string(state.settings.min_level.value_or(0));
|
||||||
|
payload += "," + std::to_string(state.settings.max_level.value_or(0));
|
||||||
|
payload += "," + std::to_string(state.settings.fade_time.value_or(0));
|
||||||
|
payload += "," + std::to_string(state.settings.fade_rate.value_or(0));
|
||||||
|
payload += "," + std::to_string(scene_known_mask);
|
||||||
|
for (const auto& scene_level : state.scene_levels) {
|
||||||
|
payload += "," + std::to_string(scene_level.value_or(255));
|
||||||
|
}
|
||||||
|
return payload;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ApplyDaliStatePayload(std::string_view raw, GatewayCacheDaliAddressState& state) {
|
||||||
|
const auto values = ParseCsv(raw);
|
||||||
|
if (values.size() < 13 || values[0] != kDaliStatePayloadVersion) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const uint32_t flags = static_cast<uint32_t>(std::max(values[1], 0));
|
||||||
|
state.group_mask_known = (flags & kDaliStateGroupMaskKnown) != 0;
|
||||||
|
state.group_mask = state.group_mask_known ? WordValue(values[3]) : 0;
|
||||||
|
|
||||||
|
state.status = {};
|
||||||
|
state.status.revision = static_cast<uint32_t>(std::max(values[2], 0));
|
||||||
|
state.status.stale = (flags & kDaliStateStatusStale) != 0;
|
||||||
|
state.status.use_min_level = (flags & kDaliStateUseMinLevel) != 0;
|
||||||
|
if ((flags & kDaliStateActualKnown) != 0) {
|
||||||
|
state.status.actual_level = ByteValue(values[4]);
|
||||||
|
}
|
||||||
|
if ((flags & kDaliStateSceneKnown) != 0) {
|
||||||
|
state.status.scene_id = static_cast<uint8_t>(std::min<int>(ByteValue(values[5]), 15));
|
||||||
|
}
|
||||||
|
|
||||||
|
state.settings = {};
|
||||||
|
if ((flags & kDaliStatePowerOnKnown) != 0) {
|
||||||
|
state.settings.power_on_level = ByteValue(values[6]);
|
||||||
|
}
|
||||||
|
if ((flags & kDaliStateSystemFailureKnown) != 0) {
|
||||||
|
state.settings.system_failure_level = ByteValue(values[7]);
|
||||||
|
}
|
||||||
|
if ((flags & kDaliStateMinKnown) != 0) {
|
||||||
|
state.settings.min_level = ByteValue(values[8]);
|
||||||
|
}
|
||||||
|
if ((flags & kDaliStateMaxKnown) != 0) {
|
||||||
|
state.settings.max_level = ByteValue(values[9]);
|
||||||
|
}
|
||||||
|
if ((flags & kDaliStateFadeTimeKnown) != 0) {
|
||||||
|
state.settings.fade_time = ByteValue(values[10]);
|
||||||
|
}
|
||||||
|
if ((flags & kDaliStateFadeRateKnown) != 0) {
|
||||||
|
state.settings.fade_rate = ByteValue(values[11]);
|
||||||
|
}
|
||||||
|
|
||||||
|
state.scene_levels.fill(std::nullopt);
|
||||||
|
const uint16_t scene_known_mask = WordValue(values[12]);
|
||||||
|
for (uint8_t scene_id = 0; scene_id < state.scene_levels.size(); ++scene_id) {
|
||||||
|
const size_t value_index = 13 + scene_id;
|
||||||
|
if ((scene_known_mask & (1U << scene_id)) != 0 && value_index < values.size()) {
|
||||||
|
state.scene_levels[scene_id] = ByteValue(values[value_index]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
GatewayCache::GatewayCache(GatewayCacheConfig config)
|
GatewayCache::GatewayCache(GatewayCacheConfig config)
|
||||||
@@ -269,8 +426,11 @@ esp_err_t GatewayCache::start() {
|
|||||||
return ESP_ERR_NO_MEM;
|
return ESP_ERR_NO_MEM;
|
||||||
}
|
}
|
||||||
|
|
||||||
ESP_LOGI(kTag, "cache started namespace=%s flush_interval_ms=%u reconciliation=%d full_mirror=%d",
|
ESP_LOGI(kTag,
|
||||||
|
"cache started namespace=%s flush_interval_ms=%u refresh_interval_ms=%u "
|
||||||
|
"reconciliation=%d full_mirror=%d",
|
||||||
config_.storage_namespace.c_str(), static_cast<unsigned>(config_.flush_interval_ms),
|
config_.storage_namespace.c_str(), static_cast<unsigned>(config_.flush_interval_ms),
|
||||||
|
static_cast<unsigned>(config_.refresh_interval_ms),
|
||||||
config_.reconciliation_enabled, config_.full_state_mirror_enabled);
|
config_.reconciliation_enabled, config_.full_state_mirror_enabled);
|
||||||
return ESP_OK;
|
return ESP_OK;
|
||||||
}
|
}
|
||||||
@@ -282,6 +442,10 @@ void GatewayCache::preloadChannel(uint8_t gateway_id) {
|
|||||||
}
|
}
|
||||||
ensureSceneStoreLocked(gateway_id);
|
ensureSceneStoreLocked(gateway_id);
|
||||||
ensureGroupStoreLocked(gateway_id);
|
ensureGroupStoreLocked(gateway_id);
|
||||||
|
auto [it, inserted] = dali_states_.try_emplace(gateway_id);
|
||||||
|
if (inserted) {
|
||||||
|
loadDaliStateStoreLocked(gateway_id, it->second);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
GatewayCache::SceneStore GatewayCache::scenes(uint8_t gateway_id) {
|
GatewayCache::SceneStore GatewayCache::scenes(uint8_t gateway_id) {
|
||||||
@@ -595,6 +759,86 @@ GatewayCacheDaliAddressState GatewayCache::daliAddressState(uint8_t gateway_id,
|
|||||||
return ensureDaliAddressStateLocked(gateway_id, short_address);
|
return ensureDaliAddressStateLocked(gateway_id, short_address);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
GatewayCacheDaliPresence GatewayCache::daliAddressPresence(uint8_t gateway_id,
|
||||||
|
uint8_t short_address) {
|
||||||
|
LockGuard guard(lock_);
|
||||||
|
if (short_address >= 64) {
|
||||||
|
return GatewayCacheDaliPresence::kUnknown;
|
||||||
|
}
|
||||||
|
if (const auto it = dali_presence_.find(gateway_id); it != dali_presence_.end()) {
|
||||||
|
return it->second[short_address];
|
||||||
|
}
|
||||||
|
return GatewayCacheDaliPresence::kUnknown;
|
||||||
|
}
|
||||||
|
|
||||||
|
void GatewayCache::markDaliAddressPresence(uint8_t gateway_id, uint8_t short_address,
|
||||||
|
GatewayCacheDaliPresence presence) {
|
||||||
|
LockGuard guard(lock_);
|
||||||
|
markDaliAddressPresenceLocked(gateway_id, short_address, presence);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::optional<GatewayCacheDaliTarget> GatewayCache::decodeDaliTarget(uint8_t raw_addr) {
|
||||||
|
return DecodeDaliTarget(raw_addr);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<uint8_t> GatewayCache::reconciliationAddresses(
|
||||||
|
uint8_t gateway_id, std::optional<GatewayCacheDaliTarget> target) {
|
||||||
|
LockGuard guard(lock_);
|
||||||
|
std::vector<uint8_t> addresses;
|
||||||
|
|
||||||
|
auto presence = [&](uint8_t short_address) {
|
||||||
|
if (const auto it = dali_presence_.find(gateway_id); it != dali_presence_.end()) {
|
||||||
|
return it->second[short_address];
|
||||||
|
}
|
||||||
|
return GatewayCacheDaliPresence::kUnknown;
|
||||||
|
};
|
||||||
|
auto add_if_known_online = [&](uint8_t short_address) {
|
||||||
|
if (short_address < 64 && presence(short_address) == GatewayCacheDaliPresence::kOnline) {
|
||||||
|
addresses.push_back(short_address);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
if (!target.has_value()) {
|
||||||
|
for (uint8_t short_address = 0; short_address < 64; ++short_address) {
|
||||||
|
add_if_known_online(short_address);
|
||||||
|
}
|
||||||
|
return addresses;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (target->kind) {
|
||||||
|
case GatewayCacheDaliTargetKind::kShortAddress:
|
||||||
|
if (target->value < 64 && presence(target->value) != GatewayCacheDaliPresence::kOffline) {
|
||||||
|
addresses.push_back(target->value);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case GatewayCacheDaliTargetKind::kGroup: {
|
||||||
|
if (target->value >= 16) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
const uint16_t bit = static_cast<uint16_t>(1U << target->value);
|
||||||
|
auto [states_it, inserted] = dali_states_.try_emplace(gateway_id);
|
||||||
|
if (inserted) {
|
||||||
|
loadDaliStateStoreLocked(gateway_id, states_it->second);
|
||||||
|
}
|
||||||
|
for (uint8_t short_address = 0; short_address < states_it->second.size(); ++short_address) {
|
||||||
|
const auto& state = states_it->second[short_address];
|
||||||
|
if (state.group_mask_known && (state.group_mask & bit) != 0) {
|
||||||
|
add_if_known_online(short_address);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case GatewayCacheDaliTargetKind::kBroadcast:
|
||||||
|
for (uint8_t short_address = 0; short_address < 64; ++short_address) {
|
||||||
|
add_if_known_online(short_address);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return addresses;
|
||||||
|
}
|
||||||
|
|
||||||
GatewayCacheDaliRuntimeStatus GatewayCache::daliGroupStatus(uint8_t gateway_id,
|
GatewayCacheDaliRuntimeStatus GatewayCache::daliGroupStatus(uint8_t gateway_id,
|
||||||
uint8_t group_id) {
|
uint8_t group_id) {
|
||||||
LockGuard guard(lock_);
|
LockGuard guard(lock_);
|
||||||
@@ -620,6 +864,7 @@ bool GatewayCache::setDaliGroupMask(uint8_t gateway_id, uint8_t short_address,
|
|||||||
state.group_mask_known = group_mask.has_value();
|
state.group_mask_known = group_mask.has_value();
|
||||||
state.group_mask = group_mask.value_or(0);
|
state.group_mask = group_mask.value_or(0);
|
||||||
refreshDaliAddressAggregateStatusLocked(gateway_id, state);
|
refreshDaliAddressAggregateStatusLocked(gateway_id, state);
|
||||||
|
dirty_ = true;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -632,6 +877,7 @@ bool GatewayCache::setDaliSceneLevel(uint8_t gateway_id, uint8_t short_address,
|
|||||||
|
|
||||||
auto& state = ensureDaliAddressStateLocked(gateway_id, short_address);
|
auto& state = ensureDaliAddressStateLocked(gateway_id, short_address);
|
||||||
state.scene_levels[scene_id] = level;
|
state.scene_levels[scene_id] = level;
|
||||||
|
dirty_ = true;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -644,6 +890,31 @@ bool GatewayCache::setDaliSettings(uint8_t gateway_id, uint8_t short_address,
|
|||||||
|
|
||||||
auto& state = ensureDaliAddressStateLocked(gateway_id, short_address);
|
auto& state = ensureDaliAddressStateLocked(gateway_id, short_address);
|
||||||
state.settings = settings.value_or(GatewayCacheDaliSettingsSnapshot{});
|
state.settings = settings.value_or(GatewayCacheDaliSettingsSnapshot{});
|
||||||
|
dirty_ = true;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool GatewayCache::setDaliActualLevel(uint8_t gateway_id, uint8_t short_address,
|
||||||
|
std::optional<uint8_t> level) {
|
||||||
|
LockGuard guard(lock_);
|
||||||
|
if (short_address >= 64) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
GatewayCacheDaliRuntimeStatus status;
|
||||||
|
status.actual_level = level;
|
||||||
|
status.revision = nextDaliRuntimeRevisionLocked();
|
||||||
|
status.stale = false;
|
||||||
|
auto& state = ensureDaliAddressStateLocked(gateway_id, short_address);
|
||||||
|
state.status.scene_id.reset();
|
||||||
|
state.status.use_min_level = false;
|
||||||
|
applyDaliRuntimeStatusToAddressLocked(state, status);
|
||||||
|
if (!level.has_value()) {
|
||||||
|
state.status.actual_level.reset();
|
||||||
|
state.status.revision = status.revision;
|
||||||
|
state.status.stale = false;
|
||||||
|
}
|
||||||
|
dirty_ = true;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -712,7 +983,8 @@ bool GatewayCache::observeDaliCommand(uint8_t gateway_id, uint8_t raw_addr, uint
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ShouldMirrorObservedMutation(origin, priority_mode_)) {
|
if (ShouldAlwaysMirrorObservedStatus(raw_addr, command) ||
|
||||||
|
ShouldMirrorObservedMutation(origin, priority_mode_)) {
|
||||||
mirrorDaliCommandLocked(gateway_id, raw_addr, command);
|
mirrorDaliCommandLocked(gateway_id, raw_addr, command);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -791,12 +1063,15 @@ bool GatewayCache::mirrorDaliCommandLocked(uint8_t gateway_id, uint8_t raw_addr,
|
|||||||
GatewayCacheDaliRuntimeStatus status;
|
GatewayCacheDaliRuntimeStatus status;
|
||||||
status.actual_level = command;
|
status.actual_level = command;
|
||||||
status.revision = nextDaliRuntimeRevisionLocked();
|
status.revision = nextDaliRuntimeRevisionLocked();
|
||||||
|
status.stale = false;
|
||||||
applyDaliTargetRuntimeStatusLocked(gateway_id, *target, status);
|
applyDaliTargetRuntimeStatusLocked(gateway_id, *target, status);
|
||||||
|
dirty_ = true;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (command == kDaliCmdReset) {
|
if (command == kDaliCmdReset) {
|
||||||
clearDaliTargetStateLocked(gateway_id, *target, nextDaliRuntimeRevisionLocked());
|
clearDaliTargetStateLocked(gateway_id, *target, nextDaliRuntimeRevisionLocked());
|
||||||
|
dirty_ = true;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -804,7 +1079,9 @@ bool GatewayCache::mirrorDaliCommandLocked(uint8_t gateway_id, uint8_t raw_addr,
|
|||||||
GatewayCacheDaliRuntimeStatus status;
|
GatewayCacheDaliRuntimeStatus status;
|
||||||
status.actual_level = command == kDaliCmdOff ? 0 : 254;
|
status.actual_level = command == kDaliCmdOff ? 0 : 254;
|
||||||
status.revision = nextDaliRuntimeRevisionLocked();
|
status.revision = nextDaliRuntimeRevisionLocked();
|
||||||
|
status.stale = false;
|
||||||
applyDaliTargetRuntimeStatusLocked(gateway_id, *target, status);
|
applyDaliTargetRuntimeStatusLocked(gateway_id, *target, status);
|
||||||
|
dirty_ = true;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -812,7 +1089,9 @@ bool GatewayCache::mirrorDaliCommandLocked(uint8_t gateway_id, uint8_t raw_addr,
|
|||||||
GatewayCacheDaliRuntimeStatus status;
|
GatewayCacheDaliRuntimeStatus status;
|
||||||
status.use_min_level = true;
|
status.use_min_level = true;
|
||||||
status.revision = nextDaliRuntimeRevisionLocked();
|
status.revision = nextDaliRuntimeRevisionLocked();
|
||||||
|
status.stale = false;
|
||||||
applyDaliTargetRuntimeStatusLocked(gateway_id, *target, status);
|
applyDaliTargetRuntimeStatusLocked(gateway_id, *target, status);
|
||||||
|
dirty_ = true;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -820,7 +1099,9 @@ bool GatewayCache::mirrorDaliCommandLocked(uint8_t gateway_id, uint8_t raw_addr,
|
|||||||
GatewayCacheDaliRuntimeStatus status;
|
GatewayCacheDaliRuntimeStatus status;
|
||||||
status.scene_id = static_cast<uint8_t>(command - kDaliCmdGoToSceneMin);
|
status.scene_id = static_cast<uint8_t>(command - kDaliCmdGoToSceneMin);
|
||||||
status.revision = nextDaliRuntimeRevisionLocked();
|
status.revision = nextDaliRuntimeRevisionLocked();
|
||||||
|
status.stale = false;
|
||||||
applyDaliTargetRuntimeStatusLocked(gateway_id, *target, status);
|
applyDaliTargetRuntimeStatusLocked(gateway_id, *target, status);
|
||||||
|
dirty_ = true;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -828,6 +1109,7 @@ bool GatewayCache::mirrorDaliCommandLocked(uint8_t gateway_id, uint8_t raw_addr,
|
|||||||
applyDaliTargetGroupMutationLocked(gateway_id, *target,
|
applyDaliTargetGroupMutationLocked(gateway_id, *target,
|
||||||
static_cast<uint8_t>(command & 0x0F),
|
static_cast<uint8_t>(command & 0x0F),
|
||||||
command < (kDaliCmdAddToGroupMin + 16));
|
command < (kDaliCmdAddToGroupMin + 16));
|
||||||
|
dirty_ = true;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -836,6 +1118,7 @@ bool GatewayCache::mirrorDaliCommandLocked(uint8_t gateway_id, uint8_t raw_addr,
|
|||||||
applyDaliTargetSceneLevelLocked(gateway_id, *target,
|
applyDaliTargetSceneLevelLocked(gateway_id, *target,
|
||||||
static_cast<uint8_t>(command - kDaliCmdSetSceneMin),
|
static_cast<uint8_t>(command - kDaliCmdSetSceneMin),
|
||||||
*dtr_state.dtr0);
|
*dtr_state.dtr0);
|
||||||
|
dirty_ = true;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -843,12 +1126,14 @@ bool GatewayCache::mirrorDaliCommandLocked(uint8_t gateway_id, uint8_t raw_addr,
|
|||||||
applyDaliTargetSceneLevelLocked(
|
applyDaliTargetSceneLevelLocked(
|
||||||
gateway_id, *target, static_cast<uint8_t>(command - (kDaliCmdSetSceneMin + 16)),
|
gateway_id, *target, static_cast<uint8_t>(command - (kDaliCmdSetSceneMin + 16)),
|
||||||
static_cast<uint8_t>(255U));
|
static_cast<uint8_t>(255U));
|
||||||
|
dirty_ = true;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (command >= kDaliCmdStoreDtrAsMaxLevel && command <= kDaliCmdStoreDtrAsFadeRate &&
|
if (command >= kDaliCmdStoreDtrAsMaxLevel && command <= kDaliCmdStoreDtrAsFadeRate &&
|
||||||
dtr_state.dtr0.has_value()) {
|
dtr_state.dtr0.has_value()) {
|
||||||
applyDaliTargetSettingsLocked(gateway_id, *target, command, *dtr_state.dtr0);
|
applyDaliTargetSettingsLocked(gateway_id, *target, command, *dtr_state.dtr0);
|
||||||
|
dirty_ = true;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -977,6 +1262,7 @@ void GatewayCache::applyDaliRuntimeStatusToAddressLocked(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
state.status.revision = status.revision;
|
state.status.revision = status.revision;
|
||||||
|
state.status.stale = status.stale;
|
||||||
}
|
}
|
||||||
|
|
||||||
void GatewayCache::applyDaliTargetGroupMutationLocked(uint8_t gateway_id,
|
void GatewayCache::applyDaliTargetGroupMutationLocked(uint8_t gateway_id,
|
||||||
@@ -1127,7 +1413,9 @@ void GatewayCache::refreshDaliAddressAggregateStatusLocked(uint8_t gateway_id,
|
|||||||
|
|
||||||
if (const auto broadcast = dali_broadcast_status_.find(gateway_id);
|
if (const auto broadcast = dali_broadcast_status_.find(gateway_id);
|
||||||
broadcast != dali_broadcast_status_.end()) {
|
broadcast != dali_broadcast_status_.end()) {
|
||||||
applyDaliRuntimeStatusToAddressLocked(state, broadcast->second);
|
if (!broadcast->second.stale) {
|
||||||
|
applyDaliRuntimeStatusToAddressLocked(state, broadcast->second);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const auto groups = dali_group_status_.find(gateway_id);
|
const auto groups = dali_group_status_.find(gateway_id);
|
||||||
@@ -1137,6 +1425,9 @@ void GatewayCache::refreshDaliAddressAggregateStatusLocked(uint8_t gateway_id,
|
|||||||
for (uint8_t group_id = 0; group_id < groups->second.size(); ++group_id) {
|
for (uint8_t group_id = 0; group_id < groups->second.size(); ++group_id) {
|
||||||
const uint16_t bit = static_cast<uint16_t>(1U << group_id);
|
const uint16_t bit = static_cast<uint16_t>(1U << group_id);
|
||||||
if ((state.group_mask & bit) != 0) {
|
if ((state.group_mask & bit) != 0) {
|
||||||
|
if (groups->second[group_id].stale) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
applyDaliRuntimeStatusToAddressLocked(state, groups->second[group_id]);
|
applyDaliRuntimeStatusToAddressLocked(state, groups->second[group_id]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1209,6 +1500,14 @@ bool GatewayCache::flushDirty() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for (const auto& [gateway_id, states] : dali_states_) {
|
||||||
|
for (uint8_t short_address = 0; short_address < states.size(); ++short_address) {
|
||||||
|
if (!persistDaliAddressStateLocked(gateway_id, short_address, states[short_address])) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const esp_err_t commit_err = nvs_commit(storage_);
|
const esp_err_t commit_err = nvs_commit(storage_);
|
||||||
if (commit_err != ESP_OK) {
|
if (commit_err != ESP_OK) {
|
||||||
ESP_LOGE(kTag, "cache commit failed: %s", esp_err_to_name(commit_err));
|
ESP_LOGE(kTag, "cache commit failed: %s", esp_err_to_name(commit_err));
|
||||||
@@ -1288,6 +1587,18 @@ bool GatewayCache::persistGroupLocked(uint8_t gateway_id, uint8_t group_id,
|
|||||||
return commitStorageLocked();
|
return commitStorageLocked();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool GatewayCache::persistDaliAddressStateLocked(
|
||||||
|
uint8_t gateway_id, uint8_t short_address, const GatewayCacheDaliAddressState& state) {
|
||||||
|
if (short_address >= 64) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (!IsDefaultDaliAddressState(state)) {
|
||||||
|
return writeStringLocked(ShortKey("ds", gateway_id, short_address),
|
||||||
|
BuildDaliStatePayload(state));
|
||||||
|
}
|
||||||
|
return eraseKeyLocked(ShortKey("ds", gateway_id, short_address));
|
||||||
|
}
|
||||||
|
|
||||||
bool GatewayCache::commitStorageLocked() {
|
bool GatewayCache::commitStorageLocked() {
|
||||||
if (storage_ == 0) {
|
if (storage_ == 0) {
|
||||||
return false;
|
return false;
|
||||||
@@ -1304,10 +1615,26 @@ bool GatewayCache::shouldTrackUpdateFlagsLocked() const {
|
|||||||
return config_.cache_enabled && config_.reconciliation_enabled;
|
return config_.cache_enabled && config_.reconciliation_enabled;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void GatewayCache::markDaliAddressPresenceLocked(uint8_t gateway_id, uint8_t short_address,
|
||||||
|
GatewayCacheDaliPresence presence) {
|
||||||
|
if (short_address >= 64) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
auto& states = dali_presence_[gateway_id];
|
||||||
|
const auto previous = states[short_address];
|
||||||
|
states[short_address] = presence;
|
||||||
|
if (previous != presence) {
|
||||||
|
ESP_LOGD(kTag, "presence gateway=%u short=%u state=%u", gateway_id, short_address,
|
||||||
|
static_cast<unsigned>(presence));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
GatewayCacheDaliAddressState& GatewayCache::ensureDaliAddressStateLocked(uint8_t gateway_id,
|
GatewayCacheDaliAddressState& GatewayCache::ensureDaliAddressStateLocked(uint8_t gateway_id,
|
||||||
uint8_t short_address) {
|
uint8_t short_address) {
|
||||||
auto [it, inserted] = dali_states_.try_emplace(gateway_id);
|
auto [it, inserted] = dali_states_.try_emplace(gateway_id);
|
||||||
(void)inserted;
|
if (inserted) {
|
||||||
|
loadDaliStateStoreLocked(gateway_id, it->second);
|
||||||
|
}
|
||||||
return it->second[short_address];
|
return it->second[short_address];
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1377,6 +1704,23 @@ void GatewayCache::loadGroupStoreLocked(uint8_t gateway_id, GroupStore& groups)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void GatewayCache::loadDaliStateStoreLocked(
|
||||||
|
uint8_t gateway_id, std::array<GatewayCacheDaliAddressState, 64>& states) {
|
||||||
|
for (uint8_t short_address = 0; short_address < states.size(); ++short_address) {
|
||||||
|
ClearDaliState(states[short_address]);
|
||||||
|
const auto raw = readStringLocked(ShortKey("ds", gateway_id, short_address));
|
||||||
|
if (!raw.empty()) {
|
||||||
|
ApplyDaliStatePayload(raw, states[short_address]);
|
||||||
|
if (states[short_address].status.anyKnown()) {
|
||||||
|
states[short_address].status.stale = true;
|
||||||
|
}
|
||||||
|
if (states[short_address].status.revision > dali_runtime_revision_) {
|
||||||
|
dali_runtime_revision_ = states[short_address].status.revision;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
std::string GatewayCache::readStringLocked(std::string_view key) {
|
std::string GatewayCache::readStringLocked(std::string_view key) {
|
||||||
if (!openStorageLocked()) {
|
if (!openStorageLocked()) {
|
||||||
return {};
|
return {};
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
idf_component_register(
|
idf_component_register(
|
||||||
SRCS "src/gateway_controller.cpp"
|
SRCS "src/gateway_controller.cpp"
|
||||||
INCLUDE_DIRS "include"
|
INCLUDE_DIRS "include"
|
||||||
REQUIRES dali_domain gateway_runtime gateway_cache freertos log
|
REQUIRES dali_domain gateway_runtime gateway_cache gateway_bridge freertos log
|
||||||
)
|
)
|
||||||
|
|
||||||
set_property(TARGET ${COMPONENT_LIB} PROPERTY CXX_STANDARD 17)
|
set_property(TARGET ${COMPONENT_LIB} PROPERTY CXX_STANDARD 17)
|
||||||
|
|||||||
@@ -5,6 +5,7 @@
|
|||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
#include <functional>
|
#include <functional>
|
||||||
#include <map>
|
#include <map>
|
||||||
|
#include <optional>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <string_view>
|
#include <string_view>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
@@ -19,10 +20,11 @@ namespace gateway {
|
|||||||
|
|
||||||
class DaliDomainService;
|
class DaliDomainService;
|
||||||
struct DaliRawFrame;
|
struct DaliRawFrame;
|
||||||
|
class GatewayBridgeService;
|
||||||
class GatewayRuntime;
|
class GatewayRuntime;
|
||||||
|
|
||||||
struct GatewayControllerConfig {
|
struct GatewayControllerConfig {
|
||||||
uint32_t task_stack_size{6144};
|
uint32_t task_stack_size{12288};
|
||||||
UBaseType_t task_priority{5};
|
UBaseType_t task_priority{5};
|
||||||
int color_temperature_min{2000};
|
int color_temperature_min{2000};
|
||||||
int color_temperature_max{6500};
|
int color_temperature_max{6500};
|
||||||
@@ -32,6 +34,11 @@ struct GatewayControllerConfig {
|
|||||||
bool ip_router_supported{true};
|
bool ip_router_supported{true};
|
||||||
bool internal_scene_supported{true};
|
bool internal_scene_supported{true};
|
||||||
bool internal_group_supported{true};
|
bool internal_group_supported{true};
|
||||||
|
bool cache_supported{true};
|
||||||
|
uint32_t cache_refresh_interval_ms{120000};
|
||||||
|
uint32_t cache_refresh_idle_ms{100};
|
||||||
|
uint32_t cache_host_snooze_ms{5000};
|
||||||
|
uint32_t cache_host_echo_ms{250};
|
||||||
};
|
};
|
||||||
|
|
||||||
struct GatewayChannelSnapshot {
|
struct GatewayChannelSnapshot {
|
||||||
@@ -45,6 +52,13 @@ struct GatewayChannelSnapshot {
|
|||||||
uint8_t group_mask_high{0};
|
uint8_t group_mask_high{0};
|
||||||
bool allocating{false};
|
bool allocating{false};
|
||||||
int last_alloc_addr{0};
|
int last_alloc_addr{0};
|
||||||
|
bool operation_active{false};
|
||||||
|
uint8_t operation_request_id{0};
|
||||||
|
uint16_t operation_id{0};
|
||||||
|
uint8_t operation_status{0};
|
||||||
|
uint8_t operation_progress{0};
|
||||||
|
uint8_t operation_target{0};
|
||||||
|
uint8_t operation_count{0};
|
||||||
};
|
};
|
||||||
|
|
||||||
struct GatewayControllerSnapshot {
|
struct GatewayControllerSnapshot {
|
||||||
@@ -58,6 +72,19 @@ struct GatewayControllerSnapshot {
|
|||||||
std::vector<GatewayChannelSnapshot> channels;
|
std::vector<GatewayChannelSnapshot> channels;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum class GatewayCommandTransactionStatus : uint8_t {
|
||||||
|
kOk = 0,
|
||||||
|
kInvalidFrame = 1,
|
||||||
|
kQueueRejected = 2,
|
||||||
|
kTimeout = 3,
|
||||||
|
kNoResponse = 4,
|
||||||
|
};
|
||||||
|
|
||||||
|
struct GatewayCommandTransactionResult {
|
||||||
|
GatewayCommandTransactionStatus status{GatewayCommandTransactionStatus::kNoResponse};
|
||||||
|
std::vector<uint8_t> frames;
|
||||||
|
};
|
||||||
|
|
||||||
class GatewayController {
|
class GatewayController {
|
||||||
public:
|
public:
|
||||||
using NotificationSink = std::function<void(const std::vector<uint8_t>& frame)>;
|
using NotificationSink = std::function<void(const std::vector<uint8_t>& frame)>;
|
||||||
@@ -72,10 +99,16 @@ class GatewayController {
|
|||||||
|
|
||||||
esp_err_t start();
|
esp_err_t start();
|
||||||
bool enqueueCommandFrame(const std::vector<uint8_t>& frame);
|
bool enqueueCommandFrame(const std::vector<uint8_t>& frame);
|
||||||
|
GatewayCommandTransactionResult transactCommandFrame(
|
||||||
|
const std::vector<uint8_t>& frame,
|
||||||
|
uint32_t timeout_ms = 700,
|
||||||
|
uint32_t idle_ms = 30,
|
||||||
|
size_t max_response_bytes = 2048);
|
||||||
void addNotificationSink(NotificationSink sink);
|
void addNotificationSink(NotificationSink sink);
|
||||||
void addBleStateSink(BleStateSink sink);
|
void addBleStateSink(BleStateSink sink);
|
||||||
void addWifiStateSink(WifiStateSink sink);
|
void addWifiStateSink(WifiStateSink sink);
|
||||||
void addGatewayNameSink(GatewayNameSink sink);
|
void addGatewayNameSink(GatewayNameSink sink);
|
||||||
|
void setBridgeService(GatewayBridgeService* bridge_service);
|
||||||
|
|
||||||
bool setupMode() const;
|
bool setupMode() const;
|
||||||
bool wirelessSetupMode() const;
|
bool wirelessSetupMode() const;
|
||||||
@@ -83,8 +116,16 @@ class GatewayController {
|
|||||||
bool bleEnabled() const;
|
bool bleEnabled() const;
|
||||||
bool wifiEnabled() const;
|
bool wifiEnabled() const;
|
||||||
bool ipRouterEnabled() const;
|
bool ipRouterEnabled() const;
|
||||||
|
bool rawReportingEnabled(uint8_t gateway_id) const;
|
||||||
GatewayControllerSnapshot snapshot();
|
GatewayControllerSnapshot snapshot();
|
||||||
|
|
||||||
|
struct ParsedTlv {
|
||||||
|
uint8_t type{0};
|
||||||
|
std::vector<uint8_t> value;
|
||||||
|
};
|
||||||
|
|
||||||
|
using ParsedTlvMap = std::map<uint8_t, ParsedTlv>;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
struct ReconciliationJob {
|
struct ReconciliationJob {
|
||||||
enum class Phase : uint8_t {
|
enum class Phase : uint8_t {
|
||||||
@@ -96,28 +137,95 @@ class GatewayController {
|
|||||||
|
|
||||||
GatewayCacheChannelFlags flags{};
|
GatewayCacheChannelFlags flags{};
|
||||||
Phase phase{Phase::kReloadFlags};
|
Phase phase{Phase::kReloadFlags};
|
||||||
uint8_t short_address{0};
|
std::optional<GatewayCacheDaliTarget> target;
|
||||||
|
std::vector<uint8_t> addresses;
|
||||||
|
size_t address_index{0};
|
||||||
uint8_t scene_id{0};
|
uint8_t scene_id{0};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct BridgeTransportRequestState {
|
||||||
|
uint8_t version{0};
|
||||||
|
uint16_t payload_length{0};
|
||||||
|
uint8_t total_chunks{0};
|
||||||
|
std::map<uint8_t, std::vector<uint8_t>> chunks;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct CacheRefreshJob {
|
||||||
|
TickType_t next_due_tick{0};
|
||||||
|
uint8_t short_address{0};
|
||||||
|
};
|
||||||
|
|
||||||
|
struct GatewayOperationRuntimeState {
|
||||||
|
bool active{false};
|
||||||
|
bool cancel_requested{false};
|
||||||
|
uint8_t request_id{0};
|
||||||
|
uint16_t operation_id{0};
|
||||||
|
uint8_t status{0};
|
||||||
|
uint8_t progress{0};
|
||||||
|
uint8_t target{0};
|
||||||
|
uint8_t count{0};
|
||||||
|
};
|
||||||
|
|
||||||
|
struct GatewayRawReportLease {
|
||||||
|
bool enabled{false};
|
||||||
|
TickType_t expires_at{0};
|
||||||
|
};
|
||||||
|
|
||||||
|
struct GatewayOperationTaskContext {
|
||||||
|
GatewayController* controller{nullptr};
|
||||||
|
uint8_t gateway_id{0};
|
||||||
|
uint8_t request_id{0};
|
||||||
|
uint16_t operation_id{0};
|
||||||
|
ParsedTlvMap fields;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct TransactionWaiter {
|
||||||
|
uint8_t gateway_id{0};
|
||||||
|
uint8_t opcode{0};
|
||||||
|
SemaphoreHandle_t signal{nullptr};
|
||||||
|
std::vector<uint8_t> frames;
|
||||||
|
size_t max_response_bytes{0};
|
||||||
|
bool overflow{false};
|
||||||
|
};
|
||||||
|
|
||||||
static void TaskEntry(void* arg);
|
static void TaskEntry(void* arg);
|
||||||
|
static void OperationTaskEntry(void* arg);
|
||||||
void taskLoop();
|
void taskLoop();
|
||||||
|
void runOperationTask(GatewayOperationTaskContext* context);
|
||||||
void dispatchCommand(const std::vector<uint8_t>& command);
|
void dispatchCommand(const std::vector<uint8_t>& command);
|
||||||
void scheduleReconciliation(uint8_t gateway_id);
|
void scheduleReconciliation(uint8_t gateway_id,
|
||||||
|
std::optional<GatewayCacheDaliTarget> target = std::nullopt);
|
||||||
bool hasPendingReconciliation() const;
|
bool hasPendingReconciliation() const;
|
||||||
|
bool cacheRefreshEnabled() const;
|
||||||
|
bool cacheMaintenanceSnoozed(uint8_t gateway_id) const;
|
||||||
bool runMaintenanceStep();
|
bool runMaintenanceStep();
|
||||||
bool runReconciliationStep(uint8_t gateway_id, ReconciliationJob& job);
|
bool runReconciliationStep(uint8_t gateway_id, ReconciliationJob& job);
|
||||||
|
bool runCacheRefreshStep();
|
||||||
void reconcileGroupStep(uint8_t gateway_id, uint8_t short_address);
|
void reconcileGroupStep(uint8_t gateway_id, uint8_t short_address);
|
||||||
void reconcileSceneStep(uint8_t gateway_id, uint8_t short_address, uint8_t scene_id);
|
void reconcileSceneStep(uint8_t gateway_id, uint8_t short_address, uint8_t scene_id);
|
||||||
void reconcileSettingsStep(uint8_t gateway_id, uint8_t short_address);
|
void reconcileSettingsStep(uint8_t gateway_id, uint8_t short_address);
|
||||||
|
|
||||||
bool hasGateway(uint8_t gateway_id) const;
|
bool hasGateway(uint8_t gateway_id) const;
|
||||||
std::vector<uint8_t> gatewayIds() const;
|
std::vector<uint8_t> gatewayIds() const;
|
||||||
|
std::optional<uint8_t> gatewayIdForChannelNumber(uint8_t channel_number) const;
|
||||||
std::string gatewayName(uint8_t gateway_id) const;
|
std::string gatewayName(uint8_t gateway_id) const;
|
||||||
void refreshRuntimeGatewayNames();
|
void refreshRuntimeGatewayNames();
|
||||||
void publishPayload(uint8_t gateway_id, const std::vector<uint8_t>& payload);
|
void publishPayload(uint8_t gateway_id, const std::vector<uint8_t>& payload);
|
||||||
void publishFrame(const std::vector<uint8_t>& frame);
|
void publishFrame(const std::vector<uint8_t>& frame);
|
||||||
|
void publishRawReportLeaseResponse(uint8_t gateway_id, uint8_t status);
|
||||||
|
void publishOperationEvent(uint8_t gateway_id, uint8_t request_id, uint16_t operation_id,
|
||||||
|
uint8_t event, uint8_t status, uint8_t progress,
|
||||||
|
uint8_t target, uint8_t count);
|
||||||
|
void publishOperationResultChunks(uint8_t gateway_id, uint8_t request_id,
|
||||||
|
uint16_t operation_id,
|
||||||
|
const std::vector<uint8_t>& tlv_payload);
|
||||||
|
bool transactionFrameMatches(const TransactionWaiter& waiter,
|
||||||
|
const std::vector<uint8_t>& frame) const;
|
||||||
|
void captureTransactionFrame(const std::vector<uint8_t>& frame);
|
||||||
void handleDaliRawFrame(const DaliRawFrame& frame);
|
void handleDaliRawFrame(const DaliRawFrame& frame);
|
||||||
|
bool handleApplicationControllerFrame(const DaliRawFrame& frame);
|
||||||
|
std::optional<uint8_t> applicationControllerResponse(uint8_t gateway_id, uint8_t first,
|
||||||
|
uint8_t instance, uint8_t opcode) const;
|
||||||
|
|
||||||
bool sendRawAndMirror(uint8_t gateway_id, uint8_t raw_addr, uint8_t command);
|
bool sendRawAndMirror(uint8_t gateway_id, uint8_t raw_addr, uint8_t command);
|
||||||
bool sendExtRawAndMirror(uint8_t gateway_id, uint8_t raw_addr, uint8_t command);
|
bool sendExtRawAndMirror(uint8_t gateway_id, uint8_t raw_addr, uint8_t command);
|
||||||
@@ -152,28 +260,63 @@ class GatewayController {
|
|||||||
bool executeGroup(uint8_t gateway_id, uint8_t group_id);
|
bool executeGroup(uint8_t gateway_id, uint8_t group_id);
|
||||||
|
|
||||||
void handleGatewayNameCommand(uint8_t gateway_id, const std::vector<uint8_t>& command);
|
void handleGatewayNameCommand(uint8_t gateway_id, const std::vector<uint8_t>& command);
|
||||||
|
void handleGatewaySerialCommand(uint8_t channel_number, const std::vector<uint8_t>& command);
|
||||||
|
void publishGatewaySerialReport();
|
||||||
|
void publishGatewaySerialResponse(uint8_t status, uint8_t op,
|
||||||
|
const std::vector<uint8_t>& data);
|
||||||
|
bool gatewaySerialMatches(const std::vector<uint8_t>& command) const;
|
||||||
void handleGatewayIdentityCommand(uint8_t gateway_id, uint8_t op);
|
void handleGatewayIdentityCommand(uint8_t gateway_id, uint8_t op);
|
||||||
void handleAllocationCommand(uint8_t gateway_id, const std::vector<uint8_t>& command);
|
void handleAllocationCommand(uint8_t gateway_id, const std::vector<uint8_t>& command);
|
||||||
|
void handleRawReportLeaseCommand(uint8_t gateway_id, const std::vector<uint8_t>& command);
|
||||||
|
void handleGatewayOperationCommand(uint8_t gateway_id, const std::vector<uint8_t>& command);
|
||||||
|
bool operationActive(uint8_t gateway_id) const;
|
||||||
|
bool operationCancelRequested(uint8_t gateway_id, uint8_t request_id) const;
|
||||||
|
bool startOperation(uint8_t gateway_id, uint8_t request_id, uint16_t operation_id,
|
||||||
|
ParsedTlvMap fields);
|
||||||
|
void abortOperation(uint8_t gateway_id, uint8_t request_id);
|
||||||
|
void finishOperation(uint8_t gateway_id, uint8_t request_id, uint8_t status,
|
||||||
|
uint8_t progress, uint8_t target, uint8_t count);
|
||||||
|
ParsedTlvMap parseOperationTlvs(const uint8_t* data, size_t len, bool* ok) const;
|
||||||
void handleInternalSceneCommand(uint8_t gateway_id, const std::vector<uint8_t>& command);
|
void handleInternalSceneCommand(uint8_t gateway_id, const std::vector<uint8_t>& command);
|
||||||
void handleInternalGroupCommand(uint8_t gateway_id, const std::vector<uint8_t>& command);
|
void handleInternalGroupCommand(uint8_t gateway_id, const std::vector<uint8_t>& command);
|
||||||
|
void handleGatewayCacheCommand(uint8_t gateway_id, const std::vector<uint8_t>& command);
|
||||||
|
void handleBridgeTransportCommand(uint8_t gateway_id, const std::vector<uint8_t>& command);
|
||||||
|
void publishBridgeTransportResponse(uint8_t gateway_id, uint8_t version, uint8_t sequence,
|
||||||
|
std::string_view response);
|
||||||
|
|
||||||
GatewayRuntime& runtime_;
|
GatewayRuntime& runtime_;
|
||||||
DaliDomainService& dali_domain_;
|
DaliDomainService& dali_domain_;
|
||||||
GatewayCache& cache_;
|
GatewayCache& cache_;
|
||||||
|
GatewayBridgeService* bridge_service_{nullptr};
|
||||||
GatewayControllerConfig config_;
|
GatewayControllerConfig config_;
|
||||||
TaskHandle_t task_handle_{nullptr};
|
TaskHandle_t task_handle_{nullptr};
|
||||||
SemaphoreHandle_t maintenance_lock_{nullptr};
|
SemaphoreHandle_t maintenance_lock_{nullptr};
|
||||||
|
SemaphoreHandle_t transaction_lock_{nullptr};
|
||||||
|
SemaphoreHandle_t operation_lock_{nullptr};
|
||||||
std::vector<NotificationSink> notification_sinks_;
|
std::vector<NotificationSink> notification_sinks_;
|
||||||
std::vector<BleStateSink> ble_state_sinks_;
|
std::vector<BleStateSink> ble_state_sinks_;
|
||||||
std::vector<WifiStateSink> wifi_state_sinks_;
|
std::vector<WifiStateSink> wifi_state_sinks_;
|
||||||
std::vector<GatewayNameSink> gateway_name_sinks_;
|
std::vector<GatewayNameSink> gateway_name_sinks_;
|
||||||
|
std::map<uint16_t, BridgeTransportRequestState> bridge_transport_requests_;
|
||||||
|
std::vector<TransactionWaiter*> transaction_waiters_;
|
||||||
std::map<uint8_t, ReconciliationJob> reconciliation_jobs_;
|
std::map<uint8_t, ReconciliationJob> reconciliation_jobs_;
|
||||||
|
std::map<uint8_t, CacheRefreshJob> cache_refresh_jobs_;
|
||||||
|
std::map<uint8_t, GatewayOperationRuntimeState> operation_states_;
|
||||||
|
std::map<uint8_t, GatewayRawReportLease> raw_report_leases_;
|
||||||
std::atomic<int> maintenance_activity_gateway_{-1};
|
std::atomic<int> maintenance_activity_gateway_{-1};
|
||||||
bool setup_mode_{false};
|
bool setup_mode_{false};
|
||||||
bool wireless_setup_mode_{false};
|
bool wireless_setup_mode_{false};
|
||||||
bool ble_enabled_{false};
|
bool ble_enabled_{false};
|
||||||
bool wifi_enabled_{false};
|
bool wifi_enabled_{false};
|
||||||
bool ip_router_enabled_{true};
|
bool ip_router_enabled_{true};
|
||||||
|
bool application_controller_enabled_{true};
|
||||||
|
bool application_controller_power_cycle_notification_{true};
|
||||||
|
bool application_controller_power_cycle_seen_{true};
|
||||||
|
bool application_controller_reset_state_{false};
|
||||||
|
uint8_t application_controller_operating_mode_{0};
|
||||||
|
uint8_t application_controller_dtr0_{0};
|
||||||
|
uint8_t application_controller_dtr1_{0};
|
||||||
|
uint8_t application_controller_dtr2_{0};
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace gateway
|
} // namespace gateway
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -1,7 +1,18 @@
|
|||||||
idf_component_register(
|
idf_component_register(
|
||||||
SRCS "src/gateway_knx.cpp"
|
SRCS
|
||||||
|
"src/gateway_knx.cpp"
|
||||||
|
"src/gateway_knx_bridge.cpp"
|
||||||
|
"src/gateway_knx_router_lifecycle.cpp"
|
||||||
|
"src/gateway_knx_router_openknx.cpp"
|
||||||
|
"src/gateway_knx_router_packets.cpp"
|
||||||
|
"src/gateway_knx_router_services.cpp"
|
||||||
|
"src/gateway_knx_secure_transport.cpp"
|
||||||
|
"src/knx_device_broker.cpp"
|
||||||
|
"src/oam_router_runtime.cpp"
|
||||||
|
"src/ets_device_runtime.cpp"
|
||||||
|
"src/ets_memory_loader.cpp"
|
||||||
INCLUDE_DIRS "include"
|
INCLUDE_DIRS "include"
|
||||||
REQUIRES dali_cpp esp_driver_uart freertos log lwip
|
REQUIRES dali_cpp esp_driver_gpio esp_driver_uart esp_hw_support esp_netif freertos log lwip knx mbedtls
|
||||||
)
|
)
|
||||||
|
|
||||||
set_property(TARGET ${COMPONENT_LIB} PROPERTY CXX_STANDARD 17)
|
set_property(TARGET ${COMPONENT_LIB} PROPERTY CXX_STANDARD 17)
|
||||||
@@ -0,0 +1,140 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "esp_idf_platform.h"
|
||||||
|
#include "ets_memory_loader.h"
|
||||||
|
|
||||||
|
#include "knx/bau07B0.h"
|
||||||
|
#include "knx/cemi_frame.h"
|
||||||
|
|
||||||
|
#include <cstddef>
|
||||||
|
#include <cstdint>
|
||||||
|
#include <functional>
|
||||||
|
#include <memory>
|
||||||
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
class GroupObject;
|
||||||
|
|
||||||
|
namespace gateway::openknx {
|
||||||
|
|
||||||
|
class TpuartUartInterface;
|
||||||
|
|
||||||
|
class EtsDeviceRuntime {
|
||||||
|
public:
|
||||||
|
using CemiFrameSender = std::function<void(const uint8_t* data, size_t len)>;
|
||||||
|
using CemiFrameReceiver = std::function<bool(const uint8_t* data, size_t len)>;
|
||||||
|
using TpAckHandler = std::function<TPAckType(uint16_t destination, bool is_group_address)>;
|
||||||
|
using GroupWriteHandler = std::function<void(uint16_t group_address, const uint8_t* data,
|
||||||
|
size_t len)>;
|
||||||
|
using GroupObjectWriteHandler = std::function<void(uint16_t group_object_number,
|
||||||
|
const uint8_t* data, size_t len)>;
|
||||||
|
using FunctionPropertyHandler = std::function<bool(uint8_t object_index, uint8_t property_id,
|
||||||
|
const uint8_t* data, size_t len,
|
||||||
|
std::vector<uint8_t>* response)>;
|
||||||
|
using FunctionPropertyExtHandler = std::function<bool(uint16_t object_type,
|
||||||
|
uint8_t object_instance,
|
||||||
|
uint8_t property_id,
|
||||||
|
const uint8_t* data, size_t len,
|
||||||
|
std::vector<uint8_t>* response)>;
|
||||||
|
|
||||||
|
EtsDeviceRuntime(std::string nvs_namespace,
|
||||||
|
uint16_t fallback_individual_address,
|
||||||
|
uint16_t tunnel_client_address = 0,
|
||||||
|
std::unique_ptr<TpuartUartInterface> tp_uart_interface = nullptr);
|
||||||
|
~EtsDeviceRuntime();
|
||||||
|
|
||||||
|
uint16_t individualAddress() const;
|
||||||
|
uint16_t tunnelClientAddress() const;
|
||||||
|
bool configured() const;
|
||||||
|
bool programmingMode() const;
|
||||||
|
void setProgrammingMode(bool enabled);
|
||||||
|
void toggleProgrammingMode();
|
||||||
|
EtsMemorySnapshot snapshot() const;
|
||||||
|
uint8_t paramByte(uint32_t addr) const;
|
||||||
|
bool paramBit(uint32_t addr, uint8_t shift) const;
|
||||||
|
|
||||||
|
// Accessors for OpenKNX integration (DIB construction, IP parameter object).
|
||||||
|
DeviceObject& deviceObject();
|
||||||
|
Platform& platform();
|
||||||
|
|
||||||
|
void setFunctionPropertyHandlers(FunctionPropertyHandler command_handler,
|
||||||
|
FunctionPropertyHandler state_handler);
|
||||||
|
void setFunctionPropertyExtHandlers(FunctionPropertyExtHandler command_handler,
|
||||||
|
FunctionPropertyExtHandler state_handler);
|
||||||
|
void setGroupWriteHandler(GroupWriteHandler handler);
|
||||||
|
void setGroupObjectWriteHandler(GroupObjectWriteHandler handler);
|
||||||
|
void setBusFrameSender(CemiFrameSender sender);
|
||||||
|
void setTpFrameReceiver(CemiFrameReceiver receiver);
|
||||||
|
void setTpAckHandler(TpAckHandler handler);
|
||||||
|
void setNetworkInterface(esp_netif_t* netif);
|
||||||
|
bool hasTpUart() const;
|
||||||
|
bool enableTpUart(bool enabled = true);
|
||||||
|
bool tpUartOnline() const;
|
||||||
|
bool transmitTpFrame(const uint8_t* data, size_t len);
|
||||||
|
|
||||||
|
bool handleTunnelFrame(const uint8_t* data, size_t len, CemiFrameSender sender);
|
||||||
|
bool handleLocalBroadcastManagementFrame(const uint8_t* data, size_t len,
|
||||||
|
CemiFrameSender sender);
|
||||||
|
bool handleBusFrame(const uint8_t* data, size_t len);
|
||||||
|
bool emitGroupValue(uint16_t group_object_number, const uint8_t* data, size_t len,
|
||||||
|
CemiFrameSender sender);
|
||||||
|
void loop();
|
||||||
|
|
||||||
|
private:
|
||||||
|
static bool HandleOutboundCemiFrame(CemiFrame& frame, void* context);
|
||||||
|
static void EmitTunnelFrame(CemiFrame& frame, void* context);
|
||||||
|
static void HandleSecureGroupWrite(uint16_t group_address, const uint8_t* data,
|
||||||
|
uint8_t data_length, void* context);
|
||||||
|
static void HandleGroupObjectWrite(GroupObject& ko);
|
||||||
|
static bool HandleFunctionPropertyCommand(uint8_t object_index, uint8_t property_id,
|
||||||
|
uint8_t length, uint8_t* data,
|
||||||
|
uint8_t* result_data, uint8_t& result_length);
|
||||||
|
static bool HandleFunctionPropertyState(uint8_t object_index, uint8_t property_id,
|
||||||
|
uint8_t length, uint8_t* data,
|
||||||
|
uint8_t* result_data, uint8_t& result_length);
|
||||||
|
static bool HandleFunctionPropertyExtCommand(uint16_t object_type,
|
||||||
|
uint8_t object_instance,
|
||||||
|
uint8_t property_id,
|
||||||
|
uint8_t length, uint8_t* data,
|
||||||
|
uint8_t* result_data,
|
||||||
|
uint8_t& result_length);
|
||||||
|
static bool HandleFunctionPropertyExtState(uint16_t object_type,
|
||||||
|
uint8_t object_instance,
|
||||||
|
uint8_t property_id,
|
||||||
|
uint8_t length, uint8_t* data,
|
||||||
|
uint8_t* result_data,
|
||||||
|
uint8_t& result_length);
|
||||||
|
static uint16_t DefaultTunnelClientAddress(uint16_t individual_address);
|
||||||
|
static bool DispatchFunctionProperty(FunctionPropertyHandler* handler, uint8_t object_index,
|
||||||
|
uint8_t property_id, uint8_t length, uint8_t* data,
|
||||||
|
uint8_t* result_data, uint8_t& result_length);
|
||||||
|
static bool DispatchFunctionPropertyExt(FunctionPropertyExtHandler* handler,
|
||||||
|
uint16_t object_type,
|
||||||
|
uint8_t object_instance,
|
||||||
|
uint8_t property_id,
|
||||||
|
uint8_t length, uint8_t* data,
|
||||||
|
uint8_t* result_data,
|
||||||
|
uint8_t& result_length);
|
||||||
|
void installGroupObjectCallbacks();
|
||||||
|
bool shouldConsumeTunnelFrame(CemiFrame& frame) const;
|
||||||
|
bool shouldConsumeBusFrame(CemiFrame& frame) const;
|
||||||
|
|
||||||
|
std::string nvs_namespace_;
|
||||||
|
std::unique_ptr<TpuartUartInterface> tp_uart_interface_;
|
||||||
|
EspIdfPlatform platform_;
|
||||||
|
Bau07B0 device_;
|
||||||
|
CemiFrameSender sender_;
|
||||||
|
CemiFrameSender bus_frame_sender_;
|
||||||
|
CemiFrameReceiver tp_frame_receiver_;
|
||||||
|
TpAckHandler tp_ack_handler_;
|
||||||
|
GroupWriteHandler group_write_handler_;
|
||||||
|
GroupObjectWriteHandler group_object_write_handler_;
|
||||||
|
FunctionPropertyHandler command_handler_;
|
||||||
|
FunctionPropertyHandler state_handler_;
|
||||||
|
FunctionPropertyExtHandler command_ext_handler_;
|
||||||
|
FunctionPropertyExtHandler state_ext_handler_;
|
||||||
|
bool suppress_group_object_write_callback_{false};
|
||||||
|
uint16_t group_object_callback_count_{0};
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace gateway::openknx
|
||||||
@@ -0,0 +1,22 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <cstdint>
|
||||||
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
namespace gateway::openknx {
|
||||||
|
|
||||||
|
struct EtsAssociation {
|
||||||
|
uint16_t group_address{0};
|
||||||
|
uint16_t group_object_number{0};
|
||||||
|
};
|
||||||
|
|
||||||
|
struct EtsMemorySnapshot {
|
||||||
|
bool configured{false};
|
||||||
|
uint16_t individual_address{0};
|
||||||
|
std::vector<EtsAssociation> associations;
|
||||||
|
};
|
||||||
|
|
||||||
|
EtsMemorySnapshot LoadEtsMemorySnapshot(const std::string& nvs_namespace);
|
||||||
|
|
||||||
|
} // namespace gateway::openknx
|
||||||
@@ -3,24 +3,39 @@
|
|||||||
#include "bridge.hpp"
|
#include "bridge.hpp"
|
||||||
#include "model_value.hpp"
|
#include "model_value.hpp"
|
||||||
|
|
||||||
|
#include "knx/ip_parameter_object.h"
|
||||||
|
|
||||||
#include "esp_err.h"
|
#include "esp_err.h"
|
||||||
#include "freertos/FreeRTOS.h"
|
#include "freertos/FreeRTOS.h"
|
||||||
|
#include "freertos/semphr.h"
|
||||||
#include "freertos/task.h"
|
#include "freertos/task.h"
|
||||||
#include "lwip/sockets.h"
|
#include "lwip/sockets.h"
|
||||||
|
|
||||||
#include <atomic>
|
#include <atomic>
|
||||||
|
#include <array>
|
||||||
#include <cstddef>
|
#include <cstddef>
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
#include <functional>
|
#include <functional>
|
||||||
|
#include <map>
|
||||||
|
#include <memory>
|
||||||
#include <optional>
|
#include <optional>
|
||||||
|
#include <set>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
namespace gateway {
|
namespace gateway {
|
||||||
|
|
||||||
|
namespace openknx {
|
||||||
|
class EtsDeviceRuntime;
|
||||||
|
class OamRouterRuntime;
|
||||||
|
class TpuartUartInterface;
|
||||||
|
}
|
||||||
|
|
||||||
constexpr uint16_t kGatewayKnxDefaultUdpPort = 3671;
|
constexpr uint16_t kGatewayKnxDefaultUdpPort = 3671;
|
||||||
constexpr const char* kGatewayKnxDefaultMulticastAddress = "224.0.23.12";
|
constexpr const char* kGatewayKnxDefaultMulticastAddress = "224.0.23.12";
|
||||||
|
constexpr const char* kGatewayKnxOamOpenKnxNamespace = "openknx_oam";
|
||||||
constexpr uint32_t kGatewayKnxDefaultTpBaudrate = 19200;
|
constexpr uint32_t kGatewayKnxDefaultTpBaudrate = 19200;
|
||||||
|
constexpr uint32_t kGatewayKnxDefaultTpStartupTimeoutMs = 2000;
|
||||||
|
|
||||||
struct GatewayKnxTpUartConfig {
|
struct GatewayKnxTpUartConfig {
|
||||||
int uart_port{1};
|
int uart_port{1};
|
||||||
@@ -29,7 +44,55 @@ struct GatewayKnxTpUartConfig {
|
|||||||
uint32_t baudrate{kGatewayKnxDefaultTpBaudrate};
|
uint32_t baudrate{kGatewayKnxDefaultTpBaudrate};
|
||||||
size_t rx_buffer_size{1024};
|
size_t rx_buffer_size{1024};
|
||||||
size_t tx_buffer_size{1024};
|
size_t tx_buffer_size{1024};
|
||||||
|
uint32_t startup_timeout_ms{kGatewayKnxDefaultTpStartupTimeoutMs};
|
||||||
uint32_t read_timeout_ms{20};
|
uint32_t read_timeout_ms{20};
|
||||||
|
bool nine_bit_mode{true};
|
||||||
|
};
|
||||||
|
|
||||||
|
enum class GatewayKnxMappingMode : uint8_t {
|
||||||
|
kFormula = 0,
|
||||||
|
kGwReg1Direct = 1,
|
||||||
|
kManual = 2,
|
||||||
|
kEtsDatabase = 3,
|
||||||
|
};
|
||||||
|
|
||||||
|
struct GatewayKnxEtsAssociation {
|
||||||
|
uint16_t group_address{0};
|
||||||
|
uint16_t group_object_number{0};
|
||||||
|
};
|
||||||
|
|
||||||
|
struct GatewayKnxCloudRemoteConfig {
|
||||||
|
bool enabled{false};
|
||||||
|
std::string mode{"mqtt"};
|
||||||
|
std::string relay_endpoint;
|
||||||
|
std::string mqtt_topic_prefix;
|
||||||
|
std::string auth_token_ref;
|
||||||
|
bool require_secure_tunnel{true};
|
||||||
|
bool udp_punch_enabled{false};
|
||||||
|
};
|
||||||
|
|
||||||
|
struct GatewayKnxOamRouterConfig {
|
||||||
|
bool enabled{false};
|
||||||
|
bool ets_database_enabled{true};
|
||||||
|
bool secure_tunnel_enabled{true};
|
||||||
|
bool secure_routing_enabled{true};
|
||||||
|
uint16_t individual_address{0xff02};
|
||||||
|
uint16_t tunnel_address_base{0xff10};
|
||||||
|
int programming_button_gpio{-1};
|
||||||
|
bool programming_button_active_low{true};
|
||||||
|
int programming_led_gpio{-1};
|
||||||
|
bool programming_led_active_high{true};
|
||||||
|
GatewayKnxCloudRemoteConfig cloud_remote;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct GatewayKnxIpSecureCredentialMaterial {
|
||||||
|
bool activated{false};
|
||||||
|
bool backbone_key_available{false};
|
||||||
|
std::array<uint8_t, 16> backbone_key{};
|
||||||
|
bool device_authentication_key_available{false};
|
||||||
|
std::array<uint8_t, 16> device_authentication_key{};
|
||||||
|
std::vector<std::array<uint8_t, 16>> tunnel_user_keys;
|
||||||
|
uint64_t routing_sequence{0};
|
||||||
};
|
};
|
||||||
|
|
||||||
struct GatewayKnxConfig {
|
struct GatewayKnxConfig {
|
||||||
@@ -37,10 +100,20 @@ struct GatewayKnxConfig {
|
|||||||
bool ip_router_enabled{false};
|
bool ip_router_enabled{false};
|
||||||
bool tunnel_enabled{true};
|
bool tunnel_enabled{true};
|
||||||
bool multicast_enabled{true};
|
bool multicast_enabled{true};
|
||||||
|
bool ets_database_enabled{true};
|
||||||
|
GatewayKnxMappingMode mapping_mode{GatewayKnxMappingMode::kFormula};
|
||||||
uint8_t main_group{0};
|
uint8_t main_group{0};
|
||||||
|
uint8_t dali_bus_id{0};
|
||||||
uint16_t udp_port{kGatewayKnxDefaultUdpPort};
|
uint16_t udp_port{kGatewayKnxDefaultUdpPort};
|
||||||
std::string multicast_address{kGatewayKnxDefaultMulticastAddress};
|
std::string multicast_address{kGatewayKnxDefaultMulticastAddress};
|
||||||
uint16_t individual_address{0x1101};
|
uint16_t ip_interface_individual_address{0xff01};
|
||||||
|
uint16_t individual_address{0xfffe};
|
||||||
|
int programming_button_gpio{-1};
|
||||||
|
bool programming_button_active_low{true};
|
||||||
|
int programming_led_gpio{-1};
|
||||||
|
bool programming_led_active_high{true};
|
||||||
|
GatewayKnxOamRouterConfig oam_router;
|
||||||
|
std::vector<GatewayKnxEtsAssociation> ets_associations;
|
||||||
GatewayKnxTpUartConfig tp_uart;
|
GatewayKnxTpUartConfig tp_uart;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -50,6 +123,8 @@ enum class GatewayKnxDaliDataType : uint8_t {
|
|||||||
kBrightness = 2,
|
kBrightness = 2,
|
||||||
kColorTemperature = 3,
|
kColorTemperature = 3,
|
||||||
kRgb = 4,
|
kRgb = 4,
|
||||||
|
kBrightnessRelative = 5,
|
||||||
|
kScene = 6,
|
||||||
};
|
};
|
||||||
|
|
||||||
enum class GatewayKnxDaliTargetKind : uint8_t {
|
enum class GatewayKnxDaliTargetKind : uint8_t {
|
||||||
@@ -69,16 +144,66 @@ struct GatewayKnxDaliBinding {
|
|||||||
uint8_t main_group{0};
|
uint8_t main_group{0};
|
||||||
uint8_t middle_group{0};
|
uint8_t middle_group{0};
|
||||||
uint8_t sub_group{0};
|
uint8_t sub_group{0};
|
||||||
|
GatewayKnxMappingMode mapping_mode{GatewayKnxMappingMode::kFormula};
|
||||||
|
int group_object_number{-1};
|
||||||
|
int channel_index{-1};
|
||||||
std::string address;
|
std::string address;
|
||||||
std::string name;
|
std::string name;
|
||||||
|
std::string object_role;
|
||||||
std::string datapoint_type;
|
std::string datapoint_type;
|
||||||
GatewayKnxDaliDataType data_type{GatewayKnxDaliDataType::kUnknown};
|
GatewayKnxDaliDataType data_type{GatewayKnxDaliDataType::kUnknown};
|
||||||
GatewayKnxDaliTarget target;
|
GatewayKnxDaliTarget target;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct GatewayKnxCommissioningBallast {
|
||||||
|
uint8_t high{0};
|
||||||
|
uint8_t middle{0};
|
||||||
|
uint8_t low{0};
|
||||||
|
uint8_t short_address{0xff};
|
||||||
|
};
|
||||||
|
|
||||||
|
struct GatewayKnxReg1ScanOptions {
|
||||||
|
bool only_new{false};
|
||||||
|
bool randomize{false};
|
||||||
|
bool delete_all{false};
|
||||||
|
bool assign{false};
|
||||||
|
};
|
||||||
|
|
||||||
|
struct GatewayKnxGatewayChannelSnapshot {
|
||||||
|
uint8_t gateway_id{0};
|
||||||
|
};
|
||||||
|
|
||||||
|
struct GatewayKnxGatewaySnapshot {
|
||||||
|
std::vector<GatewayKnxGatewayChannelSnapshot> channels;
|
||||||
|
};
|
||||||
|
|
||||||
|
enum class GatewayKnxGatewayTransactionStatus : uint8_t {
|
||||||
|
kOk = 0,
|
||||||
|
kInvalidFrame = 1,
|
||||||
|
kQueueRejected = 2,
|
||||||
|
kTimeout = 3,
|
||||||
|
kNoResponse = 4,
|
||||||
|
};
|
||||||
|
|
||||||
|
struct GatewayKnxGatewayTransactionResult {
|
||||||
|
GatewayKnxGatewayTransactionStatus status{GatewayKnxGatewayTransactionStatus::kNoResponse};
|
||||||
|
std::vector<uint8_t> frames;
|
||||||
|
};
|
||||||
|
|
||||||
|
using GatewayKnxGatewaySnapshotProvider = std::function<GatewayKnxGatewaySnapshot()>;
|
||||||
|
using GatewayKnxGatewayCommandTransactor =
|
||||||
|
std::function<GatewayKnxGatewayTransactionResult(const std::vector<uint8_t>& frame,
|
||||||
|
uint32_t timeout_ms)>;
|
||||||
|
|
||||||
std::optional<GatewayKnxConfig> GatewayKnxConfigFromValue(const DaliValue* value);
|
std::optional<GatewayKnxConfig> GatewayKnxConfigFromValue(const DaliValue* value);
|
||||||
DaliValue GatewayKnxConfigToValue(const GatewayKnxConfig& config);
|
DaliValue GatewayKnxConfigToValue(const GatewayKnxConfig& config);
|
||||||
|
std::optional<GatewayKnxOamRouterConfig> GatewayKnxOamRouterConfigFromValue(
|
||||||
|
const DaliValue* value);
|
||||||
|
DaliValue GatewayKnxOamRouterConfigToValue(const GatewayKnxOamRouterConfig& config);
|
||||||
|
bool GatewayKnxConfigUsesTpUart(const GatewayKnxConfig& config);
|
||||||
|
|
||||||
|
const char* GatewayKnxMappingModeToString(GatewayKnxMappingMode mode);
|
||||||
|
GatewayKnxMappingMode GatewayKnxMappingModeFromString(const std::string& value);
|
||||||
const char* GatewayKnxDataTypeToString(GatewayKnxDaliDataType data_type);
|
const char* GatewayKnxDataTypeToString(GatewayKnxDaliDataType data_type);
|
||||||
const char* GatewayKnxTargetKindToString(GatewayKnxDaliTargetKind kind);
|
const char* GatewayKnxTargetKindToString(GatewayKnxDaliTargetKind kind);
|
||||||
std::optional<GatewayKnxDaliDataType> GatewayKnxDaliDataTypeForMiddleGroup(
|
std::optional<GatewayKnxDaliDataType> GatewayKnxDaliDataTypeForMiddleGroup(
|
||||||
@@ -91,89 +216,374 @@ std::string GatewayKnxGroupAddressString(uint16_t group_address);
|
|||||||
class GatewayKnxBridge {
|
class GatewayKnxBridge {
|
||||||
public:
|
public:
|
||||||
explicit GatewayKnxBridge(DaliBridgeEngine& engine);
|
explicit GatewayKnxBridge(DaliBridgeEngine& engine);
|
||||||
|
~GatewayKnxBridge();
|
||||||
|
|
||||||
void setConfig(const GatewayKnxConfig& config);
|
void setConfig(const GatewayKnxConfig& config);
|
||||||
|
void setRuntimeContext(const openknx::EtsDeviceRuntime* runtime);
|
||||||
|
void setGatewayControllerCallbacks(GatewayKnxGatewaySnapshotProvider snapshot_provider,
|
||||||
|
GatewayKnxGatewayCommandTransactor command_transactor);
|
||||||
const GatewayKnxConfig& config() const;
|
const GatewayKnxConfig& config() const;
|
||||||
|
size_t etsBindingCount() const;
|
||||||
|
|
||||||
std::vector<GatewayKnxDaliBinding> describeDaliBindings() const;
|
std::vector<GatewayKnxDaliBinding> describeDaliBindings() const;
|
||||||
DaliBridgeResult handleCemiFrame(const uint8_t* data, size_t len);
|
bool matchesGroupAddress(uint16_t group_address) const;
|
||||||
DaliBridgeResult handleGroupWrite(uint16_t group_address, const uint8_t* data,
|
DaliBridgeResult handleGroupWrite(uint16_t group_address, const uint8_t* data,
|
||||||
size_t len);
|
size_t len);
|
||||||
|
DaliBridgeResult handleGroupObjectWrite(uint16_t group_object_number,
|
||||||
|
const uint8_t* data, size_t len);
|
||||||
|
bool handleFunctionPropertyCommand(uint8_t object_index, uint8_t property_id,
|
||||||
|
const uint8_t* data, size_t len,
|
||||||
|
std::vector<uint8_t>* response);
|
||||||
|
bool handleFunctionPropertyState(uint8_t object_index, uint8_t property_id,
|
||||||
|
const uint8_t* data, size_t len,
|
||||||
|
std::vector<uint8_t>* response);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
struct GatewayTransferState {
|
||||||
|
uint16_t total_length{0};
|
||||||
|
uint8_t total_chunks{0};
|
||||||
|
std::map<uint8_t, std::vector<uint8_t>> request_chunks;
|
||||||
|
std::vector<uint8_t> response_bytes;
|
||||||
|
};
|
||||||
|
|
||||||
DaliBridgeResult executeForDecodedWrite(uint16_t group_address,
|
DaliBridgeResult executeForDecodedWrite(uint16_t group_address,
|
||||||
GatewayKnxDaliDataType data_type,
|
GatewayKnxDaliDataType data_type,
|
||||||
GatewayKnxDaliTarget target,
|
GatewayKnxDaliTarget target,
|
||||||
const uint8_t* data, size_t len);
|
const uint8_t* data, size_t len);
|
||||||
|
DaliBridgeResult executeReg1SceneWrite(uint16_t group_address, const uint8_t* data,
|
||||||
|
size_t len);
|
||||||
|
DaliBridgeResult executeEtsBindings(uint16_t group_address,
|
||||||
|
const std::vector<GatewayKnxDaliBinding>& bindings,
|
||||||
|
const uint8_t* data, size_t len);
|
||||||
|
void rebuildEtsBindings();
|
||||||
|
|
||||||
|
bool handleReg1TypeCommand(const uint8_t* data, size_t len,
|
||||||
|
std::vector<uint8_t>* response);
|
||||||
|
bool handleReg1ScanCommand(const uint8_t* data, size_t len,
|
||||||
|
std::vector<uint8_t>* response);
|
||||||
|
bool handleReg1AssignCommand(const uint8_t* data, size_t len,
|
||||||
|
std::vector<uint8_t>* response);
|
||||||
|
bool handleReg1EvgWriteCommand(const uint8_t* data, size_t len,
|
||||||
|
std::vector<uint8_t>* response);
|
||||||
|
bool handleReg1EvgReadCommand(const uint8_t* data, size_t len,
|
||||||
|
std::vector<uint8_t>* response);
|
||||||
|
bool handleReg1SetSceneCommand(const uint8_t* data, size_t len,
|
||||||
|
std::vector<uint8_t>* response);
|
||||||
|
bool handleReg1GetSceneCommand(const uint8_t* data, size_t len,
|
||||||
|
std::vector<uint8_t>* response);
|
||||||
|
bool handleReg1IdentifyCommand(const uint8_t* data, size_t len,
|
||||||
|
std::vector<uint8_t>* response);
|
||||||
|
bool handleReg1ScanState(const uint8_t* data, size_t len,
|
||||||
|
std::vector<uint8_t>* response);
|
||||||
|
bool handleReg1AssignState(const uint8_t* data, size_t len,
|
||||||
|
std::vector<uint8_t>* response);
|
||||||
|
bool handleReg1FoundEvgsState(const uint8_t* data, size_t len,
|
||||||
|
std::vector<uint8_t>* response);
|
||||||
|
bool handleDalimasterDiscoveryState(const uint8_t* data, size_t len,
|
||||||
|
std::vector<uint8_t>* response);
|
||||||
|
bool handleDalimasterTransferCommand(const uint8_t* data, size_t len,
|
||||||
|
std::vector<uint8_t>* response);
|
||||||
|
bool handleDalimasterTransferState(const uint8_t* data, size_t len,
|
||||||
|
std::vector<uint8_t>* response);
|
||||||
|
bool executeDalimasterTransfer(uint16_t transaction_id, uint32_t timeout_ms,
|
||||||
|
std::vector<uint8_t>* response);
|
||||||
|
bool appendDalimasterTransferResponse(uint8_t transfer_status,
|
||||||
|
uint16_t transaction_id,
|
||||||
|
const std::vector<uint8_t>& response_bytes,
|
||||||
|
uint8_t chunk_index,
|
||||||
|
std::vector<uint8_t>* response) const;
|
||||||
|
static void CommissioningScanTaskEntry(void* arg);
|
||||||
|
void runCommissioningScanTask();
|
||||||
|
|
||||||
DaliBridgeEngine& engine_;
|
DaliBridgeEngine& engine_;
|
||||||
|
GatewayKnxGatewaySnapshotProvider gateway_snapshot_provider_;
|
||||||
|
GatewayKnxGatewayCommandTransactor gateway_command_transactor_;
|
||||||
GatewayKnxConfig config_;
|
GatewayKnxConfig config_;
|
||||||
|
const openknx::EtsDeviceRuntime* runtime_{nullptr};
|
||||||
|
std::map<uint16_t, std::vector<GatewayKnxDaliBinding>> ets_bindings_by_group_address_;
|
||||||
|
std::map<uint16_t, GatewayTransferState> gateway_transfer_states_;
|
||||||
|
SemaphoreHandle_t commissioning_lock_{nullptr};
|
||||||
|
TaskHandle_t commissioning_scan_task_{nullptr};
|
||||||
|
std::atomic_bool commissioning_scan_cancel_requested_{false};
|
||||||
|
GatewayKnxReg1ScanOptions commissioning_scan_options_;
|
||||||
|
bool commissioning_scan_done_{true};
|
||||||
|
bool commissioning_assign_done_{true};
|
||||||
|
std::vector<GatewayKnxCommissioningBallast> commissioning_found_ballasts_;
|
||||||
};
|
};
|
||||||
|
|
||||||
class GatewayKnxTpIpRouter {
|
class GatewayKnxTpIpRouter {
|
||||||
public:
|
public:
|
||||||
using CemiFrameHandler = std::function<DaliBridgeResult(const uint8_t* data, size_t len)>;
|
using GroupWriteHandler = std::function<DaliBridgeResult(uint16_t group_address,
|
||||||
|
const uint8_t* data,
|
||||||
|
size_t len)>;
|
||||||
|
using GroupObjectWriteHandler = std::function<DaliBridgeResult(uint16_t group_object_number,
|
||||||
|
const uint8_t* data,
|
||||||
|
size_t len)>;
|
||||||
|
using RoutingSequenceStoreHandler = std::function<void(uint64_t sequence)>;
|
||||||
|
using CloudCemiPublisher = std::function<void(const uint8_t* data, size_t len)>;
|
||||||
|
|
||||||
GatewayKnxTpIpRouter(GatewayKnxBridge& bridge, CemiFrameHandler handler);
|
struct CloudCemiStats {
|
||||||
|
bool enabled{false};
|
||||||
|
uint64_t uplink_frames{0};
|
||||||
|
uint64_t downlink_frames{0};
|
||||||
|
};
|
||||||
|
|
||||||
|
GatewayKnxTpIpRouter(GatewayKnxBridge& bridge,
|
||||||
|
std::string openknx_namespace = "openknx");
|
||||||
~GatewayKnxTpIpRouter();
|
~GatewayKnxTpIpRouter();
|
||||||
|
|
||||||
void setConfig(const GatewayKnxConfig& config);
|
void setConfig(const GatewayKnxConfig& config);
|
||||||
|
void setCommissioningOnly(bool enabled);
|
||||||
|
void setGroupWriteHandler(GroupWriteHandler handler);
|
||||||
|
void setGroupObjectWriteHandler(GroupObjectWriteHandler handler);
|
||||||
|
void setOamIpSecureCredentials(const GatewayKnxIpSecureCredentialMaterial& credentials);
|
||||||
|
void setOamIpSecureRoutingSequenceStoreHandler(RoutingSequenceStoreHandler handler);
|
||||||
|
void setCloudCemiPublisher(CloudCemiPublisher publisher);
|
||||||
const GatewayKnxConfig& config() const;
|
const GatewayKnxConfig& config() const;
|
||||||
|
bool injectCloudCemiFrame(const uint8_t* data, size_t len);
|
||||||
|
CloudCemiStats cloudCemiStats() const;
|
||||||
|
bool tpUartOnline() const;
|
||||||
|
bool programmingMode();
|
||||||
|
esp_err_t setProgrammingMode(bool enabled);
|
||||||
|
esp_err_t toggleProgrammingMode();
|
||||||
|
bool oamProgrammingMode();
|
||||||
|
esp_err_t setOamProgrammingMode(bool enabled);
|
||||||
|
esp_err_t toggleOamProgrammingMode();
|
||||||
|
|
||||||
esp_err_t start(uint32_t task_stack_size, UBaseType_t task_priority);
|
esp_err_t start(uint32_t task_stack_size, UBaseType_t task_priority);
|
||||||
esp_err_t stop();
|
esp_err_t stop();
|
||||||
bool started() const;
|
bool started() const;
|
||||||
const std::string& lastError() const;
|
const std::string& lastError() const;
|
||||||
|
bool publishDaliStatus(const GatewayKnxDaliTarget& target, uint8_t actual_level);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
bool handleFunctionPropertyExtCommand(uint16_t object_type,
|
||||||
|
uint8_t object_instance,
|
||||||
|
uint8_t property_id,
|
||||||
|
const uint8_t* data, size_t len,
|
||||||
|
std::vector<uint8_t>* response);
|
||||||
|
bool handleFunctionPropertyExtState(uint16_t object_type,
|
||||||
|
uint8_t object_instance,
|
||||||
|
uint8_t property_id,
|
||||||
|
const uint8_t* data, size_t len,
|
||||||
|
std::vector<uint8_t>* response);
|
||||||
|
|
||||||
|
static constexpr size_t kMaxTunnelClients = 16;
|
||||||
|
static constexpr size_t kMaxTcpClients = 4;
|
||||||
|
|
||||||
|
struct TcpClient {
|
||||||
|
int sock{-1};
|
||||||
|
::sockaddr_in remote{};
|
||||||
|
std::vector<uint8_t> rx_buffer;
|
||||||
|
TickType_t last_activity_tick{0};
|
||||||
|
};
|
||||||
|
|
||||||
|
struct TunnelClient {
|
||||||
|
bool connected{false};
|
||||||
|
uint8_t channel_id{0};
|
||||||
|
uint8_t connection_type{0};
|
||||||
|
uint8_t received_sequence{255};
|
||||||
|
uint8_t send_sequence{0};
|
||||||
|
uint8_t last_tunnel_confirmation_sequence{0};
|
||||||
|
uint16_t individual_address{0};
|
||||||
|
int tcp_sock{-1};
|
||||||
|
TickType_t last_activity_tick{0};
|
||||||
|
::sockaddr_in control_remote{};
|
||||||
|
::sockaddr_in data_remote{};
|
||||||
|
std::vector<uint8_t> last_received_cemi;
|
||||||
|
std::vector<uint8_t> last_tunnel_confirmation_packet;
|
||||||
|
std::vector<uint8_t> last_sent_cemi;
|
||||||
|
uint16_t secure_session_id{0};
|
||||||
|
bool oam_router_persona{false};
|
||||||
|
TickType_t last_sent_cemi_tick{0};
|
||||||
|
};
|
||||||
|
|
||||||
|
struct SecureSession {
|
||||||
|
bool active{false};
|
||||||
|
bool authenticated{false};
|
||||||
|
uint16_t session_id{0};
|
||||||
|
int tcp_sock{-1};
|
||||||
|
::sockaddr_in remote{};
|
||||||
|
std::array<uint8_t, 32> client_public_key{};
|
||||||
|
std::array<uint8_t, 32> server_public_key{};
|
||||||
|
std::array<uint8_t, 32> shared_secret{};
|
||||||
|
std::array<uint8_t, 16> session_key{};
|
||||||
|
uint64_t send_sequence{0};
|
||||||
|
uint64_t receive_sequence{0};
|
||||||
|
uint8_t user_id{0};
|
||||||
|
TickType_t last_activity_tick{0};
|
||||||
|
};
|
||||||
|
|
||||||
static void TaskEntry(void* arg);
|
static void TaskEntry(void* arg);
|
||||||
|
|
||||||
|
esp_err_t initializeRuntime();
|
||||||
void taskLoop();
|
void taskLoop();
|
||||||
void finishTask();
|
void finishTask();
|
||||||
void closeSockets();
|
void closeSockets();
|
||||||
bool configureSocket();
|
bool configureSocket();
|
||||||
|
void handleTcpAccept();
|
||||||
|
void handleTcpClient(TcpClient& client);
|
||||||
|
void closeTcpClient(TcpClient& client);
|
||||||
|
void closeSecureSessionsForTcp(int sock);
|
||||||
|
std::unique_ptr<openknx::TpuartUartInterface> createOpenKnxTpUartInterface();
|
||||||
bool configureTpUart();
|
bool configureTpUart();
|
||||||
bool initializeTpUart();
|
bool configureProgrammingGpio();
|
||||||
|
void refreshNetworkInterfaces(bool force_log = false);
|
||||||
void handleUdpDatagram(const uint8_t* data, size_t len, const ::sockaddr_in& remote);
|
void handleUdpDatagram(const uint8_t* data, size_t len, const ::sockaddr_in& remote);
|
||||||
void handleRoutingIndication(const uint8_t* body, size_t len);
|
void handleSearchRequest(uint16_t service, const uint8_t* packet_data, size_t len,
|
||||||
void handleTunnellingRequest(const uint8_t* body, size_t len, const ::sockaddr_in& remote);
|
const ::sockaddr_in& remote);
|
||||||
void handleConnectRequest(const uint8_t* body, size_t len, const ::sockaddr_in& remote);
|
void handleDescriptionRequest(const uint8_t* packet_data, size_t len,
|
||||||
void handleConnectionStateRequest(const uint8_t* body, size_t len,
|
const ::sockaddr_in& remote);
|
||||||
|
void handleRoutingIndication(const uint8_t* packet_data, size_t len);
|
||||||
|
void handleTunnellingRequest(const uint8_t* packet_data, size_t len, const ::sockaddr_in& remote);
|
||||||
|
void handleDeviceConfigurationRequest(const uint8_t* packet_data, size_t len,
|
||||||
|
const ::sockaddr_in& remote);
|
||||||
|
void handleConnectRequest(const uint8_t* packet_data, size_t len, const ::sockaddr_in& remote);
|
||||||
|
void handleConnectionStateRequest(const uint8_t* packet_data, size_t len,
|
||||||
const ::sockaddr_in& remote);
|
const ::sockaddr_in& remote);
|
||||||
void handleDisconnectRequest(const uint8_t* body, size_t len, const ::sockaddr_in& remote);
|
void handleDisconnectRequest(const uint8_t* packet_data, size_t len, const ::sockaddr_in& remote);
|
||||||
|
void handleSecureService(uint16_t service, const uint8_t* body, size_t len,
|
||||||
|
const ::sockaddr_in& remote);
|
||||||
|
void handleSecureSessionRequest(const uint8_t* body, size_t len,
|
||||||
|
const ::sockaddr_in& remote);
|
||||||
|
void handleSecureWrapper(const uint8_t* body, size_t len,
|
||||||
|
const ::sockaddr_in& remote);
|
||||||
|
void handleSecureGroupSync(const uint8_t* body, size_t len,
|
||||||
|
const ::sockaddr_in& remote);
|
||||||
void sendTunnellingAck(uint8_t channel_id, uint8_t sequence, uint8_t status,
|
void sendTunnellingAck(uint8_t channel_id, uint8_t sequence, uint8_t status,
|
||||||
const ::sockaddr_in& remote);
|
const ::sockaddr_in& remote);
|
||||||
|
void sendDeviceConfigurationAck(uint8_t channel_id, uint8_t sequence, uint8_t status,
|
||||||
|
const ::sockaddr_in& remote);
|
||||||
|
void sendConnectionHeaderAck(uint16_t service, uint8_t channel_id, uint8_t sequence,
|
||||||
|
uint8_t status, const ::sockaddr_in& remote);
|
||||||
|
void sendSecureSessionStatus(uint8_t status, const ::sockaddr_in& remote);
|
||||||
void sendTunnelIndication(const uint8_t* data, size_t len);
|
void sendTunnelIndication(const uint8_t* data, size_t len);
|
||||||
|
void sendTunnelIndicationToClient(TunnelClient& client, const uint8_t* data, size_t len);
|
||||||
|
bool sendCemiFrameToClient(TunnelClient& client, uint16_t service,
|
||||||
|
const uint8_t* data, size_t len);
|
||||||
void sendConnectionStateResponse(uint8_t channel_id, uint8_t status,
|
void sendConnectionStateResponse(uint8_t channel_id, uint8_t status,
|
||||||
const ::sockaddr_in& remote);
|
const ::sockaddr_in& remote);
|
||||||
void sendDisconnectResponse(uint8_t channel_id, uint8_t status,
|
void sendDisconnectResponse(uint8_t channel_id, uint8_t status,
|
||||||
const ::sockaddr_in& remote);
|
const ::sockaddr_in& remote);
|
||||||
void sendConnectResponse(uint8_t channel_id, uint8_t status,
|
void sendConnectResponse(uint8_t channel_id, uint8_t status,
|
||||||
const ::sockaddr_in& remote);
|
const ::sockaddr_in& remote, uint8_t connection_type,
|
||||||
|
uint16_t tunnel_address);
|
||||||
void sendRoutingIndication(const uint8_t* data, size_t len);
|
void sendRoutingIndication(const uint8_t* data, size_t len);
|
||||||
void pollTpUart();
|
bool sendPacket(const std::vector<uint8_t>& packet, const ::sockaddr_in& remote);
|
||||||
void handleTpUartControlByte(uint8_t byte);
|
bool sendPacketToTunnelClient(const TunnelClient& client,
|
||||||
void handleTpTelegram(const uint8_t* data, size_t len);
|
const std::vector<uint8_t>& packet);
|
||||||
void forwardCemiToTp(const uint8_t* data, size_t len);
|
bool currentTransportAllowsTcpHpai() const;
|
||||||
|
std::optional<std::array<uint8_t, 8>> localHpaiForRemote(const ::sockaddr_in& remote,
|
||||||
|
bool tcp = false) const;
|
||||||
|
|
||||||
|
// --- OpenKNX-backed DIB construction (uses KnxIpSearchResponse / KnxIpDescriptionResponse) ---
|
||||||
|
std::vector<uint8_t> buildOpenKnxSearchResponse(const ::sockaddr_in& remote) const;
|
||||||
|
std::vector<uint8_t> buildOpenKnxDescriptionResponse(const ::sockaddr_in& remote) const;
|
||||||
|
|
||||||
|
// --- Hand-rolled DIB builders (fallback when OpenKNX is unavailable) ---
|
||||||
|
std::vector<uint8_t> buildDeviceInfoDib(const ::sockaddr_in& remote) const;
|
||||||
|
std::vector<uint8_t> buildSupportedServiceDib() const;
|
||||||
|
std::vector<uint8_t> buildExtendedDeviceInfoDib() const;
|
||||||
|
std::vector<uint8_t> buildIpConfigDib(const ::sockaddr_in& remote, bool current) const;
|
||||||
|
std::vector<uint8_t> buildKnxAddressesDib() const;
|
||||||
|
std::vector<uint8_t> buildTunnelingInfoDib() const;
|
||||||
|
TunnelClient* findTunnelClient(uint8_t channel_id);
|
||||||
|
const TunnelClient* findTunnelClient(uint8_t channel_id) const;
|
||||||
|
TunnelClient* allocateTunnelClient(const ::sockaddr_in& control_remote,
|
||||||
|
const ::sockaddr_in& data_remote,
|
||||||
|
uint8_t connection_type);
|
||||||
|
void resetTunnelClient(TunnelClient& client);
|
||||||
|
SecureSession* findSecureSession(uint16_t session_id, const ::sockaddr_in& remote);
|
||||||
|
const SecureSession* findSecureSession(uint16_t session_id,
|
||||||
|
const ::sockaddr_in& remote) const;
|
||||||
|
SecureSession* allocateSecureSession(const ::sockaddr_in& remote);
|
||||||
|
SecureSession* activeSecureSession();
|
||||||
|
bool wrapSecurePacket(SecureSession& session, const std::vector<uint8_t>& inner,
|
||||||
|
std::vector<uint8_t>* wrapped);
|
||||||
|
bool wrapSecureRoutingPacket(const std::vector<uint8_t>& inner,
|
||||||
|
std::vector<uint8_t>* wrapped);
|
||||||
|
bool decryptSecureWrapper(SecureSession& session, const uint8_t* body, size_t len,
|
||||||
|
std::vector<uint8_t>* inner);
|
||||||
|
bool decryptSecureRoutingWrapper(const uint8_t* body, size_t len,
|
||||||
|
std::vector<uint8_t>* inner);
|
||||||
|
bool verifySecureSessionAuth(SecureSession& session, const uint8_t* packet,
|
||||||
|
size_t len, uint8_t* status);
|
||||||
|
bool secureCredentialsReady() const;
|
||||||
|
uint8_t nextTunnelChannelId() const;
|
||||||
|
uint16_t effectiveTunnelAddressForSlot(size_t slot) const;
|
||||||
|
void pruneStaleTunnelClients();
|
||||||
|
bool handleOpenKnxTunnelFrame(const uint8_t* data, size_t len,
|
||||||
|
TunnelClient* response_client, uint16_t response_service,
|
||||||
|
const uint8_t* suppress_routing_echo = nullptr,
|
||||||
|
size_t suppress_routing_echo_len = 0);
|
||||||
|
bool handleOamRouterTunnelFrame(const uint8_t* data, size_t len,
|
||||||
|
TunnelClient* response_client, uint16_t response_service,
|
||||||
|
const uint8_t* suppress_routing_echo = nullptr,
|
||||||
|
size_t suppress_routing_echo_len = 0);
|
||||||
|
bool handleOpenKnxBusFrame(const uint8_t* data, size_t len);
|
||||||
|
bool transmitOpenKnxTpFrame(const uint8_t* data, size_t len);
|
||||||
|
bool transmitOpenKnxTpFrameLocked(const uint8_t* data, size_t len);
|
||||||
|
bool handleOpenKnxTpIngressFrame(const uint8_t* data, size_t len);
|
||||||
|
void publishCloudCemiFrame(const uint8_t* data, size_t len);
|
||||||
|
void selectOpenKnxNetworkInterface(const ::sockaddr_in& remote);
|
||||||
|
bool routeOpenKnxGroupWrite(const uint8_t* data, size_t len, const char* context);
|
||||||
|
bool emitOpenKnxGroupValue(uint16_t group_object_number, const uint8_t* data, size_t len);
|
||||||
|
bool shouldRouteDaliApplicationFrames() const;
|
||||||
|
uint8_t advertisedMedium() const;
|
||||||
|
const char* ipInterfaceName() const;
|
||||||
|
const char* ipInterfaceFriendlyName() const;
|
||||||
|
void syncOpenKnxConfigFromDevice();
|
||||||
|
uint16_t effectiveIpInterfaceIndividualAddress() const;
|
||||||
|
uint16_t effectiveKnxDeviceIndividualAddress() const;
|
||||||
|
uint16_t effectiveTunnelAddress() const;
|
||||||
|
void pollProgrammingButton();
|
||||||
|
void updateProgrammingLed();
|
||||||
|
void setProgrammingLed(bool on);
|
||||||
|
void setOamProgrammingLed(bool on);
|
||||||
|
|
||||||
GatewayKnxBridge& bridge_;
|
GatewayKnxBridge& bridge_;
|
||||||
CemiFrameHandler handler_;
|
GroupWriteHandler group_write_handler_;
|
||||||
|
GroupObjectWriteHandler group_object_write_handler_;
|
||||||
|
RoutingSequenceStoreHandler routing_sequence_store_handler_;
|
||||||
|
CloudCemiPublisher cloud_cemi_publisher_;
|
||||||
|
std::string openknx_namespace_;
|
||||||
GatewayKnxConfig config_;
|
GatewayKnxConfig config_;
|
||||||
|
std::unique_ptr<openknx::EtsDeviceRuntime> ets_device_;
|
||||||
|
std::unique_ptr<openknx::OamRouterRuntime> oam_router_;
|
||||||
TaskHandle_t task_handle_{nullptr};
|
TaskHandle_t task_handle_{nullptr};
|
||||||
|
SemaphoreHandle_t openknx_lock_{nullptr};
|
||||||
|
SemaphoreHandle_t startup_semaphore_{nullptr};
|
||||||
|
esp_err_t startup_result_{ESP_OK};
|
||||||
std::atomic_bool stop_requested_{false};
|
std::atomic_bool stop_requested_{false};
|
||||||
std::atomic_bool started_{false};
|
std::atomic_bool started_{false};
|
||||||
int udp_sock_{-1};
|
int udp_sock_{-1};
|
||||||
|
int tcp_sock_{-1};
|
||||||
|
int active_tcp_sock_{-1};
|
||||||
int tp_uart_port_{-1};
|
int tp_uart_port_{-1};
|
||||||
uint8_t tunnel_channel_id_{1};
|
int tp_uart_tx_pin_{-1};
|
||||||
uint8_t expected_tunnel_sequence_{0};
|
int tp_uart_rx_pin_{-1};
|
||||||
uint8_t tunnel_send_sequence_{0};
|
std::vector<uint32_t> multicast_joined_interfaces_;
|
||||||
bool tunnel_connected_{false};
|
TickType_t network_refresh_tick_{0};
|
||||||
::sockaddr_in tunnel_remote_{};
|
std::array<TcpClient, kMaxTcpClients> tcp_clients_{};
|
||||||
std::vector<uint8_t> tp_rx_frame_;
|
std::array<TunnelClient, kMaxTunnelClients> tunnel_clients_{};
|
||||||
std::vector<uint8_t> tp_last_sent_telegram_;
|
std::array<SecureSession, kMaxTcpClients> secure_sessions_{};
|
||||||
TickType_t tp_uart_last_byte_tick_{0};
|
std::unique_ptr<IpParameterObject> knx_ip_parameters_;
|
||||||
bool tp_uart_extended_frame_{false};
|
uint8_t last_tunnel_channel_id_{0};
|
||||||
|
uint16_t last_secure_session_id_{0};
|
||||||
|
uint16_t active_secure_session_id_{0};
|
||||||
|
GatewayKnxIpSecureCredentialMaterial oam_ip_secure_credentials_{};
|
||||||
bool tp_uart_online_{false};
|
bool tp_uart_online_{false};
|
||||||
|
bool commissioning_only_{false};
|
||||||
|
std::atomic_bool openknx_configured_{false};
|
||||||
|
std::atomic<uint64_t> cloud_cemi_uplink_frames_{0};
|
||||||
|
std::atomic<uint64_t> cloud_cemi_downlink_frames_{0};
|
||||||
|
bool programming_button_last_pressed_{false};
|
||||||
|
bool programming_led_state_{false};
|
||||||
|
TickType_t programming_button_last_toggle_tick_{0};
|
||||||
|
bool oam_programming_mode_{false};
|
||||||
|
bool oam_programming_button_last_pressed_{false};
|
||||||
|
bool oam_programming_led_state_{false};
|
||||||
|
TickType_t oam_programming_button_last_toggle_tick_{0};
|
||||||
std::string last_error_;
|
std::string last_error_;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,153 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
// Internal helpers and product identity shared by gateway_knx component sources.
|
||||||
|
|
||||||
|
#include "driver/uart.h"
|
||||||
|
#include "freertos/FreeRTOS.h"
|
||||||
|
#include "freertos/semphr.h"
|
||||||
|
#include "sdkconfig.h"
|
||||||
|
#include "soc/uart_periph.h"
|
||||||
|
|
||||||
|
#include <cstdint>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
namespace gateway {
|
||||||
|
namespace knx_internal {
|
||||||
|
|
||||||
|
constexpr const char* kTag = "gateway_knx";
|
||||||
|
|
||||||
|
#ifndef CONFIG_GATEWAY_KNX_OEM_MANUFACTURER_ID
|
||||||
|
#define CONFIG_GATEWAY_KNX_OEM_MANUFACTURER_ID 0x00A4
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef CONFIG_GATEWAY_KNX_OEM_APPLICATION_NUMBER
|
||||||
|
#define CONFIG_GATEWAY_KNX_OEM_APPLICATION_NUMBER 0x0001
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef CONFIG_GATEWAY_KNX_OEM_APPLICATION_VERSION
|
||||||
|
#define CONFIG_GATEWAY_KNX_OEM_APPLICATION_VERSION 0x08
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef CONFIG_GATEWAY_KNX_OEM_HARDWARE_ID
|
||||||
|
#define CONFIG_GATEWAY_KNX_OEM_HARDWARE_ID 0xA401
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef CONFIG_GATEWAY_KNX_OAM_ROUTER_OEM_MANUFACTURER_ID
|
||||||
|
#define CONFIG_GATEWAY_KNX_OAM_ROUTER_OEM_MANUFACTURER_ID 0x00FA
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef CONFIG_GATEWAY_KNX_OAM_ROUTER_APPLICATION_NUMBER
|
||||||
|
#define CONFIG_GATEWAY_KNX_OAM_ROUTER_APPLICATION_NUMBER 0xA11F
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef CONFIG_GATEWAY_KNX_OAM_ROUTER_APPLICATION_VERSION
|
||||||
|
#define CONFIG_GATEWAY_KNX_OAM_ROUTER_APPLICATION_VERSION 0x07
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef CONFIG_GATEWAY_KNX_OAM_ROUTER_HARDWARE_ID
|
||||||
|
#define CONFIG_GATEWAY_KNX_OAM_ROUTER_HARDWARE_ID 0x0001
|
||||||
|
#endif
|
||||||
|
|
||||||
|
inline constexpr uint16_t kReg1DaliManufacturerId =
|
||||||
|
static_cast<uint16_t>(CONFIG_GATEWAY_KNX_OEM_MANUFACTURER_ID);
|
||||||
|
inline constexpr uint16_t kReg1DaliHardwareId =
|
||||||
|
static_cast<uint16_t>(CONFIG_GATEWAY_KNX_OEM_HARDWARE_ID);
|
||||||
|
inline constexpr uint16_t kReg1DaliApplicationNumber =
|
||||||
|
static_cast<uint16_t>(CONFIG_GATEWAY_KNX_OEM_APPLICATION_NUMBER);
|
||||||
|
inline constexpr uint8_t kReg1DaliApplicationVersion =
|
||||||
|
static_cast<uint8_t>(CONFIG_GATEWAY_KNX_OEM_APPLICATION_VERSION);
|
||||||
|
inline constexpr uint8_t kReg1DaliHardwareType[6] = {
|
||||||
|
0x00,
|
||||||
|
0x00,
|
||||||
|
static_cast<uint8_t>((kReg1DaliHardwareId >> 8) & 0xff),
|
||||||
|
static_cast<uint8_t>(kReg1DaliHardwareId & 0xff),
|
||||||
|
kReg1DaliApplicationVersion,
|
||||||
|
0x00};
|
||||||
|
inline constexpr uint8_t kReg1DaliOrderNumber[10] = {
|
||||||
|
'R', 'E', 'G', '1', '-', 'D', 'a', 'l', 'i', 0};
|
||||||
|
inline constexpr uint8_t kReg1DaliProgramVersion[5] = {
|
||||||
|
static_cast<uint8_t>((kReg1DaliManufacturerId >> 8) & 0xff),
|
||||||
|
static_cast<uint8_t>(kReg1DaliManufacturerId & 0xff),
|
||||||
|
static_cast<uint8_t>((kReg1DaliApplicationNumber >> 8) & 0xff),
|
||||||
|
static_cast<uint8_t>(kReg1DaliApplicationNumber & 0xff),
|
||||||
|
kReg1DaliApplicationVersion};
|
||||||
|
|
||||||
|
inline constexpr uint32_t kDaliMaxKnxInstanceCount = 16;
|
||||||
|
inline constexpr uint32_t kReg1DaliSerialMacIncrement = 0;
|
||||||
|
inline constexpr uint32_t kOamRouterSerialMacIncrement = kDaliMaxKnxInstanceCount;
|
||||||
|
inline constexpr uint16_t kOamRouterDeviceDescriptor = 0x091A;
|
||||||
|
inline constexpr uint16_t kOamRouterManufacturerId =
|
||||||
|
static_cast<uint16_t>(CONFIG_GATEWAY_KNX_OAM_ROUTER_OEM_MANUFACTURER_ID);
|
||||||
|
inline constexpr uint16_t kOamRouterLegacyHardwareId =
|
||||||
|
static_cast<uint16_t>(CONFIG_GATEWAY_KNX_OAM_ROUTER_HARDWARE_ID);
|
||||||
|
inline constexpr uint16_t kOamRouterApplicationNumber =
|
||||||
|
static_cast<uint16_t>(CONFIG_GATEWAY_KNX_OAM_ROUTER_APPLICATION_NUMBER);
|
||||||
|
inline constexpr uint8_t kOamRouterApplicationVersion =
|
||||||
|
static_cast<uint8_t>(CONFIG_GATEWAY_KNX_OAM_ROUTER_APPLICATION_VERSION);
|
||||||
|
inline constexpr uint8_t kOamRouterHardwareType[6] = {
|
||||||
|
0x00,
|
||||||
|
0x00,
|
||||||
|
static_cast<uint8_t>((kOamRouterApplicationNumber >> 8) & 0xff),
|
||||||
|
static_cast<uint8_t>(kOamRouterApplicationNumber & 0xff),
|
||||||
|
kOamRouterApplicationVersion,
|
||||||
|
0x00};
|
||||||
|
inline constexpr uint8_t kOamRouterLegacyHardwareType[6] = {
|
||||||
|
0x00,
|
||||||
|
0x00,
|
||||||
|
static_cast<uint8_t>((kOamRouterLegacyHardwareId >> 8) & 0xff),
|
||||||
|
static_cast<uint8_t>(kOamRouterLegacyHardwareId & 0xff),
|
||||||
|
kOamRouterApplicationVersion,
|
||||||
|
0x00};
|
||||||
|
inline constexpr uint8_t kOamRouterOrderNumber[10] = {
|
||||||
|
'I', 'P', '-', 'R', 'o', 'u', 't', 'e', 'r', 0};
|
||||||
|
inline constexpr uint8_t kOamRouterProgramVersion[5] = {
|
||||||
|
static_cast<uint8_t>((kOamRouterManufacturerId >> 8) & 0xff),
|
||||||
|
static_cast<uint8_t>(kOamRouterManufacturerId & 0xff),
|
||||||
|
static_cast<uint8_t>((kOamRouterApplicationNumber >> 8) & 0xff),
|
||||||
|
static_cast<uint8_t>(kOamRouterApplicationNumber & 0xff),
|
||||||
|
kOamRouterApplicationVersion};
|
||||||
|
|
||||||
|
// RAII semaphore guard.
|
||||||
|
class SemaphoreGuard {
|
||||||
|
public:
|
||||||
|
explicit SemaphoreGuard(SemaphoreHandle_t semaphore) : semaphore_(semaphore) {
|
||||||
|
if (semaphore_ != nullptr) {
|
||||||
|
xSemaphoreTake(semaphore_, portMAX_DELAY);
|
||||||
|
locked_ = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
~SemaphoreGuard() {
|
||||||
|
if (locked_) {
|
||||||
|
xSemaphoreGive(semaphore_);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
private:
|
||||||
|
SemaphoreHandle_t semaphore_{nullptr};
|
||||||
|
bool locked_{false};
|
||||||
|
};
|
||||||
|
|
||||||
|
// Resolve a UART IO pin from config or SoC defaults.
|
||||||
|
inline bool ResolveUartIoPin(uart_port_t uart_port, int configured_pin,
|
||||||
|
uint32_t pin_index, int* resolved_pin) {
|
||||||
|
if (resolved_pin == nullptr) return false;
|
||||||
|
if (configured_pin >= 0) {
|
||||||
|
*resolved_pin = configured_pin;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (uart_port < 0 || uart_port >= SOC_UART_NUM ||
|
||||||
|
pin_index >= SOC_UART_PINS_COUNT) {
|
||||||
|
*resolved_pin = UART_PIN_NO_CHANGE;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
const int default_pin =
|
||||||
|
uart_periph_signal[uart_port].pins[pin_index].default_gpio;
|
||||||
|
if (default_pin < 0) {
|
||||||
|
*resolved_pin = UART_PIN_NO_CHANGE;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
*resolved_pin = default_pin;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace knx_internal
|
||||||
|
} // namespace gateway
|
||||||
@@ -0,0 +1,38 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <cstddef>
|
||||||
|
#include <cstdint>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
namespace gateway {
|
||||||
|
|
||||||
|
enum class KnxPortKind : uint8_t {
|
||||||
|
kIpTunnel,
|
||||||
|
kIpRouting,
|
||||||
|
kTpUart,
|
||||||
|
kCloud,
|
||||||
|
kRfReserved,
|
||||||
|
};
|
||||||
|
|
||||||
|
struct KnxIngressContext {
|
||||||
|
KnxPortKind port{KnxPortKind::kIpTunnel};
|
||||||
|
bool oam_persona_hint{false};
|
||||||
|
bool broadcast_management{false};
|
||||||
|
};
|
||||||
|
|
||||||
|
class KnxResponseDeduplicator {
|
||||||
|
public:
|
||||||
|
KnxResponseDeduplicator() = default;
|
||||||
|
KnxResponseDeduplicator(const uint8_t* original, size_t len);
|
||||||
|
|
||||||
|
bool remember(const uint8_t* data, size_t len);
|
||||||
|
bool remember(const std::vector<uint8_t>& data);
|
||||||
|
size_t suppressedCount() const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::vector<uint8_t> original_;
|
||||||
|
std::vector<std::vector<uint8_t>> sent_;
|
||||||
|
size_t suppressed_count_{0};
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace gateway
|
||||||
@@ -0,0 +1,73 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "esp_idf_platform.h"
|
||||||
|
#include "ets_memory_loader.h"
|
||||||
|
|
||||||
|
#include "esp_netif.h"
|
||||||
|
#include "freertos/FreeRTOS.h"
|
||||||
|
#include "knx/cemi_frame.h"
|
||||||
|
#include "knx/device_object.h"
|
||||||
|
#include "knx/platform.h"
|
||||||
|
|
||||||
|
#include <cstddef>
|
||||||
|
#include <cstdint>
|
||||||
|
#include <functional>
|
||||||
|
#include <memory>
|
||||||
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
#if defined(ENABLE_BAU091A_PERSONA)
|
||||||
|
#include "knx/bau091A.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
namespace gateway::openknx {
|
||||||
|
|
||||||
|
class OamRouterRuntime {
|
||||||
|
public:
|
||||||
|
using CemiFrameSender = std::function<void(const uint8_t* data, size_t len)>;
|
||||||
|
|
||||||
|
OamRouterRuntime(std::string nvs_namespace,
|
||||||
|
uint16_t fallback_individual_address,
|
||||||
|
uint16_t tunnel_client_address = 0);
|
||||||
|
~OamRouterRuntime();
|
||||||
|
|
||||||
|
bool available() const;
|
||||||
|
uint16_t individualAddress() const;
|
||||||
|
uint16_t tunnelClientAddress() const;
|
||||||
|
bool configured() const;
|
||||||
|
bool programmingMode() const;
|
||||||
|
void setProgrammingMode(bool enabled);
|
||||||
|
void toggleProgrammingMode();
|
||||||
|
bool matchesSecureSyncSerial(CemiFrame& frame) const;
|
||||||
|
bool matchesRecentSecureToolAccess(CemiFrame& frame) const;
|
||||||
|
EtsMemorySnapshot snapshot() const;
|
||||||
|
|
||||||
|
DeviceObject* deviceObject();
|
||||||
|
Platform* platform();
|
||||||
|
void setNetworkInterface(esp_netif_t* netif);
|
||||||
|
void setBusFrameSender(CemiFrameSender sender);
|
||||||
|
bool handleTunnelFrame(const uint8_t* data, size_t len, CemiFrameSender sender);
|
||||||
|
bool handleLocalBroadcastManagementFrame(const uint8_t* data, size_t len,
|
||||||
|
CemiFrameSender sender);
|
||||||
|
bool handleBusFrame(const uint8_t* data, size_t len, CemiFrameSender sender);
|
||||||
|
void loop();
|
||||||
|
|
||||||
|
private:
|
||||||
|
static bool HandleOutboundCemiFrame(CemiFrame& frame, void* context);
|
||||||
|
static void EmitTunnelFrame(CemiFrame& frame, void* context);
|
||||||
|
static uint16_t DefaultTunnelClientAddress(uint16_t individual_address);
|
||||||
|
bool shouldConsumeTunnelFrame(CemiFrame& frame) const;
|
||||||
|
bool shouldConsumeBusFrame(CemiFrame& frame) const;
|
||||||
|
|
||||||
|
std::string nvs_namespace_;
|
||||||
|
CemiFrameSender sender_;
|
||||||
|
CemiFrameSender bus_frame_sender_;
|
||||||
|
mutable uint16_t recent_secure_tool_source_{0xffff};
|
||||||
|
mutable int64_t recent_secure_tool_sync_us_{0};
|
||||||
|
#if defined(ENABLE_BAU091A_PERSONA)
|
||||||
|
EspIdfPlatform platform_;
|
||||||
|
Bau091A device_;
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace gateway::openknx
|
||||||
@@ -0,0 +1,218 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<KNX xmlns="http://knx.org/xml/project/20" xmlns:op="http://github.com/OpenKNX/OpenKNXproducer">
|
||||||
|
<ManufacturerData>
|
||||||
|
<Manufacturer RefId="M-00FA">
|
||||||
|
<Languages>
|
||||||
|
<Language Identifier="en-US">
|
||||||
|
<TranslationUnit RefId="%AID%">
|
||||||
|
<TranslationElement RefId="%AID%_PT-DelayBase_EN-0"><Translation AttributeName="Text" Text="second(s)" /></TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_PT-DelayBase_EN-1"><Translation AttributeName="Text" Text="minute(s)" /></TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_PT-DelayBase_EN-2"><Translation AttributeName="Text" Text="hour(s)" /></TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_PT-DelayBase10_EN-3"><Translation AttributeName="Text" Text="1/10 second(s)" /></TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_PT-DelayBase10_EN-0"><Translation AttributeName="Text" Text="second(s)" /></TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_PT-DelayBase10_EN-1"><Translation AttributeName="Text" Text="minute(s)" /></TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_PT-DelayBase10_EN-2"><Translation AttributeName="Text" Text="hour(s)" /></TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_PT-OnOffYesNo_EN-0"><Translation AttributeName="Text" Text="No" /></TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_PT-OnOffYesNo_EN-1"><Translation AttributeName="Text" Text="Yes" /></TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_PT-OnOffYesNoInverted_EN-1"><Translation AttributeName="Text" Text="No" /></TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_PT-OnOffYesNoInverted_EN-0"><Translation AttributeName="Text" Text="Yes" /></TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_PT-ValueDpt1_EN-0"><Translation AttributeName="Text" Text="OFF (0)" /></TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_PT-ValueDpt1_EN-1"><Translation AttributeName="Text" Text="ON (1)" /></TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_PT-ValueDpt2_EN-4"><Translation AttributeName="Text" Text="not used" /></TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_PT-ValueDpt2_EN-0"><Translation AttributeName="Text" Text="normal OFF (00)" /></TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_PT-ValueDpt2_EN-1"><Translation AttributeName="Text" Text="normal ON (01)" /></TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_PT-ValueDpt2_EN-2"><Translation AttributeName="Text" Text="priority OFF (10)" /></TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_PT-ValueDpt2_EN-3"><Translation AttributeName="Text" Text="priority ON (11)" /></TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_PT-ValueDpt2Out_EN-0"><Translation AttributeName="Text" Text="normal OFF (00)" /></TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_PT-ValueDpt2Out_EN-1"><Translation AttributeName="Text" Text="normal ON (01)" /></TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_PT-ValueDpt2Out_EN-2"><Translation AttributeName="Text" Text="priority OFF (10)" /></TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_PT-ValueDpt2Out_EN-3"><Translation AttributeName="Text" Text="priority ON (11)" /></TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_PT-CombinedTimeDate_EN-1"><Translation AttributeName="Text" Text="one combined communication object" /></TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_PT-CombinedTimeDate_EN-0"><Translation AttributeName="Text" Text="two separate communication objects" /></TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_PT-SummertimeAll_EN-0"><Translation AttributeName="Text" Text="Communication object 'daylight saving time active'" /></TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_PT-SummertimeAll_EN-1"><Translation AttributeName="Text" Text="Combined date/time communication object (DPT 19)" /></TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_PT-SummertimeAll_EN-2"><Translation AttributeName="Text" Text="Internal calculation" /></TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_PT-SummertimeDE_EN-0"><Translation AttributeName="Text" Text="Communication object 'daylight saving time active'" /></TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_PT-SummertimeDE_EN-2"><Translation AttributeName="Text" Text="Internal calculation" /></TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_PT-SummertimeWorld_EN-0"><Translation AttributeName="Text" Text="Communication object 'daylight saving time active'" /></TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_PT-SummertimeWorld_EN-1"><Translation AttributeName="Text" Text="Combined date/time communication object (DPT 19)" /></TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_PT-SummertimeKO_EN-0"><Translation AttributeName="Text" Text="Communication object 'daylight saving time active'" /></TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_PT-Timezone_EN-1"><Translation AttributeName="Text" Text="Amsterdam, Berlin, Bern, Rome, Vienna (+1 hour)" /></TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_PT-Timezone_EN-31"><Translation AttributeName="Text" Text="Custom" /></TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_PT-Timezone_EN-27"><Translation AttributeName="Text" Text="UTC -11 hours" /></TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_PT-Timezone_EN-26"><Translation AttributeName="Text" Text="UTC -10 hours" /></TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_PT-Timezone_EN-25"><Translation AttributeName="Text" Text="UTC -9 hours" /></TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_PT-Timezone_EN-24"><Translation AttributeName="Text" Text="UTC -8 hours" /></TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_PT-Timezone_EN-23"><Translation AttributeName="Text" Text="UTC -7 hours" /></TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_PT-Timezone_EN-22"><Translation AttributeName="Text" Text="UTC -6 hours" /></TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_PT-Timezone_EN-21"><Translation AttributeName="Text" Text="UTC -5 hours" /></TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_PT-Timezone_EN-20"><Translation AttributeName="Text" Text="UTC -4 hours" /></TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_PT-Timezone_EN-19"><Translation AttributeName="Text" Text="UTC -3 hours" /></TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_PT-Timezone_EN-18"><Translation AttributeName="Text" Text="UTC -2 hours" /></TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_PT-Timezone_EN-17"><Translation AttributeName="Text" Text="UTC -1 hour" /></TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_PT-Timezone_EN-0"><Translation AttributeName="Text" Text="UTC +0 hours" /></TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_PT-Timezone_EN-28"><Translation AttributeName="Text" Text="UTC +1 hour" /></TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_PT-Timezone_EN-2"><Translation AttributeName="Text" Text="UTC +2 hours" /></TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_PT-Timezone_EN-3"><Translation AttributeName="Text" Text="UTC +3 hours" /></TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_PT-Timezone_EN-4"><Translation AttributeName="Text" Text="UTC +4 hours" /></TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_PT-Timezone_EN-5"><Translation AttributeName="Text" Text="UTC +5 hours" /></TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_PT-Timezone_EN-6"><Translation AttributeName="Text" Text="UTC +6 hours" /></TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_PT-Timezone_EN-7"><Translation AttributeName="Text" Text="UTC +7 hours" /></TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_PT-Timezone_EN-8"><Translation AttributeName="Text" Text="UTC +8 hours" /></TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_PT-Timezone_EN-9"><Translation AttributeName="Text" Text="UTC +9 hours" /></TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_PT-Timezone_EN-10"><Translation AttributeName="Text" Text="UTC +10 hours" /></TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_PT-Timezone_EN-11"><Translation AttributeName="Text" Text="UTC +11 hours" /></TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_PT-Timezone_EN-12"><Translation AttributeName="Text" Text="UTC +12 hours" /></TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_PT-PeriodicSave_EN-0"><Translation AttributeName="Text" Text="Disabled" /></TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_PT-PeriodicSave_EN-1"><Translation AttributeName="Text" Text="Every hour" /></TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_PT-PeriodicSave_EN-2"><Translation AttributeName="Text" Text="Every 2 hours" /></TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_PT-PeriodicSave_EN-4"><Translation AttributeName="Text" Text="Every 4 hours" /></TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_PT-PeriodicSave_EN-6"><Translation AttributeName="Text" Text="Every 6 hours" /></TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_PT-PeriodicSave_EN-24"><Translation AttributeName="Text" Text="Daily" /></TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_PT-PeriodicSave_EN-168"><Translation AttributeName="Text" Text="Weekly" /></TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_PT-ManualSave_EN-0"><Translation AttributeName="Text" Text="Disabled" /></TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_PT-ManualSave_EN-1"><Translation AttributeName="Text" Text="Active with 5 min. write protection" /></TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_PT-ManualSave_EN-2"><Translation AttributeName="Text" Text="Active with 15 min. write protection" /></TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_PT-ManualSave_EN-3"><Translation AttributeName="Text" Text="Active with 60 min. write protection" /></TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_PT-SLEDFunc_EN-0"><Translation AttributeName="Text" Text="Disabled" /></TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_PT-SLEDFunc_EN-1"><Translation AttributeName="Text" Text="Prog LED" /></TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_PT-SLEDFunc_EN-2"><Translation AttributeName="Text" Text="Device status" /></TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_PT-SLEDFunc_EN-3"><Translation AttributeName="Text" Text="Bus status" /></TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_PT-SLEDFunc_EN-4"><Translation AttributeName="Text" Text="Time status" /></TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_PT-SLEDFunc_EN-10"><Translation AttributeName="Text" Text="Network status" /></TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_PT-CustomHostname_EN-0"><Translation AttributeName="Text" Text="Default" /></TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_PT-CustomHostname_EN-1"><Translation AttributeName="Text" Text="Custom" /></TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_PT-OTAUpdate_EN-0"><Translation AttributeName="Text" Text="In programming mode" /></TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_PT-OTAUpdate_EN-1"><Translation AttributeName="Text" Text="Always active" /></TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_PT-OTAUpdate_EN-2"><Translation AttributeName="Text" Text="Disabled" /></TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_PT-LanMode_EN-0"><Translation AttributeName="Text" Text="Automatic" /></TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_PT-LanMode_EN-3"><Translation AttributeName="Text" Text="10 MBit/s (power saving)" /></TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_PT-LanMode_EN-1"><Translation AttributeName="Text" Text="100 MBit/s" /></TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_UP-1000002"><Translation AttributeName="Text" Text="Time base" /></TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_UP-1000003"><Translation AttributeName="Text" Text="Time" /></TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_UP-1000147"><Translation AttributeName="Text" Text="Enable watchdog" /></TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_UP-1000144"><Translation AttributeName="Text" Text="Time zone" /></TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_UP-1000156"><Translation AttributeName="Text" Text="Receive via" /></TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_UP-1000159"><Translation AttributeName="Text" Text="Determine daylight saving time by" /></TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_UP-1100011"><Translation AttributeName="Text" Text="IP address" /></TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_UP-1100012"><Translation AttributeName="Text" Text="Subnet mask" /></TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_UP-1100013"><Translation AttributeName="Text" Text="Default gateway" /></TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_UP-1100001"><Translation AttributeName="Text" Text="Customize hostname" /></TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_UP-1100032"><Translation AttributeName="Text" Text="Web server" /></TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_UP-1100052"><Translation AttributeName="Text" Text="LAN mode" /></TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_UP-1100061"><Translation AttributeName="Text" Text="Time server" /></TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_M-1100001"><Translation AttributeName="Text" Text="Must be no more than 24 characters and consist only of letters, numbers, and hyphens." /></TranslationElement>
|
||||||
|
</TranslationUnit>
|
||||||
|
</Language>
|
||||||
|
<Language Identifier="zh-CN">
|
||||||
|
<TranslationUnit RefId="%AID%">
|
||||||
|
<TranslationElement RefId="%AID%_PT-DelayBase_EN-0"><Translation AttributeName="Text" Text="秒" /></TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_PT-DelayBase_EN-1"><Translation AttributeName="Text" Text="分钟" /></TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_PT-DelayBase_EN-2"><Translation AttributeName="Text" Text="小时" /></TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_PT-DelayBase10_EN-3"><Translation AttributeName="Text" Text="1/10 秒" /></TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_PT-OnOffYesNo_EN-0"><Translation AttributeName="Text" Text="否" /></TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_PT-OnOffYesNo_EN-1"><Translation AttributeName="Text" Text="是" /></TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_PT-OnOffYesNoInverted_EN-1"><Translation AttributeName="Text" Text="否" /></TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_PT-OnOffYesNoInverted_EN-0"><Translation AttributeName="Text" Text="是" /></TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_PT-CombinedTimeDate_EN-1"><Translation AttributeName="Text" Text="一个组合通信对象" /></TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_PT-CombinedTimeDate_EN-0"><Translation AttributeName="Text" Text="两个独立通信对象" /></TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_PT-SummertimeAll_EN-0"><Translation AttributeName="Text" Text="通信对象“夏令时激活”" /></TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_PT-SummertimeAll_EN-1"><Translation AttributeName="Text" Text="组合日期/时间通信对象 (DPT 19)" /></TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_PT-SummertimeAll_EN-2"><Translation AttributeName="Text" Text="内部计算" /></TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_PT-SummertimeDE_EN-0"><Translation AttributeName="Text" Text="通信对象“夏令时激活”" /></TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_PT-SummertimeDE_EN-2"><Translation AttributeName="Text" Text="内部计算" /></TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_PT-SummertimeWorld_EN-0"><Translation AttributeName="Text" Text="通信对象“夏令时激活”" /></TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_PT-SummertimeWorld_EN-1"><Translation AttributeName="Text" Text="组合日期/时间通信对象 (DPT 19)" /></TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_PT-SummertimeKO_EN-0"><Translation AttributeName="Text" Text="通信对象“夏令时激活”" /></TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_PT-Timezone_EN-1"><Translation AttributeName="Text" Text="阿姆斯特丹、柏林、伯尔尼、罗马、维也纳(+1 小时)" /></TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_PT-Timezone_EN-31"><Translation AttributeName="Text" Text="自定义" /></TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_PT-PeriodicSave_EN-0"><Translation AttributeName="Text" Text="已禁用" /></TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_PT-ManualSave_EN-0"><Translation AttributeName="Text" Text="已禁用" /></TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_PT-SLEDFunc_EN-0"><Translation AttributeName="Text" Text="已禁用" /></TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_PT-SLEDFunc_EN-1"><Translation AttributeName="Text" Text="编程 LED" /></TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_PT-SLEDFunc_EN-2"><Translation AttributeName="Text" Text="设备状态" /></TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_PT-SLEDFunc_EN-3"><Translation AttributeName="Text" Text="总线状态" /></TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_PT-SLEDFunc_EN-4"><Translation AttributeName="Text" Text="时间状态" /></TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_PT-SLEDFunc_EN-10"><Translation AttributeName="Text" Text="网络状态" /></TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_PT-CustomHostname_EN-0"><Translation AttributeName="Text" Text="默认" /></TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_PT-CustomHostname_EN-1"><Translation AttributeName="Text" Text="自定义" /></TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_PT-OTAUpdate_EN-0"><Translation AttributeName="Text" Text="编程模式下" /></TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_PT-OTAUpdate_EN-1"><Translation AttributeName="Text" Text="始终启用" /></TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_PT-OTAUpdate_EN-2"><Translation AttributeName="Text" Text="已禁用" /></TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_PT-LanMode_EN-0"><Translation AttributeName="Text" Text="自动" /></TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_PT-LanMode_EN-3"><Translation AttributeName="Text" Text="10 MBit/s(省电)" /></TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_UP-1000002"><Translation AttributeName="Text" Text="时间基准" /></TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_UP-1000003"><Translation AttributeName="Text" Text="时间" /></TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_UP-1000147"><Translation AttributeName="Text" Text="启用看门狗" /></TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_UP-1000144"><Translation AttributeName="Text" Text="时区" /></TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_UP-1000156"><Translation AttributeName="Text" Text="接收方式" /></TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_UP-1000159"><Translation AttributeName="Text" Text="夏令时判定方式" /></TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_UP-1100011"><Translation AttributeName="Text" Text="IP 地址" /></TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_UP-1100012"><Translation AttributeName="Text" Text="子网掩码" /></TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_UP-1100013"><Translation AttributeName="Text" Text="默认网关" /></TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_UP-1100001"><Translation AttributeName="Text" Text="自定义主机名" /></TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_UP-1100032"><Translation AttributeName="Text" Text="Web 服务器" /></TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_UP-1100052"><Translation AttributeName="Text" Text="LAN 模式" /></TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_UP-1100061"><Translation AttributeName="Text" Text="时间服务器" /></TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_M-1100001"><Translation AttributeName="Text" Text="最多 24 个字符,且只能包含字母、数字和连字符。" /></TranslationElement>
|
||||||
|
</TranslationUnit>
|
||||||
|
</Language>
|
||||||
|
<Language Identifier="de-DE">
|
||||||
|
<TranslationUnit RefId="%AID%">
|
||||||
|
<TranslationElement RefId="%AID%_PT-SLEDFunc_EN-2"><Translation AttributeName="Text" Text="Gerätestatus" /></TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_UP-1100032"><Translation AttributeName="Text" Text="Webserver" /></TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_M-1100001"><Translation AttributeName="Text" Text="Darf nur 24 Zeichen lang sein und muss aus Buchstaben, Zahlen und Bindestrichen bestehen." /></TranslationElement>
|
||||||
|
</TranslationUnit>
|
||||||
|
</Language>
|
||||||
|
<Language Identifier="ja-JP">
|
||||||
|
<TranslationUnit RefId="%AID%">
|
||||||
|
<TranslationElement RefId="%AID%_PT-DelayBase_EN-0"><Translation AttributeName="Text" Text="秒" /></TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_PT-DelayBase_EN-1"><Translation AttributeName="Text" Text="分" /></TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_PT-DelayBase_EN-2"><Translation AttributeName="Text" Text="時間" /></TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_PT-DelayBase10_EN-3"><Translation AttributeName="Text" Text="1/10 秒" /></TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_PT-OnOffYesNo_EN-0"><Translation AttributeName="Text" Text="いいえ" /></TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_PT-OnOffYesNo_EN-1"><Translation AttributeName="Text" Text="はい" /></TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_PT-OnOffYesNoInverted_EN-1"><Translation AttributeName="Text" Text="いいえ" /></TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_PT-OnOffYesNoInverted_EN-0"><Translation AttributeName="Text" Text="はい" /></TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_PT-CombinedTimeDate_EN-1"><Translation AttributeName="Text" Text="1 つの結合通信オブジェクト" /></TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_PT-CombinedTimeDate_EN-0"><Translation AttributeName="Text" Text="2 つの個別通信オブジェクト" /></TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_PT-SummertimeAll_EN-0"><Translation AttributeName="Text" Text="通信オブジェクト「夏時間有効」" /></TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_PT-SummertimeAll_EN-1"><Translation AttributeName="Text" Text="結合日付/時刻通信オブジェクト (DPT 19)" /></TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_PT-SummertimeAll_EN-2"><Translation AttributeName="Text" Text="内部計算" /></TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_PT-Timezone_EN-1"><Translation AttributeName="Text" Text="アムステルダム、ベルリン、ベルン、ローマ、ウィーン(+1 時間)" /></TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_PT-Timezone_EN-31"><Translation AttributeName="Text" Text="カスタム" /></TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_PT-PeriodicSave_EN-0"><Translation AttributeName="Text" Text="無効" /></TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_PT-ManualSave_EN-0"><Translation AttributeName="Text" Text="無効" /></TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_PT-SLEDFunc_EN-0"><Translation AttributeName="Text" Text="無効" /></TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_PT-SLEDFunc_EN-1"><Translation AttributeName="Text" Text="Prog LED" /></TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_PT-SLEDFunc_EN-2"><Translation AttributeName="Text" Text="デバイス状態" /></TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_PT-SLEDFunc_EN-3"><Translation AttributeName="Text" Text="バス状態" /></TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_PT-SLEDFunc_EN-4"><Translation AttributeName="Text" Text="時刻状態" /></TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_PT-SLEDFunc_EN-10"><Translation AttributeName="Text" Text="ネットワーク状態" /></TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_PT-CustomHostname_EN-0"><Translation AttributeName="Text" Text="デフォルト" /></TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_PT-CustomHostname_EN-1"><Translation AttributeName="Text" Text="カスタム" /></TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_PT-OTAUpdate_EN-0"><Translation AttributeName="Text" Text="プログラミングモード時" /></TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_PT-OTAUpdate_EN-1"><Translation AttributeName="Text" Text="常に有効" /></TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_PT-OTAUpdate_EN-2"><Translation AttributeName="Text" Text="無効" /></TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_PT-LanMode_EN-0"><Translation AttributeName="Text" Text="自動" /></TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_PT-LanMode_EN-3"><Translation AttributeName="Text" Text="10 MBit/s(省電力)" /></TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_UP-1000002"><Translation AttributeName="Text" Text="時間基準" /></TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_UP-1000003"><Translation AttributeName="Text" Text="時間" /></TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_UP-1000147"><Translation AttributeName="Text" Text="ウォッチドッグを有効化" /></TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_UP-1000144"><Translation AttributeName="Text" Text="タイムゾーン" /></TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_UP-1000156"><Translation AttributeName="Text" Text="受信方法" /></TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_UP-1000159"><Translation AttributeName="Text" Text="夏時間の判定方法" /></TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_UP-1100011"><Translation AttributeName="Text" Text="IP アドレス" /></TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_UP-1100012"><Translation AttributeName="Text" Text="サブネットマスク" /></TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_UP-1100013"><Translation AttributeName="Text" Text="デフォルトゲートウェイ" /></TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_UP-1100001"><Translation AttributeName="Text" Text="ホスト名をカスタマイズ" /></TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_UP-1100032"><Translation AttributeName="Text" Text="Web サーバー" /></TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_UP-1100052"><Translation AttributeName="Text" Text="LAN モード" /></TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_UP-1100061"><Translation AttributeName="Text" Text="時刻サーバー" /></TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_M-1100001"><Translation AttributeName="Text" Text="24 文字以内で、文字、数字、ハイフンのみを使用してください。" /></TranslationElement>
|
||||||
|
</TranslationUnit>
|
||||||
|
</Language>
|
||||||
|
</Languages>
|
||||||
|
</Manufacturer>
|
||||||
|
</ManufacturerData>
|
||||||
|
</KNX>
|
||||||
@@ -0,0 +1,436 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<KNX xmlns:op="http://github.com/OpenKNX/OpenKNXproducer" xmlns="http://knx.org/xml/project/20" CreatedBy="KNX MT" ToolVersion="5.1.255.16695">
|
||||||
|
<ManufacturerData>
|
||||||
|
<Manufacturer>
|
||||||
|
<ApplicationPrograms>
|
||||||
|
<ApplicationProgram>
|
||||||
|
<Static>
|
||||||
|
<ParameterTypes>
|
||||||
|
<ParameterType Id="%AID%_PT-Bool" Name="Bool">
|
||||||
|
<TypeRestriction Base="Value" SizeInBit="1">
|
||||||
|
<Enumeration Text="Disabled" Value="0" Id="%AID%_PT-Bool_EN-0" />
|
||||||
|
<Enumeration Text="Enabled" Value="1" Id="%AID%_PT-Bool_EN-1" />
|
||||||
|
</TypeRestriction>
|
||||||
|
</ParameterType>
|
||||||
|
<ParameterType Id="%AID%_PT-RoutingWithFilter" Name="RoutingWithFilter">
|
||||||
|
<TypeRestriction Base="Value" SizeInBit="2">
|
||||||
|
<Enumeration Text="Block" Value="2" Id="%AID%_PT-RoutingWithFilter_EN-2" />
|
||||||
|
<Enumeration Text="Route" Value="1" Id="%AID%_PT-RoutingWithFilter_EN-1" />
|
||||||
|
<Enumeration Text="Filter" Value="3" Id="%AID%_PT-RoutingWithFilter_EN-3" />
|
||||||
|
</TypeRestriction>
|
||||||
|
</ParameterType>
|
||||||
|
<ParameterType Id="%AID%_PT-GrpAcknowledge" Name="GrpAcknowledge">
|
||||||
|
<TypeRestriction Base="Value" SizeInBit="1">
|
||||||
|
<Enumeration Text="Always" Value="0" Id="%AID%_PT-GrpAcknowledge_EN-0" />
|
||||||
|
<Enumeration Text="Only when routed" Value="1" Id="%AID%_PT-GrpAcknowledge_EN-1" />
|
||||||
|
</TypeRestriction>
|
||||||
|
</ParameterType>
|
||||||
|
<ParameterType Id="%AID%_PT-BroadcastLock" Name="BroadcastLock">
|
||||||
|
<TypeRestriction Base="Value" SizeInBit="1">
|
||||||
|
<Enumeration Text="Block" Value="1" Id="%AID%_PT-BroadcastLock_EN-1" />
|
||||||
|
<Enumeration Text="Route" Value="0" Id="%AID%_PT-BroadcastLock_EN-0" />
|
||||||
|
</TypeRestriction>
|
||||||
|
</ParameterType>
|
||||||
|
<ParameterType Id="%AID%_PT-PhysAcknowledge" Name="PhysAcknowledge">
|
||||||
|
<TypeRestriction Base="Value" SizeInBit="2">
|
||||||
|
<Enumeration Text="Only when routed" Value="1" Id="%AID%_PT-PhysAcknowledge_EN-1" />
|
||||||
|
<Enumeration Text="Always" Value="2" Id="%AID%_PT-PhysAcknowledge_EN-2" />
|
||||||
|
<Enumeration Text="Always reject (NACK)" Value="3" Id="%AID%_PT-PhysAcknowledge_EN-3" />
|
||||||
|
</TypeRestriction>
|
||||||
|
</ParameterType>
|
||||||
|
<ParameterType Id="%AID%_PT-TunnelResOpt" Name="TunnelResOpt">
|
||||||
|
<TypeRestriction Base="Value" SizeInBit="2">
|
||||||
|
<Enumeration Text="Reject tunnel connection" Value="1" Id="%AID%_PT-TunnelResOpt_EN-1" />
|
||||||
|
<Enumeration Text="Disconnect previous tunnel connection" Value="2" Id="%AID%_PT-TunnelResOpt_EN-2" />
|
||||||
|
<Enumeration Text="Use another free tunnel" Value="3" Id="%AID%_PT-TunnelResOpt_EN-3" />
|
||||||
|
</TypeRestriction>
|
||||||
|
</ParameterType>
|
||||||
|
</ParameterTypes>
|
||||||
|
<Parameters>
|
||||||
|
<Parameter Id="%AID%_P-9900002" Name="AckOfPhysTelSubMain" ParameterType="%AID%_PT-PhysAcknowledge" Text="ACK for physically addressed telegrams" Value="1">
|
||||||
|
<Property ObjectType="6" PropertyId="53" Offset="0" BitOffset="0" />
|
||||||
|
</Parameter>
|
||||||
|
<Parameter Id="%AID%_P-9900003" Name="AckOfGrpTelSubMain" ParameterType="%AID%_PT-GrpAcknowledge" Text="ACK for group telegrams" Value="1">
|
||||||
|
<Property ObjectType="6" PropertyId="53" Offset="0" BitOffset="2" />
|
||||||
|
</Parameter>
|
||||||
|
<Parameter Id="%AID%_P-9900004" Name="BroadcastTelSubMain" ParameterType="%AID%_PT-BroadcastLock" Text="Broadcast telegrams" Value="0">
|
||||||
|
<Property ObjectType="6" PropertyId="53" Offset="0" BitOffset="4" />
|
||||||
|
</Parameter>
|
||||||
|
<Parameter Id="%AID%_P-9900005" Name="PhysTelSubMain" ParameterType="%AID%_PT-RoutingWithFilter" Text="Physically addressed telegrams" Value="3">
|
||||||
|
<Property ObjectType="6" PropertyId="53" Offset="0" BitOffset="6" />
|
||||||
|
</Parameter>
|
||||||
|
<Parameter Id="%AID%_P-9900006" Name="GrpTelSubMain_14_31" ParameterType="%AID%_PT-RoutingWithFilter" Text="Group telegrams (main group 14 - 31)" Value="3">
|
||||||
|
<Property ObjectType="6" PropertyId="55" Offset="0" BitOffset="4" />
|
||||||
|
</Parameter>
|
||||||
|
<Parameter Id="%AID%_P-9900007" Name="GrpTelSubMain_0_13" ParameterType="%AID%_PT-RoutingWithFilter" Text="Group telegrams (main group 0 - 13)" Value="3">
|
||||||
|
<Property ObjectType="6" PropertyId="55" Offset="0" BitOffset="6" />
|
||||||
|
</Parameter>
|
||||||
|
<Parameter Id="%AID%_P-9900008" Name="RepetitionBroadcastTelMainSub" ParameterType="%AID%_PT-Bool" Text="Repetition of broadcast telegrams" Value="1">
|
||||||
|
<Property ObjectType="6" PropertyId="52" Offset="0" BitOffset="3" />
|
||||||
|
</Parameter>
|
||||||
|
<Parameter Id="%AID%_P-9900009" Name="BroadcastTelMainSub" ParameterType="%AID%_PT-BroadcastLock" Text="Broadcast telegrams" Value="0">
|
||||||
|
<Property ObjectType="6" PropertyId="52" Offset="0" BitOffset="4" />
|
||||||
|
</Parameter>
|
||||||
|
<Parameter Id="%AID%_P-9900010" Name="RepetitionPhysTelMainSub" ParameterType="%AID%_PT-Bool" Text="Repetition of physically addressed telegrams" Value="1">
|
||||||
|
<Property ObjectType="6" PropertyId="52" Offset="0" BitOffset="5" />
|
||||||
|
</Parameter>
|
||||||
|
<Parameter Id="%AID%_P-9900011" Name="PhysTelMainSub" ParameterType="%AID%_PT-RoutingWithFilter" Text="Physically addressed telegrams" Value="3">
|
||||||
|
<Property ObjectType="6" PropertyId="52" Offset="0" BitOffset="6" />
|
||||||
|
</Parameter>
|
||||||
|
<Parameter Id="%AID%_P-9900012" Name="RepetitionGrpTelMainSub" ParameterType="%AID%_PT-Bool" Text="Repetition of group telegrams" Value="1">
|
||||||
|
<Property ObjectType="6" PropertyId="54" Offset="0" BitOffset="3" />
|
||||||
|
</Parameter>
|
||||||
|
<Parameter Id="%AID%_P-9900013" Name="GrpTelMainSub_14_31" ParameterType="%AID%_PT-RoutingWithFilter" Text="Group telegrams (main group 14 - 31)" Value="3">
|
||||||
|
<Property ObjectType="6" PropertyId="54" Offset="0" BitOffset="4" />
|
||||||
|
</Parameter>
|
||||||
|
<Parameter Id="%AID%_P-9900014" Name="GrpTelMainSub_0_13" ParameterType="%AID%_PT-RoutingWithFilter" Text="Group telegrams (main group 0 - 13)" Value="3">
|
||||||
|
<Property ObjectType="6" PropertyId="54" Offset="0" BitOffset="6" />
|
||||||
|
</Parameter>
|
||||||
|
</Parameters>
|
||||||
|
<ParameterRefs>
|
||||||
|
<ParameterRef Id="%AID%_P-9900002_R-990000201" RefId="%AID%_P-9900002" Tag="42" />
|
||||||
|
<ParameterRef Id="%AID%_P-9900003_R-990000301" RefId="%AID%_P-9900003" Tag="27" />
|
||||||
|
<ParameterRef Id="%AID%_P-9900004_R-990000401" RefId="%AID%_P-9900004" Tag="26" />
|
||||||
|
<ParameterRef Id="%AID%_P-9900005_R-990000501" RefId="%AID%_P-9900005" Tag="25" />
|
||||||
|
<ParameterRef Id="%AID%_P-9900006_R-990000601" RefId="%AID%_P-9900006" Tag="24" />
|
||||||
|
<ParameterRef Id="%AID%_P-9900007_R-990000701" RefId="%AID%_P-9900007" Tag="23" />
|
||||||
|
<ParameterRef Id="%AID%_P-9900008_R-990000801" RefId="%AID%_P-9900008" Tag="34" />
|
||||||
|
<ParameterRef Id="%AID%_P-9900009_R-990000901" RefId="%AID%_P-9900009" Tag="31" />
|
||||||
|
<ParameterRef Id="%AID%_P-9900010_R-990001001" RefId="%AID%_P-9900010" Tag="33" />
|
||||||
|
<ParameterRef Id="%AID%_P-9900011_R-990001101" RefId="%AID%_P-9900011" Tag="30" />
|
||||||
|
<ParameterRef Id="%AID%_P-9900012_R-990001201" RefId="%AID%_P-9900012" Tag="32" />
|
||||||
|
<ParameterRef Id="%AID%_P-9900013_R-990001301" RefId="%AID%_P-9900013" Tag="29" />
|
||||||
|
<ParameterRef Id="%AID%_P-9900014_R-990001401" RefId="%AID%_P-9900014" Tag="28" />
|
||||||
|
</ParameterRefs>
|
||||||
|
<ComObjectTable>
|
||||||
|
</ComObjectTable>
|
||||||
|
<ComObjectRefs>
|
||||||
|
</ComObjectRefs>
|
||||||
|
</Static>
|
||||||
|
<Dynamic>
|
||||||
|
<Channel Id="%AID%_CH-%PREFIX%-Routing" Number="%PREFIX%" Name="OAM IP Router" Text="OAM IP Router" Icon="router-network">
|
||||||
|
<ParameterBlock Id="%AID%_PB-nnn" Name="RoutingKNXIP" Text="Routing KNX -> IP" Icon="router">
|
||||||
|
<ParameterSeparator Id="%AID%_PS-" Text="Settings for routing telegrams from TP to IP" UIHint="Headline" />
|
||||||
|
<ParameterRefRef RefId="%AID%_P-9900007_R-990000701" IndentLevel="1" />
|
||||||
|
<ParameterRefRef RefId="%AID%_P-9900006_R-990000601" IndentLevel="1" />
|
||||||
|
<ParameterRefRef RefId="%AID%_P-9900005_R-990000501" IndentLevel="1" />
|
||||||
|
<ParameterRefRef RefId="%AID%_P-9900004_R-990000401" IndentLevel="1" />
|
||||||
|
<ParameterRefRef RefId="%AID%_P-9900003_R-990000301" IndentLevel="1" />
|
||||||
|
<ParameterRefRef RefId="%AID%_P-9900002_R-990000201" IndentLevel="1" />
|
||||||
|
<choose ParamRefId="%AID%_P-9900002_R-990000201">
|
||||||
|
<when test="3">
|
||||||
|
<ParameterSeparator Id="%AID%_PS-" Text="With always reject (NACK), programming is only possible over IP." />
|
||||||
|
</when>
|
||||||
|
</choose>
|
||||||
|
</ParameterBlock>
|
||||||
|
<ParameterBlock Id="%AID%_PB-nnn" Name="RoutingIPKNX" Text="Routing IP -> KNX" Icon="router">
|
||||||
|
<ParameterSeparator Id="%AID%_PS-" Text="Settings for routing telegrams from IP to TP" UIHint="Headline" />
|
||||||
|
<ParameterRefRef RefId="%AID%_P-9900014_R-990001401" IndentLevel="1" />
|
||||||
|
<ParameterRefRef RefId="%AID%_P-9900013_R-990001301" IndentLevel="1" />
|
||||||
|
<ParameterRefRef RefId="%AID%_P-9900011_R-990001101" IndentLevel="1" />
|
||||||
|
<ParameterRefRef RefId="%AID%_P-9900009_R-990000901" IndentLevel="1" />
|
||||||
|
<ParameterRefRef RefId="%AID%_P-9900012_R-990001201" IndentLevel="1" />
|
||||||
|
<ParameterRefRef RefId="%AID%_P-9900010_R-990001001" IndentLevel="1" />
|
||||||
|
<ParameterRefRef RefId="%AID%_P-9900008_R-990000801" IndentLevel="1" />
|
||||||
|
</ParameterBlock>
|
||||||
|
<ParameterBlock Id="%AID%_PB-nnn" Name="Tunnel" Text="Tunnel connections" Icon="lan-connect">
|
||||||
|
<ParameterSeparator Id="%AID%_PS-" Text="Settings for reserved tunnel connections" UIHint="Headline" />
|
||||||
|
<ParameterSeparator Id="%AID%_PS-nnn" Text="The physical addresses of tunnel connections are configured in the ETS topology view." UIHint="Information" />
|
||||||
|
<ParameterBlock Id="%AID%_PB-nnn" Inline="true" Layout="Grid">
|
||||||
|
<Rows>
|
||||||
|
<Row Id="%AID%_PB-nnn_R-1" />
|
||||||
|
</Rows>
|
||||||
|
<Columns>
|
||||||
|
<Column Id="%AID%_PB-nnn_C-1" Width="2%" />
|
||||||
|
<Column Id="%AID%_PB-nnn_C-2" Width="18%" />
|
||||||
|
<Column Id="%AID%_PB-nnn_C-3" Width="5%" />
|
||||||
|
<Column Id="%AID%_PB-nnn_C-4" Width="20%" />
|
||||||
|
<Column Id="%AID%_PB-nnn_C-5" Width="50%" />
|
||||||
|
</Columns>
|
||||||
|
<ParameterSeparator Id="%AID%_PS-nnn" Text="Assignment" UIHint="Headline" Cell="1,2" />
|
||||||
|
<ParameterSeparator Id="%AID%_PS-nnn" Text="IP address" UIHint="Headline" Cell="1,4" />
|
||||||
|
<ParameterSeparator Id="%AID%_PS-nnn" Text="Behavior when tunnel is busy" UIHint="Headline" Cell="1,5" />
|
||||||
|
</ParameterBlock>
|
||||||
|
<op:include href="Gateway-OAM-IP-Router.templ.xml" xpath="//Dynamic/ChannelIndependentBlock/*" IsInner="true" type="template" prefix="ROUTE" />
|
||||||
|
</ParameterBlock>
|
||||||
|
</Channel>
|
||||||
|
</Dynamic>
|
||||||
|
</ApplicationProgram>
|
||||||
|
</ApplicationPrograms>
|
||||||
|
<Languages>
|
||||||
|
<Language Identifier="zh-CN">
|
||||||
|
<TranslationUnit RefId="%AID%">
|
||||||
|
<TranslationElement RefId="%AID%_PT-Bool_EN-0">
|
||||||
|
<Translation AttributeName="Text" Text="禁用" />
|
||||||
|
</TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_PT-Bool_EN-1">
|
||||||
|
<Translation AttributeName="Text" Text="启用" />
|
||||||
|
</TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_PT-RoutingWithFilter_EN-2">
|
||||||
|
<Translation AttributeName="Text" Text="阻止" />
|
||||||
|
</TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_PT-RoutingWithFilter_EN-1">
|
||||||
|
<Translation AttributeName="Text" Text="路由" />
|
||||||
|
</TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_PT-RoutingWithFilter_EN-3">
|
||||||
|
<Translation AttributeName="Text" Text="过滤" />
|
||||||
|
</TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_PT-GrpAcknowledge_EN-0">
|
||||||
|
<Translation AttributeName="Text" Text="始终" />
|
||||||
|
</TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_PT-GrpAcknowledge_EN-1">
|
||||||
|
<Translation AttributeName="Text" Text="仅在路由时" />
|
||||||
|
</TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_PT-BroadcastLock_EN-1">
|
||||||
|
<Translation AttributeName="Text" Text="阻止" />
|
||||||
|
</TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_PT-BroadcastLock_EN-0">
|
||||||
|
<Translation AttributeName="Text" Text="路由" />
|
||||||
|
</TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_PT-PhysAcknowledge_EN-1">
|
||||||
|
<Translation AttributeName="Text" Text="仅在路由时" />
|
||||||
|
</TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_PT-PhysAcknowledge_EN-2">
|
||||||
|
<Translation AttributeName="Text" Text="始终" />
|
||||||
|
</TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_PT-PhysAcknowledge_EN-3">
|
||||||
|
<Translation AttributeName="Text" Text="始终拒绝 (NACK)" />
|
||||||
|
</TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_PT-TunnelResOpt_EN-1">
|
||||||
|
<Translation AttributeName="Text" Text="拒绝隧道连接" />
|
||||||
|
</TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_PT-TunnelResOpt_EN-2">
|
||||||
|
<Translation AttributeName="Text" Text="断开之前的隧道连接" />
|
||||||
|
</TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_PT-TunnelResOpt_EN-3">
|
||||||
|
<Translation AttributeName="Text" Text="使用另一个空闲隧道" />
|
||||||
|
</TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_P-9900002">
|
||||||
|
<Translation AttributeName="Text" Text="物理寻址报文的 ACK" />
|
||||||
|
</TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_P-9900003">
|
||||||
|
<Translation AttributeName="Text" Text="组报文的 ACK" />
|
||||||
|
</TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_P-9900004">
|
||||||
|
<Translation AttributeName="Text" Text="广播报文" />
|
||||||
|
</TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_P-9900005">
|
||||||
|
<Translation AttributeName="Text" Text="物理寻址报文" />
|
||||||
|
</TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_P-9900006">
|
||||||
|
<Translation AttributeName="Text" Text="组报文(主组 14 - 31)" />
|
||||||
|
</TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_P-9900007">
|
||||||
|
<Translation AttributeName="Text" Text="组报文(主组 0 - 13)" />
|
||||||
|
</TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_P-9900008">
|
||||||
|
<Translation AttributeName="Text" Text="重复广播报文" />
|
||||||
|
</TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_P-9900009">
|
||||||
|
<Translation AttributeName="Text" Text="广播报文" />
|
||||||
|
</TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_P-9900010">
|
||||||
|
<Translation AttributeName="Text" Text="重复物理寻址报文" />
|
||||||
|
</TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_P-9900011">
|
||||||
|
<Translation AttributeName="Text" Text="物理寻址报文" />
|
||||||
|
</TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_P-9900012">
|
||||||
|
<Translation AttributeName="Text" Text="重复组报文" />
|
||||||
|
</TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_P-9900013">
|
||||||
|
<Translation AttributeName="Text" Text="组报文(主组 14 - 31)" />
|
||||||
|
</TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_P-9900014">
|
||||||
|
<Translation AttributeName="Text" Text="组报文(主组 0 - 13)" />
|
||||||
|
</TranslationElement>
|
||||||
|
</TranslationUnit>
|
||||||
|
</Language>
|
||||||
|
<Language Identifier="de-DE">
|
||||||
|
<TranslationUnit RefId="%AID%">
|
||||||
|
<TranslationElement RefId="%AID%_PT-Bool_EN-0">
|
||||||
|
<Translation AttributeName="Text" Text="Deaktiviert" />
|
||||||
|
</TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_PT-Bool_EN-1">
|
||||||
|
<Translation AttributeName="Text" Text="Aktiviert" />
|
||||||
|
</TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_PT-RoutingWithFilter_EN-2">
|
||||||
|
<Translation AttributeName="Text" Text="Sperren" />
|
||||||
|
</TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_PT-RoutingWithFilter_EN-1">
|
||||||
|
<Translation AttributeName="Text" Text="Weiterleiten" />
|
||||||
|
</TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_PT-RoutingWithFilter_EN-3">
|
||||||
|
<Translation AttributeName="Text" Text="Filtern" />
|
||||||
|
</TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_PT-GrpAcknowledge_EN-0">
|
||||||
|
<Translation AttributeName="Text" Text="Immer" />
|
||||||
|
</TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_PT-GrpAcknowledge_EN-1">
|
||||||
|
<Translation AttributeName="Text" Text="Nur wenn weitergeleitet" />
|
||||||
|
</TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_PT-BroadcastLock_EN-1">
|
||||||
|
<Translation AttributeName="Text" Text="Sperren" />
|
||||||
|
</TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_PT-BroadcastLock_EN-0">
|
||||||
|
<Translation AttributeName="Text" Text="Weiterleiten" />
|
||||||
|
</TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_PT-PhysAcknowledge_EN-1">
|
||||||
|
<Translation AttributeName="Text" Text="Nur wenn weitergeleitet" />
|
||||||
|
</TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_PT-PhysAcknowledge_EN-2">
|
||||||
|
<Translation AttributeName="Text" Text="Immer" />
|
||||||
|
</TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_PT-PhysAcknowledge_EN-3">
|
||||||
|
<Translation AttributeName="Text" Text="Immer ablehnen (NACK)" />
|
||||||
|
</TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_PT-TunnelResOpt_EN-1">
|
||||||
|
<Translation AttributeName="Text" Text="Tunnelverbindung ablehnen" />
|
||||||
|
</TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_PT-TunnelResOpt_EN-2">
|
||||||
|
<Translation AttributeName="Text" Text="Vorherige Tunnelverbindung trennen" />
|
||||||
|
</TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_PT-TunnelResOpt_EN-3">
|
||||||
|
<Translation AttributeName="Text" Text="Anderen freien Tunnel verwenden" />
|
||||||
|
</TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_P-9900002">
|
||||||
|
<Translation AttributeName="Text" Text="ACK für physikalisch adressierte Telegramme" />
|
||||||
|
</TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_P-9900003">
|
||||||
|
<Translation AttributeName="Text" Text="ACK für Gruppentelegramme" />
|
||||||
|
</TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_P-9900004">
|
||||||
|
<Translation AttributeName="Text" Text="Broadcast-Telegramme" />
|
||||||
|
</TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_P-9900005">
|
||||||
|
<Translation AttributeName="Text" Text="Physikalisch adressierte Telegramme" />
|
||||||
|
</TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_P-9900006">
|
||||||
|
<Translation AttributeName="Text" Text="Gruppentelegramme (Hauptgruppe 14 - 31)" />
|
||||||
|
</TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_P-9900007">
|
||||||
|
<Translation AttributeName="Text" Text="Gruppentelegramme (Hauptgruppe 0 - 13)" />
|
||||||
|
</TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_P-9900008">
|
||||||
|
<Translation AttributeName="Text" Text="Wiederholung von Broadcast-Telegrammen" />
|
||||||
|
</TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_P-9900009">
|
||||||
|
<Translation AttributeName="Text" Text="Broadcast-Telegramme" />
|
||||||
|
</TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_P-9900010">
|
||||||
|
<Translation AttributeName="Text" Text="Wiederholung von physikalisch adressierten Telegrammen" />
|
||||||
|
</TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_P-9900011">
|
||||||
|
<Translation AttributeName="Text" Text="Physikalisch adressierte Telegramme" />
|
||||||
|
</TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_P-9900012">
|
||||||
|
<Translation AttributeName="Text" Text="Wiederholung von Gruppentelegrammen" />
|
||||||
|
</TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_P-9900013">
|
||||||
|
<Translation AttributeName="Text" Text="Gruppentelegramme (Hauptgruppe 14 - 31)" />
|
||||||
|
</TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_P-9900014">
|
||||||
|
<Translation AttributeName="Text" Text="Gruppentelegramme (Hauptgruppe 0 - 13)" />
|
||||||
|
</TranslationElement>
|
||||||
|
</TranslationUnit>
|
||||||
|
</Language>
|
||||||
|
<Language Identifier="ja-JP">
|
||||||
|
<TranslationUnit RefId="%AID%">
|
||||||
|
<TranslationElement RefId="%AID%_PT-Bool_EN-0">
|
||||||
|
<Translation AttributeName="Text" Text="無効" />
|
||||||
|
</TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_PT-Bool_EN-1">
|
||||||
|
<Translation AttributeName="Text" Text="有効" />
|
||||||
|
</TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_PT-RoutingWithFilter_EN-2">
|
||||||
|
<Translation AttributeName="Text" Text="ブロック" />
|
||||||
|
</TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_PT-RoutingWithFilter_EN-1">
|
||||||
|
<Translation AttributeName="Text" Text="ルーティング" />
|
||||||
|
</TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_PT-RoutingWithFilter_EN-3">
|
||||||
|
<Translation AttributeName="Text" Text="フィルター" />
|
||||||
|
</TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_PT-GrpAcknowledge_EN-0">
|
||||||
|
<Translation AttributeName="Text" Text="常時" />
|
||||||
|
</TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_PT-GrpAcknowledge_EN-1">
|
||||||
|
<Translation AttributeName="Text" Text="ルーティング時のみ" />
|
||||||
|
</TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_PT-BroadcastLock_EN-1">
|
||||||
|
<Translation AttributeName="Text" Text="ブロック" />
|
||||||
|
</TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_PT-BroadcastLock_EN-0">
|
||||||
|
<Translation AttributeName="Text" Text="ルーティング" />
|
||||||
|
</TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_PT-PhysAcknowledge_EN-1">
|
||||||
|
<Translation AttributeName="Text" Text="ルーティング時のみ" />
|
||||||
|
</TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_PT-PhysAcknowledge_EN-2">
|
||||||
|
<Translation AttributeName="Text" Text="常時" />
|
||||||
|
</TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_PT-PhysAcknowledge_EN-3">
|
||||||
|
<Translation AttributeName="Text" Text="常時拒否 (NACK)" />
|
||||||
|
</TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_PT-TunnelResOpt_EN-1">
|
||||||
|
<Translation AttributeName="Text" Text="トンネル接続を拒否" />
|
||||||
|
</TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_PT-TunnelResOpt_EN-2">
|
||||||
|
<Translation AttributeName="Text" Text="以前のトンネル接続を切断" />
|
||||||
|
</TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_PT-TunnelResOpt_EN-3">
|
||||||
|
<Translation AttributeName="Text" Text="別の空きトンネルを使用" />
|
||||||
|
</TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_P-9900002">
|
||||||
|
<Translation AttributeName="Text" Text="物理アドレス宛テレグラムの ACK" />
|
||||||
|
</TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_P-9900003">
|
||||||
|
<Translation AttributeName="Text" Text="グループテレグラムの ACK" />
|
||||||
|
</TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_P-9900004">
|
||||||
|
<Translation AttributeName="Text" Text="ブロードキャストテレグラム" />
|
||||||
|
</TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_P-9900005">
|
||||||
|
<Translation AttributeName="Text" Text="物理アドレス宛テレグラム" />
|
||||||
|
</TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_P-9900006">
|
||||||
|
<Translation AttributeName="Text" Text="グループテレグラム (メイングループ 14 - 31)" />
|
||||||
|
</TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_P-9900007">
|
||||||
|
<Translation AttributeName="Text" Text="グループテレグラム (メイングループ 0 - 13)" />
|
||||||
|
</TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_P-9900008">
|
||||||
|
<Translation AttributeName="Text" Text="ブロードキャストテレグラムの繰り返し" />
|
||||||
|
</TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_P-9900009">
|
||||||
|
<Translation AttributeName="Text" Text="ブロードキャストテレグラム" />
|
||||||
|
</TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_P-9900010">
|
||||||
|
<Translation AttributeName="Text" Text="物理アドレス宛テレグラムの繰り返し" />
|
||||||
|
</TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_P-9900011">
|
||||||
|
<Translation AttributeName="Text" Text="物理アドレス宛テレグラム" />
|
||||||
|
</TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_P-9900012">
|
||||||
|
<Translation AttributeName="Text" Text="グループテレグラムの繰り返し" />
|
||||||
|
</TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_P-9900013">
|
||||||
|
<Translation AttributeName="Text" Text="グループテレグラム (メイングループ 14 - 31)" />
|
||||||
|
</TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_P-9900014">
|
||||||
|
<Translation AttributeName="Text" Text="グループテレグラム (メイングループ 0 - 13)" />
|
||||||
|
</TranslationElement>
|
||||||
|
</TranslationUnit>
|
||||||
|
</Language>
|
||||||
|
</Languages>
|
||||||
|
<Baggages>
|
||||||
|
<Baggage TargetPath="" Name="Help_en.zip" Id="%FILE-HELP-de%">
|
||||||
|
<FileInfo TimeInfo="%DATETIME%" />
|
||||||
|
</Baggage>
|
||||||
|
<Baggage TargetPath="" Name="Icons.zip" Id="%FILE-ICONS%">
|
||||||
|
<FileInfo TimeInfo="%DATETIME%" />
|
||||||
|
</Baggage>
|
||||||
|
</Baggages>
|
||||||
|
</Manufacturer>
|
||||||
|
</ManufacturerData>
|
||||||
|
</KNX>
|
||||||
@@ -0,0 +1,56 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8" ?>
|
||||||
|
<KNX xmlns="http://knx.org/xml/project/20" xmlns:op="http://github.com/OpenKNX/OpenKNXproducer">
|
||||||
|
<ManufacturerData>
|
||||||
|
<Manufacturer RefId="M-00FA">
|
||||||
|
<ApplicationPrograms>
|
||||||
|
<ApplicationProgram>
|
||||||
|
<Static>
|
||||||
|
<Parameters>
|
||||||
|
<Parameter Id="%AID%_P-%TT%%CC%001" Name="ResTunnel%C%" ParameterType="%AID%_PT-CheckBox" Text="Reserve tunnel %C%" Value="0">
|
||||||
|
<Property ObjectType="11" PropertyId="201" Offset="%C-1%" BitOffset="0" />
|
||||||
|
</Parameter>
|
||||||
|
<Parameter Id="%AID%_P-%TT%%CC%002" Name="Tunnel%C%IP" ParameterType="%AID%_PT-HostAddress" Text="IP address for tunnel %C%" Value="0.0.0.0">
|
||||||
|
<Property ObjectType="11" PropertyId="202" Offset="%C*4-4%" BitOffset="0" />
|
||||||
|
</Parameter>
|
||||||
|
<Parameter Id="%AID%_P-%TT%%CC%003" Name="OptTunnel%C%" ParameterType="%AID%_PT-TunnelResOpt" Text="Behavior when tunnel is busy" Value="1">
|
||||||
|
<Property ObjectType="11" PropertyId="201" Offset="%C-1%" BitOffset="1" />
|
||||||
|
</Parameter>
|
||||||
|
</Parameters>
|
||||||
|
<ParameterRefs>
|
||||||
|
<ParameterRef Id="%AID%_P-%TT%%CC%001_R-%TT%%CC%00101" RefId="%AID%_P-%TT%%CC%001" />
|
||||||
|
<ParameterRef Id="%AID%_P-%TT%%CC%002_R-%TT%%CC%00201" RefId="%AID%_P-%TT%%CC%002" />
|
||||||
|
<ParameterRef Id="%AID%_P-%TT%%CC%003_R-%TT%%CC%00301" RefId="%AID%_P-%TT%%CC%003" />
|
||||||
|
</ParameterRefs>
|
||||||
|
<BusInterfaces>
|
||||||
|
<BusInterface Id="%AID%_BI-%C%" AddressIndex="%C%" AccessType="Tunneling" Text="Tunnel %C%" />
|
||||||
|
</BusInterfaces>
|
||||||
|
</Static>
|
||||||
|
<Dynamic>
|
||||||
|
<ChannelIndependentBlock>
|
||||||
|
<ParameterBlock Id="%AID%_PB-nnn" Inline="true" Layout="Grid">
|
||||||
|
<Rows>
|
||||||
|
<Row Id="%AID%_PB-nnn_R-1" />
|
||||||
|
</Rows>
|
||||||
|
<Columns>
|
||||||
|
<Column Id="%AID%_PB-nnn_C-1" Width="2%" />
|
||||||
|
<Column Id="%AID%_PB-nnn_C-2" Width="18%" />
|
||||||
|
<Column Id="%AID%_PB-nnn_C-3" Width="5%" />
|
||||||
|
<Column Id="%AID%_PB-nnn_C-4" Width="20%" />
|
||||||
|
<Column Id="%AID%_PB-nnn_C-5" Width="50%" />
|
||||||
|
</Columns>
|
||||||
|
<ParameterSeparator Id="%AID%_PS-nnn" Text="Tunnel %C%" Cell="1,2" />
|
||||||
|
<ParameterRefRef RefId="%AID%_P-%TT%%CC%001_R-%TT%%CC%00101" Cell="1,3" />
|
||||||
|
<choose ParamRefId="%AID%_P-%TT%%CC%001_R-%TT%%CC%00101">
|
||||||
|
<when test="1">
|
||||||
|
<ParameterRefRef RefId="%AID%_P-%TT%%CC%002_R-%TT%%CC%00201" Cell="1,4" />
|
||||||
|
<ParameterRefRef RefId="%AID%_P-%TT%%CC%003_R-%TT%%CC%00301" Cell="1,5" />
|
||||||
|
</when>
|
||||||
|
</choose>
|
||||||
|
</ParameterBlock>
|
||||||
|
</ChannelIndependentBlock>
|
||||||
|
</Dynamic>
|
||||||
|
</ApplicationProgram>
|
||||||
|
</ApplicationPrograms>
|
||||||
|
</Manufacturer>
|
||||||
|
</ManufacturerData>
|
||||||
|
</KNX>
|
||||||
@@ -0,0 +1,47 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8" ?>
|
||||||
|
<KNX xmlns="http://knx.org/xml/project/20" xmlns:op="http://github.com/OpenKNX/OpenKNXproducer">
|
||||||
|
|
||||||
|
<op:config name="%IsSecureEnabled%" value="true" />
|
||||||
|
<op:config name="%NET_IPConfigTool%" value="1" />
|
||||||
|
<op:config name="%Tunnelcount%" value="16" />
|
||||||
|
<op:config name="%MaxUserEntries%" value="17" />
|
||||||
|
<op:config name="%NET_ServiceNTP%" value="1" />
|
||||||
|
<op:config name="%SecurityProxyGroupKeyTableEntries%" value="3000" />
|
||||||
|
|
||||||
|
<op:config name="%BASE_Info1LedLabel%" value=" (N/A)" />
|
||||||
|
<op:config name="%BASE_Info2LedLabel%" value=" (IP)" />
|
||||||
|
<op:config name="%BASE_Info3LedLabel%" value=" (KNX)" />
|
||||||
|
<op:config name="%BASE_Info1LedFunc%" value="0" />
|
||||||
|
<op:config name="%BASE_Info2LedFunc%" value="10" />
|
||||||
|
<op:config name="%BASE_Info3LedFunc%" value="3" />
|
||||||
|
<op:config name="%BASE_Info1LedFunc_Access%" value="ReadWrite" />
|
||||||
|
<op:config name="%BASE_Info2LedFunc_Access%" value="ReadWrite" />
|
||||||
|
<op:config name="%BASE_Info3LedFunc_Access%" value="ReadWrite" />
|
||||||
|
|
||||||
|
<op:nowarn id="1" regex="%BASE_" />
|
||||||
|
<op:nowarn id="3" regex="BASE_getUnsupportedEtsModules" />
|
||||||
|
|
||||||
|
<op:ETS OpenKnxId="0xA1"
|
||||||
|
ApplicationNumber="31"
|
||||||
|
ApplicationVersion="0.7"
|
||||||
|
ReplacesVersions="0.6 0.4 0.3 0.2 0.1"
|
||||||
|
ApplicationRevision="0"
|
||||||
|
ProductName="Gateway OAM IP Router"
|
||||||
|
SerialNumber="1"
|
||||||
|
OrderNumber="GatewayOAMIPRouter"
|
||||||
|
ApplicationName="Gateway OAM IP Router"
|
||||||
|
IsRailMounted="true"
|
||||||
|
BusCurrent="30"
|
||||||
|
MaskVersion="MV-091A" />
|
||||||
|
|
||||||
|
<op:define prefix="BASE" ModuleType="10">
|
||||||
|
<op:verify File="deps/OGM-Common/library.json" ModuleVersion="1.7" />
|
||||||
|
</op:define>
|
||||||
|
<op:define prefix="NET" ModuleType="11" share="deps/OFM-Network/src/Network.share.xml">
|
||||||
|
<op:verify File="deps/OFM-Network/library.json" ModuleVersion="0.5" />
|
||||||
|
</op:define>
|
||||||
|
<op:define prefix="ROUTE" NumChannels="%Tunnelcount%" ModuleType="99" share="Gateway-OAM-IP-Router.share.xml" template="Gateway-OAM-IP-Router.templ.xml" />
|
||||||
|
|
||||||
|
<generate base="Gateway-SecureTemplateRouter.xml" />
|
||||||
|
|
||||||
|
</KNX>
|
||||||
@@ -0,0 +1,348 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8" ?>
|
||||||
|
<KNX xmlns="http://knx.org/xml/project/20" xmlns:op="http://github.com/OpenKNX/OpenKNXproducer">
|
||||||
|
<ManufacturerData>
|
||||||
|
<Manufacturer RefId="M-00FA">
|
||||||
|
<Catalog>
|
||||||
|
<CatalogSection Id="M-00FA_CS-OpenKNX" Name="OpenKNX" Number="OpenKNX" DefaultLanguage="en-US">
|
||||||
|
<CatalogItem Id="%CatalogItemId%" Name="OpenKNX: %CatalogName%%BuildSuffixText%" Number="1" ProductRefId="%ProductId%" Hardware2ProgramRefId="%Hardware2ProgramId%" DefaultLanguage="en-US" />
|
||||||
|
</CatalogSection>
|
||||||
|
</Catalog>
|
||||||
|
<ApplicationPrograms>
|
||||||
|
<op:version OpenKnxId="%OpenKnxId%" ApplicationNumber="%ApplicationNumber%" ApplicationVersion="%ApplicationVersion%" ReplacesVersions="%ReplacesVersions%" ApplicationRevision="%ApplicationRevision%" FirmwareRevision="%FirmwareRevision%" />
|
||||||
|
<ApplicationProgram Id="%AID%" ProgramType="ApplicationProgram" MaskVersion="%MaskVersion%" Name="%ApplicationName%%BuildSuffix%" LoadProcedureStyle="MergedProcedure" PeiType="0" DefaultLanguage="en-US" IsSecureEnabled="%IsSecureEnabled%" MaxUserEntries="%MaxUserEntries%" MaxSecurityGroupKeyTableEntries="3000" MaxSecurityIndividualAddressEntries="1000" MaxSecurityProxyGroupKeyTableEntries="%SecurityProxyGroupKeyTableEntries%" DynamicTableManagement="false" Linkable="false" MinEtsVersion="6.0" ContextHelpFile="%FILE-HELP-de%" IconFile="%FILE-ICONS%" IPConfig="Custom" ApplicationNumber="0" ApplicationVersion="0" ReplacesVersions="0" AdditionalAddressesCount="%Tunnelcount%" MaxTunnelingUserEntries="%Tunnelcount%">
|
||||||
|
<Static>
|
||||||
|
<Code>
|
||||||
|
<AbsoluteSegment Id="%AID%_AS-0100" Address="256" Size="256" />
|
||||||
|
</Code>
|
||||||
|
<ParameterTypes>
|
||||||
|
<op:include href="deps/OGM-Common/src/Common.share.xml" xpath="//ParameterTypes/ParameterType" prefix="BASE" />
|
||||||
|
<op:includetemplate href="%share%" xpath="//ApplicationProgram/Static/ParameterTypes/ParameterType" prefix="%prefix%" />
|
||||||
|
</ParameterTypes>
|
||||||
|
<Parameters>
|
||||||
|
<op:include href="deps/OGM-Common/src/Common.Router.share.xml" xpath="//ApplicationProgram/Static/Parameters/Parameter|//ApplicationProgram/Static/Parameters/Union" type="parameter" prefix="BASE" />
|
||||||
|
<op:includetemplate href="%share%" xpath="//ApplicationProgram/Static/Parameters/Parameter|//ApplicationProgram/Static/Parameters/Union" type="parameter" prefix="%prefix%" />
|
||||||
|
<op:includetemplate href="%templ%" xpath="//ApplicationProgram/Static/Parameters/Parameter|//ApplicationProgram/Static/Parameters/Union" type="template" prefix="%prefix%" />
|
||||||
|
</Parameters>
|
||||||
|
<ParameterRefs>
|
||||||
|
<op:include href="deps/OGM-Common/src/Common.Router.share.xml" xpath="//ApplicationProgram/Static/ParameterRefs/ParameterRef" prefix="BASE" />
|
||||||
|
<op:includetemplate href="%share%" xpath="//ApplicationProgram/Static/ParameterRefs/ParameterRef" prefix="%prefix%" />
|
||||||
|
<op:includetemplate href="%templ%" xpath="//ApplicationProgram/Static/ParameterRefs/ParameterRef" type="template" prefix="%prefix%" />
|
||||||
|
</ParameterRefs>
|
||||||
|
<ParameterCalculations>
|
||||||
|
<op:include href="deps/OGM-Common/src/Common.share.xml" xpath="//ApplicationProgram/Static/ParameterCalculations/ParameterCalculation" prefix="BASE" />
|
||||||
|
<op:includetemplate href="%share%" xpath="//ApplicationProgram/Static/ParameterCalculations/ParameterCalculation" prefix="%prefix%" />
|
||||||
|
<op:includetemplate href="%templ%" xpath="//ApplicationProgram/Static/ParameterCalculations/ParameterCalculation" type="template" prefix="%prefix%" />
|
||||||
|
</ParameterCalculations>
|
||||||
|
<ParameterValidations>
|
||||||
|
<op:include href="deps/OGM-Common/src/Common.share.xml" xpath="//ApplicationProgram/Static/ParameterValidations/ParameterValidation" prefix="BASE" />
|
||||||
|
<op:includetemplate href="%share%" xpath="//ApplicationProgram/Static/ParameterValidations/ParameterValidation" prefix="%prefix%" />
|
||||||
|
<op:includetemplate href="%templ%" xpath="//ApplicationProgram/Static/ParameterValidations/ParameterValidation" type="template" prefix="%prefix%" />
|
||||||
|
</ParameterValidations>
|
||||||
|
<AddressTable MaxEntries="2047" />
|
||||||
|
<AssociationTable MaxEntries="2047" />
|
||||||
|
<LoadProcedures>
|
||||||
|
<LoadProcedure MergeId="1">
|
||||||
|
<LdCtrlCompareProp InlineData="00FA" ObjIdx="0" PropId="12">
|
||||||
|
<OnError Cause="CompareMismatch" MessageRef="%AID%_M-1" />
|
||||||
|
</LdCtrlCompareProp>
|
||||||
|
<LdCtrlCompareProp InlineData="%VersionCheck%" ObjIdx="0" PropId="78">
|
||||||
|
<OnError Cause="CompareMismatch" MessageRef="%AID%_M-2" />
|
||||||
|
</LdCtrlCompareProp>
|
||||||
|
</LoadProcedure>
|
||||||
|
<LoadProcedure MergeId="4">
|
||||||
|
<LdCtrlWriteMem Address="256" Size="256" Verify="true" />
|
||||||
|
<LdCtrlWriteProp ObjType="11" PropId="94" Count="1" Verify="true" />
|
||||||
|
<LdCtrlWriteProp ObjType="11" PropId="97" Count="%Tunnelcount%" Verify="true" />
|
||||||
|
<LdCtrlWriteProp ObjType="11" PropId="201" Count="%Tunnelcount%" Verify="true" />
|
||||||
|
<LdCtrlWriteProp ObjType="11" PropId="202" Count="%Tunnelcount%" Verify="true" />
|
||||||
|
<LdCtrlWriteProp ObjType="6" PropId="81" Count="%SecurityProxyGroupKeyTableEntries%" Verify="true" />
|
||||||
|
</LoadProcedure>
|
||||||
|
</LoadProcedures>
|
||||||
|
<Messages>
|
||||||
|
<Message Id="%AID%_M-1" Name="VersionMismatch" Text="Manufacturer identifier is incompatible." />
|
||||||
|
<Message Id="%AID%_M-2" Name="VersionMismatch" Text="Hardware type or firmware version is incompatible." />
|
||||||
|
<op:include href="deps/OGM-Common/src/Common.share.xml" xpath="//ApplicationProgram/Static/Messages/*" prefix="BASE" />
|
||||||
|
<op:includetemplate href="%share%" xpath="//ApplicationProgram/Static/Messages/*" prefix="%prefix%" />
|
||||||
|
</Messages>
|
||||||
|
<Script>
|
||||||
|
<op:include href="deps/OGM-Common/src/Common.share.xml" xpath="//ApplicationProgram/Static/Script/text()" prefix="BASE" />
|
||||||
|
<op:includetemplate href="%share%" xpath="//ApplicationProgram/Static/Script/text()" prefix="%prefix%" />
|
||||||
|
</Script>
|
||||||
|
<BusInterfaces>
|
||||||
|
<op:include href="Gateway-OAM-IP-Router.templ.xml" xpath="//BusInterfaces/BusInterface" type="template" prefix="ROUTE" />
|
||||||
|
</BusInterfaces>
|
||||||
|
<Options LineCoupler0912NewProgrammingStyle="true" MaxRoutingApduLength="66" Comparable="true" Reconstructable="true" DownloadInvisibleParameters="None" SupportsExtendedMemoryServices="true" SupportsExtendedPropertyServices="true" SupportsIpSystemBroadcast="true" />
|
||||||
|
</Static>
|
||||||
|
<ModuleDefs>
|
||||||
|
<op:include href="deps/OGM-Common/src/Common.share.xml" xpath="//ApplicationProgram/ModuleDefs/*" prefix="BASE" />
|
||||||
|
<op:includetemplate href="%share%" xpath="//ApplicationProgram/ModuleDefs/*" prefix="%prefix%" />
|
||||||
|
<op:includetemplate href="%templ%" xpath="//ApplicationProgram/ModuleDefs/*" type="template" prefix="%prefix%" />
|
||||||
|
</ModuleDefs>
|
||||||
|
<Dynamic>
|
||||||
|
<op:include href="deps/OGM-Common/src/Common.Router.share.xml" xpath="//Dynamic/*" prefix="BASE" />
|
||||||
|
<op:include href="deps/OFM-Network/src/Network.share.xml" xpath="//Dynamic/*" prefix="NET" />
|
||||||
|
<op:include href="Gateway-OAM-IP-Router.share.xml" xpath="//Dynamic/*" prefix="ROUTE" />
|
||||||
|
</Dynamic>
|
||||||
|
</ApplicationProgram>
|
||||||
|
</ApplicationPrograms>
|
||||||
|
<Baggages>
|
||||||
|
<op:include href="deps/OGM-Common/src/Common.share.xml" xpath="//Baggages/*" prefix="BASE" />
|
||||||
|
<op:includetemplate href="%share%" xpath="//Manufacturer/Baggages/*" prefix="%prefix%" />
|
||||||
|
</Baggages>
|
||||||
|
<Hardware>
|
||||||
|
<Hardware Id="%HardwareId%" Name="OpenKNX-%HardwareName%%BuildSuffix%" SerialNumber="%SerialNumber%" VersionNumber="1" BusCurrent="%BusCurrent%" HasIndividualAddress="true" IsCoupler="true" HasApplicationProgram="true" IsIPEnabled="1">
|
||||||
|
<Products>
|
||||||
|
<Product Id="%ProductId%" Text="OpenKNX: %ProductName%%BuildSuffixText%" OrderNumber="%OrderNumber%" IsRailMounted="%IsRailMounted%" WidthInMillimeter="18" DefaultLanguage="en-US">
|
||||||
|
<RegistrationInfo RegistrationStatus="Registered" />
|
||||||
|
</Product>
|
||||||
|
</Products>
|
||||||
|
<Hardware2Programs>
|
||||||
|
<Hardware2Program Id="%Hardware2ProgramId%" MediumTypes="%MediumTypes%" CouplerCapabilities="SecurityProxy">
|
||||||
|
<ApplicationProgramRef RefId="%AID%" />
|
||||||
|
<RegistrationInfo RegistrationStatus="Registered" RegistrationNumber="0001/%HardwareVersionEncoded%1" />
|
||||||
|
</Hardware2Program>
|
||||||
|
</Hardware2Programs>
|
||||||
|
</Hardware>
|
||||||
|
</Hardware>
|
||||||
|
<Languages>
|
||||||
|
<Language Identifier="zh-CN">
|
||||||
|
<TranslationUnit RefId="%AID%">
|
||||||
|
<TranslationElement RefId="%AID%">
|
||||||
|
<Translation AttributeName="Name" Text="网关 OAM IP 路由器%BuildSuffix%" />
|
||||||
|
</TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_M-1">
|
||||||
|
<Translation AttributeName="Text" Text="制造商标识不兼容。" />
|
||||||
|
</TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_M-2">
|
||||||
|
<Translation AttributeName="Text" Text="硬件类型或固件版本不兼容。" />
|
||||||
|
</TranslationElement>
|
||||||
|
<op:include href="Gateway-OAM-IP-Router.share.xml" xpath="//Manufacturer/Languages/Language[@Identifier='zh-CN']/TranslationUnit/TranslationElement" prefix="ROUTE" />
|
||||||
|
<op:include href="Gateway-Dependency-Translations.xml" xpath="//Manufacturer/Languages/Language[@Identifier='zh-CN']/TranslationUnit/TranslationElement" />
|
||||||
|
<TranslationElement RefId="%AID%_BI-1"><Translation AttributeName="Text" Text="隧道 1" /></TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_P-9901001"><Translation AttributeName="Text" Text="预留隧道 1" /></TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_P-9901002"><Translation AttributeName="Text" Text="隧道 1 的 IP 地址" /></TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_P-9901003"><Translation AttributeName="Text" Text="隧道忙碌时的行为" /></TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_BI-2"><Translation AttributeName="Text" Text="隧道 2" /></TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_P-9902001"><Translation AttributeName="Text" Text="预留隧道 2" /></TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_P-9902002"><Translation AttributeName="Text" Text="隧道 2 的 IP 地址" /></TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_P-9902003"><Translation AttributeName="Text" Text="隧道忙碌时的行为" /></TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_BI-3"><Translation AttributeName="Text" Text="隧道 3" /></TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_P-9903001"><Translation AttributeName="Text" Text="预留隧道 3" /></TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_P-9903002"><Translation AttributeName="Text" Text="隧道 3 的 IP 地址" /></TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_P-9903003"><Translation AttributeName="Text" Text="隧道忙碌时的行为" /></TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_BI-4"><Translation AttributeName="Text" Text="隧道 4" /></TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_P-9904001"><Translation AttributeName="Text" Text="预留隧道 4" /></TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_P-9904002"><Translation AttributeName="Text" Text="隧道 4 的 IP 地址" /></TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_P-9904003"><Translation AttributeName="Text" Text="隧道忙碌时的行为" /></TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_BI-5"><Translation AttributeName="Text" Text="隧道 5" /></TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_P-9905001"><Translation AttributeName="Text" Text="预留隧道 5" /></TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_P-9905002"><Translation AttributeName="Text" Text="隧道 5 的 IP 地址" /></TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_P-9905003"><Translation AttributeName="Text" Text="隧道忙碌时的行为" /></TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_BI-6"><Translation AttributeName="Text" Text="隧道 6" /></TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_P-9906001"><Translation AttributeName="Text" Text="预留隧道 6" /></TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_P-9906002"><Translation AttributeName="Text" Text="隧道 6 的 IP 地址" /></TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_P-9906003"><Translation AttributeName="Text" Text="隧道忙碌时的行为" /></TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_BI-7"><Translation AttributeName="Text" Text="隧道 7" /></TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_P-9907001"><Translation AttributeName="Text" Text="预留隧道 7" /></TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_P-9907002"><Translation AttributeName="Text" Text="隧道 7 的 IP 地址" /></TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_P-9907003"><Translation AttributeName="Text" Text="隧道忙碌时的行为" /></TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_BI-8"><Translation AttributeName="Text" Text="隧道 8" /></TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_P-9908001"><Translation AttributeName="Text" Text="预留隧道 8" /></TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_P-9908002"><Translation AttributeName="Text" Text="隧道 8 的 IP 地址" /></TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_P-9908003"><Translation AttributeName="Text" Text="隧道忙碌时的行为" /></TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_BI-9"><Translation AttributeName="Text" Text="隧道 9" /></TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_P-9909001"><Translation AttributeName="Text" Text="预留隧道 9" /></TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_P-9909002"><Translation AttributeName="Text" Text="隧道 9 的 IP 地址" /></TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_P-9909003"><Translation AttributeName="Text" Text="隧道忙碌时的行为" /></TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_BI-10"><Translation AttributeName="Text" Text="隧道 10" /></TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_P-9910001"><Translation AttributeName="Text" Text="预留隧道 10" /></TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_P-9910002"><Translation AttributeName="Text" Text="隧道 10 的 IP 地址" /></TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_P-9910003"><Translation AttributeName="Text" Text="隧道忙碌时的行为" /></TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_BI-11"><Translation AttributeName="Text" Text="隧道 11" /></TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_P-9911001"><Translation AttributeName="Text" Text="预留隧道 11" /></TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_P-9911002"><Translation AttributeName="Text" Text="隧道 11 的 IP 地址" /></TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_P-9911003"><Translation AttributeName="Text" Text="隧道忙碌时的行为" /></TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_BI-12"><Translation AttributeName="Text" Text="隧道 12" /></TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_P-9912001"><Translation AttributeName="Text" Text="预留隧道 12" /></TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_P-9912002"><Translation AttributeName="Text" Text="隧道 12 的 IP 地址" /></TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_P-9912003"><Translation AttributeName="Text" Text="隧道忙碌时的行为" /></TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_BI-13"><Translation AttributeName="Text" Text="隧道 13" /></TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_P-9913001"><Translation AttributeName="Text" Text="预留隧道 13" /></TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_P-9913002"><Translation AttributeName="Text" Text="隧道 13 的 IP 地址" /></TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_P-9913003"><Translation AttributeName="Text" Text="隧道忙碌时的行为" /></TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_BI-14"><Translation AttributeName="Text" Text="隧道 14" /></TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_P-9914001"><Translation AttributeName="Text" Text="预留隧道 14" /></TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_P-9914002"><Translation AttributeName="Text" Text="隧道 14 的 IP 地址" /></TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_P-9914003"><Translation AttributeName="Text" Text="隧道忙碌时的行为" /></TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_BI-15"><Translation AttributeName="Text" Text="隧道 15" /></TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_P-9915001"><Translation AttributeName="Text" Text="预留隧道 15" /></TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_P-9915002"><Translation AttributeName="Text" Text="隧道 15 的 IP 地址" /></TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_P-9915003"><Translation AttributeName="Text" Text="隧道忙碌时的行为" /></TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_BI-16"><Translation AttributeName="Text" Text="隧道 16" /></TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_P-9916001"><Translation AttributeName="Text" Text="预留隧道 16" /></TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_P-9916002"><Translation AttributeName="Text" Text="隧道 16 的 IP 地址" /></TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_P-9916003"><Translation AttributeName="Text" Text="隧道忙碌时的行为" /></TranslationElement>
|
||||||
|
</TranslationUnit>
|
||||||
|
</Language>
|
||||||
|
<Language Identifier="de-DE">
|
||||||
|
<TranslationUnit RefId="%AID%">
|
||||||
|
<TranslationElement RefId="%AID%">
|
||||||
|
<Translation AttributeName="Name" Text="Gateway OAM IP-Router%BuildSuffix%" />
|
||||||
|
</TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_M-1">
|
||||||
|
<Translation AttributeName="Text" Text="Herstellerkennung ist inkompatibel." />
|
||||||
|
</TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_M-2">
|
||||||
|
<Translation AttributeName="Text" Text="Hardwaretyp oder Firmwareversion ist inkompatibel." />
|
||||||
|
</TranslationElement>
|
||||||
|
<op:include href="Gateway-OAM-IP-Router.share.xml" xpath="//Manufacturer/Languages/Language[@Identifier='de-DE']/TranslationUnit/TranslationElement" prefix="ROUTE" />
|
||||||
|
<op:include href="Gateway-Dependency-Translations.xml" xpath="//Manufacturer/Languages/Language[@Identifier='de-DE']/TranslationUnit/TranslationElement" />
|
||||||
|
<TranslationElement RefId="%AID%_BI-1"><Translation AttributeName="Text" Text="Tunnel 1" /></TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_P-9901001"><Translation AttributeName="Text" Text="Tunnel 1 reservieren" /></TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_P-9901002"><Translation AttributeName="Text" Text="IP-Adresse für Tunnel 1" /></TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_P-9901003"><Translation AttributeName="Text" Text="Verhalten bei belegtem Tunnel" /></TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_BI-2"><Translation AttributeName="Text" Text="Tunnel 2" /></TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_P-9902001"><Translation AttributeName="Text" Text="Tunnel 2 reservieren" /></TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_P-9902002"><Translation AttributeName="Text" Text="IP-Adresse für Tunnel 2" /></TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_P-9902003"><Translation AttributeName="Text" Text="Verhalten bei belegtem Tunnel" /></TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_BI-3"><Translation AttributeName="Text" Text="Tunnel 3" /></TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_P-9903001"><Translation AttributeName="Text" Text="Tunnel 3 reservieren" /></TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_P-9903002"><Translation AttributeName="Text" Text="IP-Adresse für Tunnel 3" /></TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_P-9903003"><Translation AttributeName="Text" Text="Verhalten bei belegtem Tunnel" /></TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_BI-4"><Translation AttributeName="Text" Text="Tunnel 4" /></TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_P-9904001"><Translation AttributeName="Text" Text="Tunnel 4 reservieren" /></TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_P-9904002"><Translation AttributeName="Text" Text="IP-Adresse für Tunnel 4" /></TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_P-9904003"><Translation AttributeName="Text" Text="Verhalten bei belegtem Tunnel" /></TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_BI-5"><Translation AttributeName="Text" Text="Tunnel 5" /></TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_P-9905001"><Translation AttributeName="Text" Text="Tunnel 5 reservieren" /></TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_P-9905002"><Translation AttributeName="Text" Text="IP-Adresse für Tunnel 5" /></TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_P-9905003"><Translation AttributeName="Text" Text="Verhalten bei belegtem Tunnel" /></TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_BI-6"><Translation AttributeName="Text" Text="Tunnel 6" /></TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_P-9906001"><Translation AttributeName="Text" Text="Tunnel 6 reservieren" /></TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_P-9906002"><Translation AttributeName="Text" Text="IP-Adresse für Tunnel 6" /></TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_P-9906003"><Translation AttributeName="Text" Text="Verhalten bei belegtem Tunnel" /></TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_BI-7"><Translation AttributeName="Text" Text="Tunnel 7" /></TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_P-9907001"><Translation AttributeName="Text" Text="Tunnel 7 reservieren" /></TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_P-9907002"><Translation AttributeName="Text" Text="IP-Adresse für Tunnel 7" /></TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_P-9907003"><Translation AttributeName="Text" Text="Verhalten bei belegtem Tunnel" /></TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_BI-8"><Translation AttributeName="Text" Text="Tunnel 8" /></TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_P-9908001"><Translation AttributeName="Text" Text="Tunnel 8 reservieren" /></TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_P-9908002"><Translation AttributeName="Text" Text="IP-Adresse für Tunnel 8" /></TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_P-9908003"><Translation AttributeName="Text" Text="Verhalten bei belegtem Tunnel" /></TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_BI-9"><Translation AttributeName="Text" Text="Tunnel 9" /></TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_P-9909001"><Translation AttributeName="Text" Text="Tunnel 9 reservieren" /></TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_P-9909002"><Translation AttributeName="Text" Text="IP-Adresse für Tunnel 9" /></TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_P-9909003"><Translation AttributeName="Text" Text="Verhalten bei belegtem Tunnel" /></TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_BI-10"><Translation AttributeName="Text" Text="Tunnel 10" /></TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_P-9910001"><Translation AttributeName="Text" Text="Tunnel 10 reservieren" /></TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_P-9910002"><Translation AttributeName="Text" Text="IP-Adresse für Tunnel 10" /></TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_P-9910003"><Translation AttributeName="Text" Text="Verhalten bei belegtem Tunnel" /></TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_BI-11"><Translation AttributeName="Text" Text="Tunnel 11" /></TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_P-9911001"><Translation AttributeName="Text" Text="Tunnel 11 reservieren" /></TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_P-9911002"><Translation AttributeName="Text" Text="IP-Adresse für Tunnel 11" /></TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_P-9911003"><Translation AttributeName="Text" Text="Verhalten bei belegtem Tunnel" /></TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_BI-12"><Translation AttributeName="Text" Text="Tunnel 12" /></TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_P-9912001"><Translation AttributeName="Text" Text="Tunnel 12 reservieren" /></TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_P-9912002"><Translation AttributeName="Text" Text="IP-Adresse für Tunnel 12" /></TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_P-9912003"><Translation AttributeName="Text" Text="Verhalten bei belegtem Tunnel" /></TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_BI-13"><Translation AttributeName="Text" Text="Tunnel 13" /></TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_P-9913001"><Translation AttributeName="Text" Text="Tunnel 13 reservieren" /></TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_P-9913002"><Translation AttributeName="Text" Text="IP-Adresse für Tunnel 13" /></TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_P-9913003"><Translation AttributeName="Text" Text="Verhalten bei belegtem Tunnel" /></TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_BI-14"><Translation AttributeName="Text" Text="Tunnel 14" /></TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_P-9914001"><Translation AttributeName="Text" Text="Tunnel 14 reservieren" /></TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_P-9914002"><Translation AttributeName="Text" Text="IP-Adresse für Tunnel 14" /></TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_P-9914003"><Translation AttributeName="Text" Text="Verhalten bei belegtem Tunnel" /></TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_BI-15"><Translation AttributeName="Text" Text="Tunnel 15" /></TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_P-9915001"><Translation AttributeName="Text" Text="Tunnel 15 reservieren" /></TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_P-9915002"><Translation AttributeName="Text" Text="IP-Adresse für Tunnel 15" /></TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_P-9915003"><Translation AttributeName="Text" Text="Verhalten bei belegtem Tunnel" /></TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_BI-16"><Translation AttributeName="Text" Text="Tunnel 16" /></TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_P-9916001"><Translation AttributeName="Text" Text="Tunnel 16 reservieren" /></TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_P-9916002"><Translation AttributeName="Text" Text="IP-Adresse für Tunnel 16" /></TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_P-9916003"><Translation AttributeName="Text" Text="Verhalten bei belegtem Tunnel" /></TranslationElement>
|
||||||
|
</TranslationUnit>
|
||||||
|
</Language>
|
||||||
|
<Language Identifier="ja-JP">
|
||||||
|
<TranslationUnit RefId="%AID%">
|
||||||
|
<TranslationElement RefId="%AID%">
|
||||||
|
<Translation AttributeName="Name" Text="ゲートウェイ OAM IP ルーター%BuildSuffix%" />
|
||||||
|
</TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_M-1">
|
||||||
|
<Translation AttributeName="Text" Text="メーカー識別子に互換性がありません。" />
|
||||||
|
</TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_M-2">
|
||||||
|
<Translation AttributeName="Text" Text="ハードウェアタイプまたはファームウェアバージョンに互換性がありません。" />
|
||||||
|
</TranslationElement>
|
||||||
|
<op:include href="Gateway-OAM-IP-Router.share.xml" xpath="//Manufacturer/Languages/Language[@Identifier='ja-JP']/TranslationUnit/TranslationElement" prefix="ROUTE" />
|
||||||
|
<op:include href="Gateway-Dependency-Translations.xml" xpath="//Manufacturer/Languages/Language[@Identifier='ja-JP']/TranslationUnit/TranslationElement" />
|
||||||
|
<TranslationElement RefId="%AID%_BI-1"><Translation AttributeName="Text" Text="トンネル 1" /></TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_P-9901001"><Translation AttributeName="Text" Text="トンネル 1 を予約" /></TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_P-9901002"><Translation AttributeName="Text" Text="トンネル 1 の IP アドレス" /></TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_P-9901003"><Translation AttributeName="Text" Text="トンネル使用中の動作" /></TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_BI-2"><Translation AttributeName="Text" Text="トンネル 2" /></TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_P-9902001"><Translation AttributeName="Text" Text="トンネル 2 を予約" /></TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_P-9902002"><Translation AttributeName="Text" Text="トンネル 2 の IP アドレス" /></TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_P-9902003"><Translation AttributeName="Text" Text="トンネル使用中の動作" /></TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_BI-3"><Translation AttributeName="Text" Text="トンネル 3" /></TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_P-9903001"><Translation AttributeName="Text" Text="トンネル 3 を予約" /></TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_P-9903002"><Translation AttributeName="Text" Text="トンネル 3 の IP アドレス" /></TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_P-9903003"><Translation AttributeName="Text" Text="トンネル使用中の動作" /></TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_BI-4"><Translation AttributeName="Text" Text="トンネル 4" /></TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_P-9904001"><Translation AttributeName="Text" Text="トンネル 4 を予約" /></TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_P-9904002"><Translation AttributeName="Text" Text="トンネル 4 の IP アドレス" /></TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_P-9904003"><Translation AttributeName="Text" Text="トンネル使用中の動作" /></TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_BI-5"><Translation AttributeName="Text" Text="トンネル 5" /></TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_P-9905001"><Translation AttributeName="Text" Text="トンネル 5 を予約" /></TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_P-9905002"><Translation AttributeName="Text" Text="トンネル 5 の IP アドレス" /></TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_P-9905003"><Translation AttributeName="Text" Text="トンネル使用中の動作" /></TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_BI-6"><Translation AttributeName="Text" Text="トンネル 6" /></TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_P-9906001"><Translation AttributeName="Text" Text="トンネル 6 を予約" /></TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_P-9906002"><Translation AttributeName="Text" Text="トンネル 6 の IP アドレス" /></TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_P-9906003"><Translation AttributeName="Text" Text="トンネル使用中の動作" /></TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_BI-7"><Translation AttributeName="Text" Text="トンネル 7" /></TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_P-9907001"><Translation AttributeName="Text" Text="トンネル 7 を予約" /></TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_P-9907002"><Translation AttributeName="Text" Text="トンネル 7 の IP アドレス" /></TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_P-9907003"><Translation AttributeName="Text" Text="トンネル使用中の動作" /></TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_BI-8"><Translation AttributeName="Text" Text="トンネル 8" /></TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_P-9908001"><Translation AttributeName="Text" Text="トンネル 8 を予約" /></TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_P-9908002"><Translation AttributeName="Text" Text="トンネル 8 の IP アドレス" /></TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_P-9908003"><Translation AttributeName="Text" Text="トンネル使用中の動作" /></TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_BI-9"><Translation AttributeName="Text" Text="トンネル 9" /></TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_P-9909001"><Translation AttributeName="Text" Text="トンネル 9 を予約" /></TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_P-9909002"><Translation AttributeName="Text" Text="トンネル 9 の IP アドレス" /></TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_P-9909003"><Translation AttributeName="Text" Text="トンネル使用中の動作" /></TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_BI-10"><Translation AttributeName="Text" Text="トンネル 10" /></TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_P-9910001"><Translation AttributeName="Text" Text="トンネル 10 を予約" /></TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_P-9910002"><Translation AttributeName="Text" Text="トンネル 10 の IP アドレス" /></TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_P-9910003"><Translation AttributeName="Text" Text="トンネル使用中の動作" /></TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_BI-11"><Translation AttributeName="Text" Text="トンネル 11" /></TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_P-9911001"><Translation AttributeName="Text" Text="トンネル 11 を予約" /></TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_P-9911002"><Translation AttributeName="Text" Text="トンネル 11 の IP アドレス" /></TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_P-9911003"><Translation AttributeName="Text" Text="トンネル使用中の動作" /></TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_BI-12"><Translation AttributeName="Text" Text="トンネル 12" /></TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_P-9912001"><Translation AttributeName="Text" Text="トンネル 12 を予約" /></TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_P-9912002"><Translation AttributeName="Text" Text="トンネル 12 の IP アドレス" /></TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_P-9912003"><Translation AttributeName="Text" Text="トンネル使用中の動作" /></TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_BI-13"><Translation AttributeName="Text" Text="トンネル 13" /></TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_P-9913001"><Translation AttributeName="Text" Text="トンネル 13 を予約" /></TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_P-9913002"><Translation AttributeName="Text" Text="トンネル 13 の IP アドレス" /></TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_P-9913003"><Translation AttributeName="Text" Text="トンネル使用中の動作" /></TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_BI-14"><Translation AttributeName="Text" Text="トンネル 14" /></TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_P-9914001"><Translation AttributeName="Text" Text="トンネル 14 を予約" /></TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_P-9914002"><Translation AttributeName="Text" Text="トンネル 14 の IP アドレス" /></TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_P-9914003"><Translation AttributeName="Text" Text="トンネル使用中の動作" /></TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_BI-15"><Translation AttributeName="Text" Text="トンネル 15" /></TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_P-9915001"><Translation AttributeName="Text" Text="トンネル 15 を予約" /></TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_P-9915002"><Translation AttributeName="Text" Text="トンネル 15 の IP アドレス" /></TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_P-9915003"><Translation AttributeName="Text" Text="トンネル使用中の動作" /></TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_BI-16"><Translation AttributeName="Text" Text="トンネル 16" /></TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_P-9916001"><Translation AttributeName="Text" Text="トンネル 16 を予約" /></TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_P-9916002"><Translation AttributeName="Text" Text="トンネル 16 の IP アドレス" /></TranslationElement>
|
||||||
|
<TranslationElement RefId="%AID%_P-9916003"><Translation AttributeName="Text" Text="トンネル使用中の動作" /></TranslationElement>
|
||||||
|
</TranslationUnit>
|
||||||
|
</Language>
|
||||||
|
</Languages>
|
||||||
|
</Manufacturer>
|
||||||
|
</ManufacturerData>
|
||||||
|
</KNX>
|
||||||
@@ -0,0 +1,55 @@
|
|||||||
|
# Gateway OAM IP Router KNX Product XML
|
||||||
|
|
||||||
|
This folder contains the gateway-owned OpenKNXproducer source for the OAM-compatible BAU091A KNX/IP Router persona.
|
||||||
|
|
||||||
|
The source is derived from the upstream OpenKNX OAM-IP-Router database and merges the secure application metadata used by OAM-AccessControl:
|
||||||
|
|
||||||
|
- Manufacturer: `0x00FA`
|
||||||
|
- Application: `0xA11F`
|
||||||
|
- Version: `0x07`
|
||||||
|
- Mask: `MV-091A`
|
||||||
|
- Tunnels: `16`
|
||||||
|
- Security: `IsSecureEnabled="true"`
|
||||||
|
- Default language: `en-US`
|
||||||
|
- Translations: `zh-CN`, `de-DE`, `ja-JP`
|
||||||
|
|
||||||
|
The XML keeps the upstream router/coupler shape and absolute memory segment while adding KNXnet/IP Secure download hooks for:
|
||||||
|
|
||||||
|
- OT-11 PID 94, `PID_SECURED_SERVICE_FAMILIES`
|
||||||
|
- OT-11 PID 97, `PID_TUNNELLING_USERS`
|
||||||
|
- OT-6 PID 81, `PID_SECURITY_PROXY_GRP_KEY_TABLE`
|
||||||
|
|
||||||
|
The secure proxy capability is advertised with `CouplerCapabilities="SecurityProxy"` on `Hardware2Program` and `MaxSecurityProxyGroupKeyTableEntries` on the application program, matching the secure proxy-enabled ETS database shape.
|
||||||
|
|
||||||
|
The OpenKNX module dependencies needed by this producer source are vendored under `deps/` so generation does not require an external OpenKNX checkout:
|
||||||
|
|
||||||
|
- `deps/OGM-Common/` provides `Common.share.xml`, `Common.Router.share.xml`, `InfoLed.part.xml`, `Common.script.js`, `library.json`, and producer baggage assets.
|
||||||
|
- `deps/OFM-Network/` provides `Network.share.xml`, `Network.script.js`, `library.json`, and producer baggage assets.
|
||||||
|
|
||||||
|
Dependency strings are localized by `Gateway-Dependency-Translations.xml`. Dependency context-help documents are kept with the vendored modules in German plus translated English, Chinese, and Japanese help folders; the generated application uses the English help source as its default context help through OpenKNXproducer's legacy context-help baggage placeholder. OpenKNXproducer still emits that selected context-help baggage with its legacy `Help_de.zip` generated name, so keep the `Help_en.zip` source mapped to the `%FILE-HELP-de%` placeholder unless producer support for language-specific context-help baggage changes.
|
||||||
|
|
||||||
|
The runtime identity must stay synchronized with `gateway/components/gateway_knx/include/gateway_knx_internal.h` and the OAM router Kconfig defaults in `gateway/apps/gateway/main/Kconfig.projbuild`.
|
||||||
|
|
||||||
|
## Validation
|
||||||
|
|
||||||
|
Run a well-formed XML check from the repository root:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
xmllint --noout \
|
||||||
|
gateway/components/gateway_knx/oam_knxprod/*.xml \
|
||||||
|
gateway/components/gateway_knx/oam_knxprod/deps/OGM-Common/src/*.xml \
|
||||||
|
gateway/components/gateway_knx/oam_knxprod/deps/OFM-Network/src/*.xml
|
||||||
|
```
|
||||||
|
|
||||||
|
Then run OpenKNXproducer with `Gateway-OAM-IP-Router.xml` and import the generated product database into ETS. ETS validation should confirm the router imports as a secure-capable KNX/IP router, exposes 16 tunneling interfaces, and supports secure tunneling plus security proxy table download/verify.
|
||||||
|
|
||||||
|
For a local sanity check without ETS or the KNX XSD support folder installed, run:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
OpenKNXproducer create --NoXsd \
|
||||||
|
-h /tmp/gateway_oam_knxprod.h \
|
||||||
|
-o /tmp/Gateway-OAM-IP-Router.knxprod \
|
||||||
|
gateway/components/gateway_knx/oam_knxprod/Gateway-OAM-IP-Router.xml
|
||||||
|
```
|
||||||
|
|
||||||
|
This verifies OpenKNXproducer include expansion, generated IDs, translation references, and internal sanity checks. A full `.knxprod` export still requires ETS on the machine running OpenKNXproducer.
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
{
|
||||||
|
"name": "OFM-Network",
|
||||||
|
"version": "0.5.4",
|
||||||
|
"dependencies": {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
+4
@@ -0,0 +1,4 @@
|
|||||||
|
### Allgemein
|
||||||
|
|
||||||
|
In diesem Abschnitt werden die Basiseinstellungen und verfügbaren Dienste festgelegt.
|
||||||
|
|
||||||
+7
@@ -0,0 +1,7 @@
|
|||||||
|
### Dokumentation
|
||||||
|
|
||||||
|
|
||||||
|
Eine vollständige Applikationsbeschreibung ist unter folgendem Link verfügbar: https://github.com/openknx/OFM-Network/blob/v1/doc/Applikationsbeschreibung-Netzwerk.md
|
||||||
|
|
||||||
|
Über die Netzwerkeinstellungen kann nicht nur die IP-Adresse des Geräts angepasst werden, sondern es können auch verschiedene Dienste ein- oder ausgeschaltet werden. Dazu gehören z. B. der NTP-Client zum Abrufen der aktuellen Zeit, mDNS für das automatisierte Auffinden von OpenKNX-Geräten sowie die Möglichkeit, die Geräte-Firmware per Netzwerk zu aktualisieren.
|
||||||
|
|
||||||
+4
@@ -0,0 +1,4 @@
|
|||||||
|
### Erweitere Einstellungen
|
||||||
|
|
||||||
|
In diesem Abschnitt werden Einstellungen vorgenommen die vorwiegen von Netzwerkexperten benötigt werden.
|
||||||
|
|
||||||
@@ -0,0 +1,4 @@
|
|||||||
|
### Webserver
|
||||||
|
|
||||||
|
Hier kann später ein Webserver aktiviert werden, der dann über den Browser aufgerufen werden kann. Diese Funktion ist derzeit noch nicht integriert und dient aktuell nur als Platzhalter.
|
||||||
|
|
||||||
+4
@@ -0,0 +1,4 @@
|
|||||||
|
### Hostname
|
||||||
|
|
||||||
|
Der Hostname wird automatisch aus der Seriennummer generiert (OpenKNX-XXXXXXXX) und erfordert in der Regel keine Anpassung. Sollte jedoch eine individuelle Anpassung gewünscht sein, darf die Länge von 24 Zeichen nicht überschritten werden. Darüber hinaus sind nur Buchstaben, Zahlen und Bindestriche erlaubt. Der Hostname muss zudem mit einem Buchstaben beginnen und darf nicht mit einem Bindestrich enden.
|
||||||
|
|
||||||
+6
@@ -0,0 +1,6 @@
|
|||||||
|
### IP-Adresse
|
||||||
|
|
||||||
|
In diesem Eingabeformular kannst du entscheiden, ob die IP-Adresse dynamisch durch einen DHCP-Server zugewiesen oder manuell festgelegt werden soll. Bei manueller Konfiguration sind neben der IP-Adresse auch die Netzmaske, ein Standardgateway (Router) und ein Nameserver (DNS) erforderlich.
|
||||||
|
|
||||||
|
**Hinweis**: Es wird empfohlen, die DHCP-Einstellungen beizubehalten und stattdessen eine feste IP-Adresse direkt im Router zuzuweisen. Dies liegt daran, dass die Netzwerkeinstellungen nur im programmierten Zustand gelten. Nach einem Update kann das Gerät beispielsweise wieder in den DHCP-Modus wechseln, bis es erneut programmiert wird.
|
||||||
|
|
||||||
+7
@@ -0,0 +1,7 @@
|
|||||||
|
### LAN-Modus
|
||||||
|
|
||||||
|
|
||||||
|
Wähle den gewünschten Modus für die LAN-Schnittstelle aus. Die Auswahl des 10 MBit/s Modus kann genutzt werden, um den Stromverbrauch zu reduzieren.
|
||||||
|
|
||||||
|
**Hinweis**: In neueren Switches mit Geschwindigkeiten ab 2,5 GBit/s ist der 10 MBit/s Modus in der Regel nicht mehr vorgesehen. Es besteht daher die Möglichkeit, dass in solchen Fällen keine Verbindung hergestellt werden kann. Dennoch lohnt es sich, dies auszuprobieren, da einige Geräte diesen Modus unterstützen.
|
||||||
|
|
||||||
@@ -0,0 +1,4 @@
|
|||||||
|
### mDNS
|
||||||
|
|
||||||
|
Der mDNS Service ermöglicht das Auflösen von "Hostname.local" und kann auch später zum Auffinden von OpenKNX-Geräten im eigenen Netzwerk genutzt werden.
|
||||||
|
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
### NTP-Client
|
||||||
|
|
||||||
|
Durch das Aktivieren des NTP-Clients kann das Gerät die aktuelle Zeit zyklisch von einem Zeitserver abrufen, anstatt sie vom Bus zu beziehen. Zudem kann das Gerät auf Wunsch die aktuelle Zeit auch auf den Bus senden.
|
||||||
|
Die bisherigen Einstellungen bzw. Kommunikationsobjekte zum Abrufen der Zeit vom Bus entfallen. Stattdessen stehen drei neue Kommunikationsobjekte zur Verfügung, mit denen Zeit, Datum und beides kombiniert auf dem Bus bereitgestellt werden können.
|
||||||
|
|
||||||
|
Außerdem kann der Zeitserver (NTP-Server) angepasst werden, von dem die aktuelle Zeit bezogen wird. In der Regel ist eine Änderung nicht erforderlich, da der voreingestellte Server (pool.ntp.org) zuverlässig arbeitet und weit verbreitet ist. Dieser Server fungiert als Alias für eine Vielzahl von Zeitservern.
|
||||||
|
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
### OTA-Update
|
||||||
|
|
||||||
|
Ermöglicht eine direkte Firmwareaktualisierung, ohne den Einsatz von KNX oder einem USB-Anschluss.
|
||||||
|
|
||||||
|
* **Im Prog-Modus:** Für ein Update muss das Gerät zuvor in den Programmiermodus versetzt werden (z. B. durch Drücken der PROG-Taste).
|
||||||
|
* **Immer aktiv:** Aktiviert den dauerhaften Update-Modus für das Gerät. Wir raten von diesem Modus ab, da es schnell zu Verwechslungen zwischen Geräten kommen kann.
|
||||||
|
* **Ausgeschaltet** Deaktiviert die Möglichkeit, Updates über das Netzwerk durchzuführen.
|
||||||
|
|
||||||
+4
@@ -0,0 +1,4 @@
|
|||||||
|
### Webserver
|
||||||
|
|
||||||
|
Hier kann später der Webserver konfiguriert werden, der dann über den Browser aufgerufen werden kann. Diese Funktion ist derzeit noch nicht integriert und dient aktuell nur als Platzhalter.
|
||||||
|
|
||||||
+7
@@ -0,0 +1,7 @@
|
|||||||
|
### WiFi-Assistent
|
||||||
|
|
||||||
|
Dieser WiFi-Assistent ermöglicht das Übertragen von WiFi-Zugangsdaten auf das Gerät. Voraussetzung ist, dass die verwendete Hardware einen WiFi-Adapter verwendet. Geräte, die per IP-Netzwerk angebunden werden, müssen bereits über eine WiFi-Verbindung und somit über gültige Zugangsdaten verfügen. Der Assistent kann daher nur die bestehenden Zugangsdaten ändern. TP-Geräte können hingegen immer per Bus angepasst werden.
|
||||||
|
|
||||||
|
IP-Geräte ohne WiFi-Zugangsdaten müssen initial auf anderem Wege eingerichtet werden. Dies hängt sowohl von der Gerätesoftware als auch der verwendeten Hardware ab. Die Einrichtung per Terminal (USB) sollte immer funktionieren. Dafür muss auf der Konsole nur `wifi SSID PSK` eingegeben werden.
|
||||||
|
|
||||||
|
Bei Geräten auf Arduino-Pico-Basis können die WiFi-Zugangsdaten in der Regel zusätzlich per USB übertragen werden. Dazu muss das Gerät am Rechner angeschlossen und der Transfermodus durch einen Doppelklick auf die Prog-Taste gestartet werden. Kopiere dann eine Datei namens "WIFI.TXT" auf das Wechsellaufwerk. Die erste Zeile muss die SSID und die zweite den PSK enthalten. Danach den Modus wieder mit einem Doppelklick beenden und das Gerät neu starten.
|
||||||
+5
@@ -0,0 +1,5 @@
|
|||||||
|
### Documentation
|
||||||
|
|
||||||
|
A complete application description is available at: https://github.com/openknx/OFM-Network/blob/v1/doc/Applikationsbeschreibung-Netzwerk.md
|
||||||
|
|
||||||
|
The network settings can be used not only to adjust the device IP address, but also to enable or disable several services. These include the NTP client for retrieving the current time, mDNS for automated discovery of OpenKNX devices, and the option to update the device firmware over the network.
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
### Web Server
|
||||||
|
|
||||||
|
A web server can be enabled here in the future and then opened in a browser. This function is not currently integrated and is only a placeholder.
|
||||||
+3
@@ -0,0 +1,3 @@
|
|||||||
|
### Hostname
|
||||||
|
|
||||||
|
The hostname is generated automatically from the serial number (OpenKNX-XXXXXXXX) and normally does not need to be changed. If a custom hostname is desired, it must not exceed 24 characters. Only letters, numbers, and hyphens are allowed. The hostname must start with a letter and must not end with a hyphen.
|
||||||
+5
@@ -0,0 +1,5 @@
|
|||||||
|
### IP Address
|
||||||
|
|
||||||
|
In this form you can decide whether the IP address is assigned dynamically by a DHCP server or set manually. For manual configuration, the subnet mask, a default gateway (router), and a name server (DNS) are required in addition to the IP address.
|
||||||
|
|
||||||
|
**Note:** It is recommended to keep DHCP enabled and assign a fixed IP address directly in the router instead. Network settings only apply while the device is programmed. After an update, for example, the device may return to DHCP mode until it is programmed again.
|
||||||
+5
@@ -0,0 +1,5 @@
|
|||||||
|
### LAN Mode
|
||||||
|
|
||||||
|
Select the desired mode for the LAN interface. The 10 MBit/s mode can be used to reduce power consumption.
|
||||||
|
|
||||||
|
**Note:** Newer switches with speeds of 2.5 GBit/s and above usually no longer provide a 10 MBit/s mode. In such cases, a connection may not be established. It is still worth trying because some devices support this mode.
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
### mDNS
|
||||||
|
|
||||||
|
The mDNS service resolves "Hostname.local" and can also be used later to discover OpenKNX devices automatically in the local network.
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
### NTP Client
|
||||||
|
|
||||||
|
Enabling the NTP client allows the device to retrieve the current time cyclically from a time server instead of obtaining it from the bus. If desired, the device can also send the current time to the bus.
|
||||||
|
|
||||||
|
The previous settings and communication objects for retrieving time from the bus are no longer used. Instead, three new communication objects are available to provide time, date, or both combined on the bus.
|
||||||
|
|
||||||
|
The time server (NTP server) used to retrieve the current time can also be changed. Usually no change is required because the preset server (pool.ntp.org) works reliably and is widely used. This server is an alias for a large number of time servers.
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
### OTA Update
|
||||||
|
|
||||||
|
Allows firmware to be updated directly without using KNX or a USB connection.
|
||||||
|
|
||||||
|
* **In programming mode:** The device must first be put into programming mode for an update, for example by pressing the PROG button.
|
||||||
|
* **Always active:** Enables permanent update mode for the device. This mode is not recommended because devices can easily be confused with each other.
|
||||||
|
* **Disabled:** Disables updates over the network.
|
||||||
+3
@@ -0,0 +1,3 @@
|
|||||||
|
### Web Server
|
||||||
|
|
||||||
|
The web server can be configured here in the future and then opened in a browser. This function is not currently integrated and is only a placeholder.
|
||||||
+7
@@ -0,0 +1,7 @@
|
|||||||
|
### WiFi Assistant
|
||||||
|
|
||||||
|
This WiFi assistant transfers WiFi credentials to the device. The hardware must use a WiFi adapter. Devices connected through an IP network must already have a WiFi connection and valid credentials. The assistant can therefore only change existing credentials. TP devices, however, can always be adjusted over the bus.
|
||||||
|
|
||||||
|
IP devices without WiFi credentials must initially be set up in another way. This depends on both the device software and the hardware used. Setup via terminal (USB) should always work. On the console, enter `wifi SSID PSK`.
|
||||||
|
|
||||||
|
On Arduino-Pico-based devices, WiFi credentials can usually also be transferred over USB. Connect the device to the computer and start transfer mode by double-clicking the Prog button. Then copy a file named "WIFI.TXT" to the removable drive. The first line must contain the SSID and the second line the PSK. Afterwards, exit the mode with another double-click and restart the device.
|
||||||
+5
@@ -0,0 +1,5 @@
|
|||||||
|
### ドキュメント
|
||||||
|
|
||||||
|
完全なアプリケーション説明は次の場所で確認できます:https://github.com/openknx/OFM-Network/blob/v1/doc/Applikationsbeschreibung-Netzwerk.md
|
||||||
|
|
||||||
|
ネットワーク設定では、デバイスの IP アドレスを調整できるだけでなく、複数のサービスを有効または無効にできます。これには、現在時刻を取得する NTP クライアント、OpenKNX デバイスを自動検出する mDNS、ネットワーク経由でデバイスファームウェアを更新する機能が含まれます。
|
||||||
+3
@@ -0,0 +1,3 @@
|
|||||||
|
### Web サーバー
|
||||||
|
|
||||||
|
将来的にここで Web サーバーを有効化し、ブラウザーから開けるようにできます。この機能は現在まだ統合されておらず、現時点ではプレースホルダーです。
|
||||||
+3
@@ -0,0 +1,3 @@
|
|||||||
|
### ホスト名
|
||||||
|
|
||||||
|
ホスト名はシリアル番号から自動生成されます(OpenKNX-XXXXXXXX)。通常は変更不要です。カスタムホスト名を使用する場合、24 文字を超えてはいけません。使用できるのは文字、数字、ハイフンのみです。ホスト名は文字で始まり、ハイフンで終わってはいけません。
|
||||||
+5
@@ -0,0 +1,5 @@
|
|||||||
|
### IP アドレス
|
||||||
|
|
||||||
|
この入力フォームでは、IP アドレスを DHCP サーバーから動的に割り当てるか、手動で設定するかを選択できます。手動設定では、IP アドレスに加えてサブネットマスク、デフォルトゲートウェイ(ルーター)、ネームサーバー(DNS)が必要です。
|
||||||
|
|
||||||
|
**注意:** DHCP 設定を維持し、固定 IP アドレスはルーター側で割り当てることを推奨します。ネットワーク設定は、デバイスがプログラム済みの状態でのみ有効です。たとえば更新後は、再度プログラムされるまで DHCP モードに戻る場合があります。
|
||||||
+5
@@ -0,0 +1,5 @@
|
|||||||
|
### LAN モード
|
||||||
|
|
||||||
|
LAN インターフェイスの希望するモードを選択します。10 MBit/s モードは消費電力を抑えるために使用できます。
|
||||||
|
|
||||||
|
**注意:** 2.5 GBit/s 以上の速度に対応する新しいスイッチでは、通常 10 MBit/s モードが用意されていません。その場合、接続できない可能性があります。ただし、このモードをサポートするデバイスもあるため、試す価値はあります。
|
||||||
+3
@@ -0,0 +1,3 @@
|
|||||||
|
### mDNS
|
||||||
|
|
||||||
|
mDNS サービスは "Hostname.local" を解決し、後でローカルネットワーク内の OpenKNX デバイスを自動検出するためにも使用できます。
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
### NTP クライアント
|
||||||
|
|
||||||
|
NTP クライアントを有効にすると、デバイスはバスからではなく、時刻サーバーから周期的に現在時刻を取得できます。必要に応じて、現在時刻をバスへ送信することもできます。
|
||||||
|
|
||||||
|
従来の、バスから時刻を取得するための設定や通信オブジェクトは使用されなくなります。代わりに、時刻、日付、またはその両方を結合してバスに提供する 3 つの新しい通信オブジェクトが利用できます。
|
||||||
|
|
||||||
|
現在時刻を取得する時刻サーバー(NTP サーバー)も変更できます。通常は変更不要です。既定のサーバー pool.ntp.org は信頼性が高く広く使われており、多数の時刻サーバーへのエイリアスとして機能します。
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
### OTA 更新
|
||||||
|
|
||||||
|
KNX や USB 接続を使用せずに、ファームウェアを直接更新できます。
|
||||||
|
|
||||||
|
* **プログラミングモード時:** 更新するには、事前にデバイスをプログラミングモードにする必要があります。たとえば PROG ボタンを押します。
|
||||||
|
* **常に有効:** デバイスの常時更新モードを有効にします。デバイスを取り違えやすくなるため、このモードは推奨されません。
|
||||||
|
* **無効:** ネットワーク経由の更新を無効にします。
|
||||||
+3
@@ -0,0 +1,3 @@
|
|||||||
|
### Web サーバー
|
||||||
|
|
||||||
|
将来的にここで Web サーバーを設定し、ブラウザーから開けるようにできます。この機能は現在まだ統合されておらず、現時点ではプレースホルダーです。
|
||||||
+7
@@ -0,0 +1,7 @@
|
|||||||
|
### WiFi アシスタント
|
||||||
|
|
||||||
|
この WiFi アシスタントは、WiFi 認証情報をデバイスへ転送します。使用するハードウェアには WiFi アダプターが必要です。IP ネットワーク経由で接続されるデバイスは、すでに WiFi 接続と有効な認証情報を持っている必要があります。そのため、このアシスタントで変更できるのは既存の認証情報のみです。一方、TP デバイスは常にバス経由で調整できます。
|
||||||
|
|
||||||
|
WiFi 認証情報を持たない IP デバイスは、最初に別の方法でセットアップする必要があります。これはデバイスソフトウェアと使用するハードウェアの両方に依存します。ターミナル(USB)経由の設定は通常常に機能します。コンソールで `wifi SSID PSK` と入力してください。
|
||||||
|
|
||||||
|
Arduino-Pico ベースのデバイスでは、通常 USB 経由でも WiFi 認証情報を転送できます。デバイスをコンピューターに接続し、Prog ボタンをダブルクリックして転送モードを開始します。その後、"WIFI.TXT" という名前のファイルをリムーバブルドライブにコピーします。1 行目に SSID、2 行目に PSK を記載してください。最後にもう一度ダブルクリックしてモードを終了し、デバイスを再起動します。
|
||||||
+5
@@ -0,0 +1,5 @@
|
|||||||
|
### 文档
|
||||||
|
|
||||||
|
完整的应用说明可在以下地址查看:https://github.com/openknx/OFM-Network/blob/v1/doc/Applikationsbeschreibung-Netzwerk.md
|
||||||
|
|
||||||
|
网络设置不仅可用于调整设备的 IP 地址,还可启用或停用多种服务。其中包括用于获取当前时间的 NTP 客户端、用于自动发现 OpenKNX 设备的 mDNS,以及通过网络更新设备固件的功能。
|
||||||
+3
@@ -0,0 +1,3 @@
|
|||||||
|
### Web 服务器
|
||||||
|
|
||||||
|
将来可在此启用 Web 服务器,并通过浏览器访问。此功能目前尚未集成,当前仅作为占位项。
|
||||||
+3
@@ -0,0 +1,3 @@
|
|||||||
|
### 主机名
|
||||||
|
|
||||||
|
主机名会根据序列号自动生成(OpenKNX-XXXXXXXX),通常不需要调整。如果需要自定义,长度不得超过 24 个字符,并且只能包含字母、数字和连字符。主机名必须以字母开头,且不能以连字符结尾。
|
||||||
+5
@@ -0,0 +1,5 @@
|
|||||||
|
### IP 地址
|
||||||
|
|
||||||
|
在此表单中,你可以选择 IP 地址由 DHCP 服务器动态分配,或手动指定。手动配置时,除 IP 地址外,还需要子网掩码、默认网关(路由器)和名称服务器(DNS)。
|
||||||
|
|
||||||
|
**注意:** 建议保留 DHCP 设置,并在路由器中直接为设备分配固定 IP 地址。网络设置仅在设备已编程的状态下生效。例如更新后,设备可能会恢复到 DHCP 模式,直到再次编程。
|
||||||
+5
@@ -0,0 +1,5 @@
|
|||||||
|
### LAN 模式
|
||||||
|
|
||||||
|
选择 LAN 接口所需的模式。10 MBit/s 模式可用于降低功耗。
|
||||||
|
|
||||||
|
**注意:** 较新的交换机,特别是 2.5 GBit/s 及以上速度的交换机,通常不再提供 10 MBit/s 模式。在这种情况下可能无法建立连接。但仍值得尝试,因为部分设备支持该模式。
|
||||||
+3
@@ -0,0 +1,3 @@
|
|||||||
|
### mDNS
|
||||||
|
|
||||||
|
mDNS 服务可解析 "Hostname.local",之后也可用于在本地网络中自动发现 OpenKNX 设备。
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
### NTP 客户端
|
||||||
|
|
||||||
|
启用 NTP 客户端后,设备可以周期性地从时间服务器获取当前时间,而不是从总线获取。如有需要,设备也可以将当前时间发送到总线。
|
||||||
|
|
||||||
|
此前用于从总线获取时间的设置和通信对象将不再使用。取而代之的是三个新的通信对象,可在总线上提供时间、日期,或时间日期组合。
|
||||||
|
|
||||||
|
也可以调整用于获取当前时间的时间服务器(NTP 服务器)。通常不需要修改,因为预设服务器 pool.ntp.org 可靠且使用广泛。该服务器是大量时间服务器的别名。
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
### OTA 更新
|
||||||
|
|
||||||
|
允许在不使用 KNX 或 USB 连接的情况下直接更新固件。
|
||||||
|
|
||||||
|
* **编程模式下:** 更新前必须先将设备置于编程模式,例如按下 PROG 按钮。
|
||||||
|
* **始终启用:** 为设备启用永久更新模式。不建议使用该模式,因为容易混淆不同设备。
|
||||||
|
* **已禁用:** 禁用通过网络进行更新。
|
||||||
+3
@@ -0,0 +1,3 @@
|
|||||||
|
### Web 服务器
|
||||||
|
|
||||||
|
将来可在此配置 Web 服务器,并通过浏览器访问。此功能目前尚未集成,当前仅作为占位项。
|
||||||
+7
@@ -0,0 +1,7 @@
|
|||||||
|
### WiFi 助手
|
||||||
|
|
||||||
|
此 WiFi 助手可将 WiFi 凭据传输到设备。前提是所用硬件带有 WiFi 适配器。通过 IP 网络连接的设备必须已经具备 WiFi 连接和有效凭据,因此该助手只能修改现有凭据。而 TP 设备始终可以通过总线进行调整。
|
||||||
|
|
||||||
|
没有 WiFi 凭据的 IP 设备必须先通过其他方式完成初始设置。这取决于设备软件和所用硬件。通过终端(USB)设置通常始终可用,只需在控制台输入 `wifi SSID PSK`。
|
||||||
|
|
||||||
|
对于基于 Arduino-Pico 的设备,通常也可以通过 USB 传输 WiFi 凭据。将设备连接到电脑,并双击 Prog 按钮启动传输模式。然后将名为 "WIFI.TXT" 的文件复制到可移动驱动器。第一行必须包含 SSID,第二行必须包含 PSK。之后再次双击退出该模式并重启设备。
|
||||||
@@ -0,0 +1,33 @@
|
|||||||
|
function sendWifiSettings(device, online, progress, context) {
|
||||||
|
progress.setText("Übertrage die WiFi-Einstellungen.");
|
||||||
|
online.connect();
|
||||||
|
|
||||||
|
var data = [1];
|
||||||
|
var ssid = device.getParameterByName("NET_WifiSSID").value;
|
||||||
|
var psk = device.getParameterByName("NET_WifiPassword").value;
|
||||||
|
|
||||||
|
data[1] = ssid.length;
|
||||||
|
data[2] = psk.length;
|
||||||
|
|
||||||
|
for (var i = 0; i < data[1]; ++i) {
|
||||||
|
var code = ssid.charCodeAt(i);
|
||||||
|
data = data.concat([code]);
|
||||||
|
}
|
||||||
|
data = data.concat(0); // null-terminated string
|
||||||
|
|
||||||
|
for (var i = 0; i < data[2]; ++i) {
|
||||||
|
var code = psk.charCodeAt(i);
|
||||||
|
data = data.concat([code]);
|
||||||
|
}
|
||||||
|
data = data.concat(0); // null-terminated string
|
||||||
|
|
||||||
|
var resp = online.invokeFunctionProperty(0xA0, 5, data);
|
||||||
|
if (resp[0] != 0) {
|
||||||
|
throw new Error("Fehler: Das verwendete Gerät unterstützt kein WiFi!");
|
||||||
|
}
|
||||||
|
|
||||||
|
device.getParameterByName("NET_WifiSSID").value = "";
|
||||||
|
device.getParameterByName("NET_WifiPassword").value = "";
|
||||||
|
online.disconnect();
|
||||||
|
progress.setText("Übertragung der WiFi-Einstellungen abgeschlossen.");
|
||||||
|
}
|
||||||
@@ -0,0 +1,302 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<?xml-model href="../../Organization/knxprod-support/knx_project_20/knx-editor.xsd" type="application/xml" schematypens="http://www.w3.org/2001/XMLSchema"?>
|
||||||
|
<KNX xmlns:op="http://github.com/OpenKNX/OpenKNXproducer" xmlns="http://knx.org/xml/project/20" CreatedBy="KNX MT" ToolVersion="5.1.255.16695">
|
||||||
|
<!-- Enable IPTool of ETS. This hide ip settings in network tab -->
|
||||||
|
<op:config name="%NET_IPConfigTool%" value="0" />
|
||||||
|
<op:config name="%NET_WifiTool%" value="0" />
|
||||||
|
<op:config name="%NET_LanMode%" value="0" />
|
||||||
|
<op:config name="%NET_ServiceNTP%" value="1" />
|
||||||
|
<op:config name="%NET_ServiceOTA%" value="1" />
|
||||||
|
<op:config name="%NET_ShowMediumInfo%" value="0" />
|
||||||
|
|
||||||
|
<!-- Prepare: Not ready to use -->
|
||||||
|
<op:config name="%NET_ServiceHTTP%" value="0" />
|
||||||
|
|
||||||
|
|
||||||
|
<ManufacturerData>
|
||||||
|
<Manufacturer>
|
||||||
|
<ApplicationPrograms>
|
||||||
|
<ApplicationProgram>
|
||||||
|
<Static>
|
||||||
|
<ParameterTypes>
|
||||||
|
<ParameterType Id="%AID%_PT-CustomHostname" Name="CustomHostname">
|
||||||
|
<TypeRestriction Base="Value" SizeInBit="1">
|
||||||
|
<Enumeration Text="Standard" Value="0" Id="%ENID%" />
|
||||||
|
<Enumeration Text="Anpassen" Value="1" Id="%ENID%" />
|
||||||
|
</TypeRestriction>
|
||||||
|
</ParameterType>
|
||||||
|
<ParameterType Id="%AID%_PT-HostAddress" Name="HostAddress">
|
||||||
|
<TypeIPAddress AddressType="HostAddress" />
|
||||||
|
</ParameterType>
|
||||||
|
<ParameterType Id="%AID%_PT-SubnetMask" Name="SubnetMask">
|
||||||
|
<TypeIPAddress AddressType="SubnetMask" />
|
||||||
|
</ParameterType>
|
||||||
|
<ParameterType Id="%AID%_PT-GatewayAddress" Name="GatewayAddress">
|
||||||
|
<TypeIPAddress AddressType="GatewayAddress" />
|
||||||
|
</ParameterType>
|
||||||
|
<ParameterType Id="%AID%_PT-Hostname" Name="Hostname" ValidationErrorRef="%AID%_M-%TT%00001">
|
||||||
|
<TypeText SizeInBit="192" Pattern="^([A-Za-z](?:[A-Za-z0-9\-]*[A-Za-z0-9])*|)$"/>
|
||||||
|
</ParameterType>
|
||||||
|
<ParameterType Id="%AID%_PT-WifiSSID" Name="WifiSSID">
|
||||||
|
<TypeText SizeInBit="256" />
|
||||||
|
</ParameterType>
|
||||||
|
<ParameterType Id="%AID%_PT-WifiPassword" Name="WifiPassword">
|
||||||
|
<TypeText SizeInBit="504" />
|
||||||
|
</ParameterType>
|
||||||
|
<ParameterType Id="%AID%_PT-OTAUpdate" Name="OTAUpdate">
|
||||||
|
<TypeRestriction Base="Value" SizeInBit="2">
|
||||||
|
<Enumeration Text="Im Prog-Modus" Value="0" Id="%ENID%" />
|
||||||
|
<Enumeration Text="Immer aktiv" Value="1" Id="%ENID%" />
|
||||||
|
<Enumeration Text="Abgeschaltet" Value="2" Id="%ENID%" />
|
||||||
|
</TypeRestriction>
|
||||||
|
</ParameterType>
|
||||||
|
<ParameterType Id="%AID%_PT-LanMode" Name="LanMode">
|
||||||
|
<TypeRestriction Base="Value" SizeInBit="4">
|
||||||
|
<Enumeration Text="Automatisch" Value="0" Id="%ENID%" />
|
||||||
|
<Enumeration Text="10 MBit/s (Stromsparender)" Value="3" Id="%ENID%" />
|
||||||
|
<Enumeration Text="100 MBit/s" Value="1" Id="%ENID%" />
|
||||||
|
<!-- <Enumeration Text="100 MBit/s Halb-Duplex" Value="2" Id="%ENID%" /> -->
|
||||||
|
<!-- <Enumeration Text="10 MBit/s Halb-Duplex" Value="4" Id="%ENID%" /> -->
|
||||||
|
</TypeRestriction>
|
||||||
|
</ParameterType>
|
||||||
|
<ParameterType Id="%AID%_PT-NTPServer" Name="NTPServer">
|
||||||
|
<TypeText SizeInBit="400" /> <!-- 50 bytes -->
|
||||||
|
</ParameterType>
|
||||||
|
<!-- Status LEDs-->
|
||||||
|
<ParameterType Id="%AID%_PT-SLEDFunc" Name="SLEDFunc">
|
||||||
|
<TypeRestriction Base="Value" SizeInBit="16" UIHint="DropDown">
|
||||||
|
<Enumeration Text="Netzwerkstatus" Value="10" Id="%ENID%" />
|
||||||
|
</TypeRestriction>
|
||||||
|
</ParameterType>
|
||||||
|
</ParameterTypes>
|
||||||
|
<Parameters>
|
||||||
|
<!-- helper to check against a certain value in the case of a choose -->
|
||||||
|
<Parameter Id="%AID%_P-%TT%01000" Name="SelectHelper" ParameterType="%AID%_PT-ValueDpt5" Text="" Value="0" Access="None" />
|
||||||
|
<Parameter Id="%AID%_P-%TT%01001" Name="WifiSSID" ParameterType="%AID%_PT-WifiSSID" Text="SSID" Value="" />
|
||||||
|
<Parameter Id="%AID%_P-%TT%01002" Name="WifiPassword" ParameterType="%AID%_PT-WifiPassword" Text="PSK" Value=""/>
|
||||||
|
|
||||||
|
<!-- IP Config -->
|
||||||
|
<Union SizeInBit="128"><!-- 16bytes-->
|
||||||
|
<Memory CodeSegment="%MID%" Offset="0" BitOffset="0" />
|
||||||
|
<Parameter Id="%AID%_UP-%TT%00011" Name="HostAddress" ParameterType="%AID%_PT-HostAddress" Offset="0" BitOffset="0" Text="IP-Adresse" Value="192.168.178.2" />
|
||||||
|
<Parameter Id="%AID%_UP-%TT%00012" Name="SubnetMask" ParameterType="%AID%_PT-SubnetMask" Offset="4" BitOffset="0" Text="Subnetzsmaske" Value="255.255.255.0" />
|
||||||
|
<Parameter Id="%AID%_UP-%TT%00013" Name="GatewayAddress" ParameterType="%AID%_PT-GatewayAddress" Offset="8" BitOffset="0" Text="Standardgateway" Value="192.168.178.1" />
|
||||||
|
<Parameter Id="%AID%_UP-%TT%00021" Name="NameserverAddress" ParameterType="%AID%_PT-HostAddress" Offset="12" BitOffset="0" Text="Nameserver" Value="192.168.178.1" />
|
||||||
|
<!-- Reserved for Nameserver 2 -->
|
||||||
|
</Union>
|
||||||
|
|
||||||
|
<!-- 1bit options -->
|
||||||
|
<Union SizeInBit="8">
|
||||||
|
<Memory CodeSegment="%MID%" Offset="16" BitOffset="0" />
|
||||||
|
|
||||||
|
<Parameter Id="%AID%_UP-%TT%00001" Name="CustomHostname" ParameterType="%AID%_PT-OnOffYesNo" Offset="0" BitOffset="0" Text="Hostname anpassen" Value="0" />
|
||||||
|
<Parameter Id="%AID%_UP-%TT%00002" Name="StaticIP" ParameterType="%AID%_PT-OnOffYesNoInverted" Offset="0" BitOffset="1" Text="DHCP" Value="0" />
|
||||||
|
<!-- 6 bits free -->
|
||||||
|
</Union>
|
||||||
|
|
||||||
|
<!-- Services -->
|
||||||
|
<Union SizeInBit="8">
|
||||||
|
<Memory CodeSegment="%MID%" Offset="17" BitOffset="0" />
|
||||||
|
<Parameter Id="%AID%_UP-%TT%00031" Name="mDNS" ParameterType="%AID%_PT-OnOffYesNo" Offset="0" BitOffset="0" Text="mDNS" Value="1" />
|
||||||
|
<Parameter Id="%AID%_UP-%TT%00032" Name="HTTP" ParameterType="%AID%_PT-OnOffYesNo" Offset="0" BitOffset="1" Text="Weberver" Value="1" />
|
||||||
|
<Parameter Id="%AID%_UP-%TT%00033" Name="NTP" ParameterType="%AID%_PT-OnOffYesNo" Offset="0" BitOffset="2" Text="NTP-Client" Value="0" />
|
||||||
|
<Parameter Id="%AID%_UP-%TT%00034" Name="OTAUpdate" ParameterType="%AID%_PT-OTAUpdate" Offset="0" BitOffset="3" Text="OTA-Update" Value="0" />
|
||||||
|
<!-- 5 bits free -->
|
||||||
|
</Union>
|
||||||
|
|
||||||
|
<!-- Hostname -->
|
||||||
|
<Parameter Id="%AID%_P-%TT%00010" Name="HostName" ParameterType="%AID%_PT-Hostname" Text="Hostname" Value="" >
|
||||||
|
<Memory CodeSegment="%MID%" Offset="18" BitOffset="0" />
|
||||||
|
<!-- 192bits / 24bytes-->
|
||||||
|
</Parameter>
|
||||||
|
|
||||||
|
<!-- Type & Mode -->
|
||||||
|
<Union SizeInBit="8">
|
||||||
|
<Memory CodeSegment="%MID%" Offset="59" BitOffset="0" />
|
||||||
|
<Parameter Id="%AID%_UP-%TT%00052" Name="LanMode" ParameterType="%AID%_PT-LanMode" Offset="0" BitOffset="0" Text="LAN-Modus" Value="0" />
|
||||||
|
</Union>
|
||||||
|
|
||||||
|
<!-- NTP -->
|
||||||
|
<Union SizeInBit="408">
|
||||||
|
<Memory CodeSegment="%MID%" Offset="60" BitOffset="0" />
|
||||||
|
<Parameter Id="%AID%_UP-%TT%00061" Name="NTPServer" ParameterType="%AID%_PT-NTPServer" Offset="0" BitOffset="0" Text="Zeitserver" Value="pool.ntp.org" />
|
||||||
|
<!-- 50 characters + 0 terminator = 51 bytes used -->
|
||||||
|
</Union>
|
||||||
|
|
||||||
|
</Parameters>
|
||||||
|
<ParameterRefs>
|
||||||
|
<ParameterRef Id="%AID%_P-%TT%01000_R-%TT%0100000" RefId="%AID%_P-%TT%01000" />
|
||||||
|
<ParameterRef Id="%AID%_P-%TT%01001_R-%TT%0100100" RefId="%AID%_P-%TT%01001" />
|
||||||
|
<ParameterRef Id="%AID%_P-%TT%01002_R-%TT%0100200" RefId="%AID%_P-%TT%01002" />
|
||||||
|
<ParameterRef Id="%AID%_UP-%TT%00001_R-%TT%0000101" RefId="%AID%_UP-%TT%00001" />
|
||||||
|
<ParameterRef Id="%AID%_UP-%TT%00002_R-%TT%0000201" RefId="%AID%_UP-%TT%00002" />
|
||||||
|
<ParameterRef Id="%AID%_UP-%TT%00034_R-%TT%0003401" RefId="%AID%_UP-%TT%00034" />
|
||||||
|
<ParameterRef Id="%AID%_P-%TT%00010_R-%TT%0001001" RefId="%AID%_P-%TT%00010" />
|
||||||
|
<ParameterRef Id="%AID%_UP-%TT%00011_R-%TT%0001101" RefId="%AID%_UP-%TT%00011" />
|
||||||
|
<ParameterRef Id="%AID%_UP-%TT%00012_R-%TT%0001201" RefId="%AID%_UP-%TT%00012" />
|
||||||
|
<ParameterRef Id="%AID%_UP-%TT%00013_R-%TT%0001301" RefId="%AID%_UP-%TT%00013" />
|
||||||
|
<ParameterRef Id="%AID%_UP-%TT%00021_R-%TT%0002101" RefId="%AID%_UP-%TT%00021" />
|
||||||
|
<ParameterRef Id="%AID%_UP-%TT%00031_R-%TT%0003101" RefId="%AID%_UP-%TT%00031" />
|
||||||
|
<ParameterRef Id="%AID%_UP-%TT%00032_R-%TT%0003201" RefId="%AID%_UP-%TT%00032" />
|
||||||
|
<ParameterRef Id="%AID%_UP-%TT%00033_R-%TT%0003301" RefId="%AID%_UP-%TT%00033" />
|
||||||
|
<ParameterRef Id="%AID%_UP-%TT%00052_R-%TT%0005201" RefId="%AID%_UP-%TT%00052" />
|
||||||
|
<!-- NTPServer -->
|
||||||
|
<ParameterRef Id="%AID%_UP-%TT%00061_R-%TT%0006101" RefId="%AID%_UP-%TT%00061" />
|
||||||
|
</ParameterRefs>
|
||||||
|
<ComObjectTable>
|
||||||
|
</ComObjectTable>
|
||||||
|
<ComObjectRefs>
|
||||||
|
</ComObjectRefs>
|
||||||
|
<Messages>
|
||||||
|
<Message Id="%AID%_M-%TT%00001" Name="InvalidHostName" Text="Darf nur 24 Zeichen lang sein und muss aus Buchstaben, Zahlen und Bindestriche bestehen." />
|
||||||
|
</Messages>
|
||||||
|
<Script>
|
||||||
|
<op:include href="Network.script.js" prefix="NET" type="script" />
|
||||||
|
</Script>
|
||||||
|
</Static>
|
||||||
|
<Dynamic>
|
||||||
|
<Channel Id="%AID%_CH-%PREFIX%" Number="%PREFIX%" Name="Main" Text="Netzwerk" Icon="ethernet" HelpContext="NET-Dokumentation">
|
||||||
|
<ParameterBlock Id="%AID%_PB-nnn" Name="Basic" Text="Allgemein" Icon="cog-outline" HelpContext="NET-Dokumentation">
|
||||||
|
<!-- Hidden -->
|
||||||
|
<ParameterRefRef RefId="%AID%_P-%TT%01000_R-%TT%0100000" />
|
||||||
|
<ParameterSeparator Id="%AID%_PS-nnn" Text="Netzwerk" UIHint="Headline" />
|
||||||
|
<ParameterSeparator Id="%AID%_PS-nnn" Text="Version: %ModuleVersion%" />
|
||||||
|
<ParameterSeparator Id="%AID%_PS-nnn" Text="" UIHint="HorizontalRuler" />
|
||||||
|
<choose ParamRefId="%AID%_P-%TT%01000_R-%TT%0100000"><!-- Static 0 -->
|
||||||
|
<when test="!=%NET_ShowMediumInfo%">
|
||||||
|
<ParameterSeparator Id="%AID%_PS-nnn" Text="Diese Einstellungen sind lediglich für Geräte mit IP-Schnittstelle vorgesehen.
|
||||||
|
Geräte, die ausschließlich per TP angebunden sind, benötigen hier keine Konfiguration" UIHint="Information" />
|
||||||
|
</when>
|
||||||
|
</choose>
|
||||||
|
|
||||||
|
<ParameterSeparator Id="%AID%_PS-nnn" Text="IP-Adresse" UIHint="Headline" />
|
||||||
|
<choose ParamRefId="%AID%_P-%TT%01000_R-%TT%0100000"><!-- Static 0 -->
|
||||||
|
<when test="%NET_IPConfigTool%"> <!-- default -->
|
||||||
|
<ParameterRefRef RefId="%AID%_UP-%TT%00002_R-%TT%0000201" IndentLevel="1" HelpContext="NET-IP-Adresse" />
|
||||||
|
<choose ParamRefId="%AID%_UP-%TT%00002_R-%TT%0000201">
|
||||||
|
<when test="1">
|
||||||
|
<ParameterRefRef RefId="%AID%_UP-%TT%00011_R-%TT%0001101" IndentLevel="1" HelpContext="NET-IP-Adresse" />
|
||||||
|
<ParameterRefRef RefId="%AID%_UP-%TT%00012_R-%TT%0001201" IndentLevel="1" HelpContext="NET-IP-Adresse" />
|
||||||
|
<ParameterRefRef RefId="%AID%_UP-%TT%00013_R-%TT%0001301" IndentLevel="1" HelpContext="NET-IP-Adresse" />
|
||||||
|
<ParameterRefRef RefId="%AID%_UP-%TT%00021_R-%TT%0002101" IndentLevel="1" HelpContext="NET-IP-Adresse" />
|
||||||
|
</when>
|
||||||
|
</choose>
|
||||||
|
</when>
|
||||||
|
<when test="!=%NET_IPConfigTool%"> <!-- router -->
|
||||||
|
<ParameterSeparator Id="%AID%_PS-nnn" Text="IP-Einstellungen können im Eigenschaften Feld der ETS, Tab IP gesetzt werden." UIHint="Information" />
|
||||||
|
</when>
|
||||||
|
</choose>
|
||||||
|
|
||||||
|
<ParameterSeparator Id="%AID%_PS-nnn" Text="Services" UIHint="Headline" />
|
||||||
|
<ParameterRefRef RefId="%AID%_UP-%TT%00031_R-%TT%0003101" IndentLevel="1" HelpContext="NET-MDNS" />
|
||||||
|
|
||||||
|
<!-- HTTP -->
|
||||||
|
<choose ParamRefId="%AID%_P-%TT%01000_R-%TT%0100000">
|
||||||
|
<when test="!=%NET_ServiceHTTP%">
|
||||||
|
<ParameterRefRef RefId="%AID%_UP-%TT%00032_R-%TT%0003201" IndentLevel="1" HelpContext="NET-HTTP" />
|
||||||
|
</when>
|
||||||
|
</choose>
|
||||||
|
|
||||||
|
<!-- NTP -->
|
||||||
|
<choose ParamRefId="%AID%_P-%TT%01000_R-%TT%0100000">
|
||||||
|
<when test="!=%NET_ServiceNTP%">
|
||||||
|
<ParameterRefRef RefId="%AID%_UP-%TT%00033_R-%TT%0003301" IndentLevel="1" HelpContext="NET-NTP" />
|
||||||
|
<choose ParamRefId="%AID%_UP-%TT%00033_R-%TT%0003301">
|
||||||
|
<when test="0">
|
||||||
|
<Assign TargetParamRefRef="%AID%_UP-1000006_R-100000601" Value="0" />
|
||||||
|
</when>
|
||||||
|
<when test="1">
|
||||||
|
<Assign TargetParamRefRef="%AID%_UP-1000006_R-100000601" Value="1" />
|
||||||
|
<ParameterRefRef RefId="%AID%_UP-%TT%00061_R-%TT%0006101" IndentLevel="1" HelpContext="NET-NTP" />
|
||||||
|
</when>
|
||||||
|
</choose>
|
||||||
|
</when>
|
||||||
|
<when test="%NET_ServiceNTP%">
|
||||||
|
<Assign TargetParamRefRef="%AID%_UP-1000006_R-100000601" Value="0" />
|
||||||
|
</when>
|
||||||
|
</choose>
|
||||||
|
|
||||||
|
<!-- OTA -->
|
||||||
|
<choose ParamRefId="%AID%_P-%TT%01000_R-%TT%0100000">
|
||||||
|
<when test="!=%NET_ServiceOTA%">
|
||||||
|
<ParameterRefRef RefId="%AID%_UP-%TT%00034_R-%TT%0003401" IndentLevel="1" HelpContext="NET-OTA" />
|
||||||
|
</when>
|
||||||
|
</choose>
|
||||||
|
|
||||||
|
<ParameterSeparator Id="%AID%_PS-nnn" Text="Erweiterte Einstellung" UIHint="Headline" />
|
||||||
|
<!-- Hostname -->
|
||||||
|
<ParameterRefRef RefId="%AID%_UP-%TT%00001_R-%TT%0000101" IndentLevel="1" HelpContext="NET-Hostname" />
|
||||||
|
<choose ParamRefId="%AID%_UP-%TT%00001_R-%TT%0000101">
|
||||||
|
<when test="1">
|
||||||
|
<ParameterRefRef RefId="%AID%_P-%TT%00010_R-%TT%0001001" IndentLevel="1" HelpContext="NET-Hostname" />
|
||||||
|
</when>
|
||||||
|
</choose>
|
||||||
|
|
||||||
|
<!-- LanMode -->
|
||||||
|
<choose ParamRefId="%AID%_P-%TT%01000_R-%TT%0100000">
|
||||||
|
<when test="!=%NET_LanMode%">
|
||||||
|
<ParameterRefRef RefId="%AID%_UP-%TT%00052_R-%TT%0005201" IndentLevel="1" HelpContext="%DOC%" />
|
||||||
|
</when>
|
||||||
|
</choose>
|
||||||
|
|
||||||
|
</ParameterBlock>
|
||||||
|
|
||||||
|
<!-- HTTP -->
|
||||||
|
<choose ParamRefId="%AID%_UP-%TT%00032_R-%TT%0003201">
|
||||||
|
<when test="1">
|
||||||
|
<ParameterBlock Id="%AID%_PB-nnn" Name="HTTP" Text="Webserver" Icon="web" HelpContext="NET-Webserver">
|
||||||
|
<ParameterSeparator Id="%AID%_PS-nnn" Text="Webserver" UIHint="Headline" />
|
||||||
|
</ParameterBlock>
|
||||||
|
</when>
|
||||||
|
</choose>
|
||||||
|
|
||||||
|
<!-- WiFi -->
|
||||||
|
<choose ParamRefId="%AID%_P-%TT%01000_R-%TT%0100000"><!-- Static 0 -->
|
||||||
|
<when test="!=%NET_WifiTool%"> <!-- default -->
|
||||||
|
<ParameterBlock Id="%AID%_PB-nnn" Name="WiFi" Text="WiFi-Assistent" Icon="wifi" HelpContext="NET-WiFi-Assistent">
|
||||||
|
<ParameterSeparator Id="%AID%_PS-nnn" Text="Dieser WiFi-Assistent ermöglicht das Übertragen von WiFi-Zugangsdaten auf das Gerät.
|
||||||
|
Diese Einstellungen sind lediglich für Geräte mit WiFi-Schnittstelle vorgesehen." UIHint="Information" />
|
||||||
|
|
||||||
|
<ParameterSeparator Id="%AID%_PS-nnn" Text="WiFi-Zugangsdaten" UIHint="Headline" />
|
||||||
|
<ParameterRefRef RefId="%AID%_P-%TT%01001_R-%TT%0100100" IndentLevel="1" />
|
||||||
|
<ParameterRefRef RefId="%AID%_P-%TT%01002_R-%TT%0100200" IndentLevel="1" />
|
||||||
|
|
||||||
|
<ParameterBlock Id="%AID%_PB-nnn" Name="A" Inline="true" Layout="Grid">
|
||||||
|
<Rows>
|
||||||
|
<Row Id="%AID%_PB-nnn_R-1" Name="Row1" />
|
||||||
|
</Rows>
|
||||||
|
<Columns>
|
||||||
|
<Column Id="%AID%_PB-nnn_C-1" Name="Col1" Width="46%" />
|
||||||
|
<Column Id="%AID%_PB-nnn_C-2" Name="Col2" Width="53%" />
|
||||||
|
</Columns>
|
||||||
|
<Button Id="%AID%_MD-%TT%000100_B-%TT%00000" Text="Übertragen" EventHandlerOnline="ConnectionOriented" EventHandler="sendWifiSettings" EventHandlerParameters="{ "Module": %TT% }" Cell="1,2" />
|
||||||
|
</ParameterBlock>
|
||||||
|
|
||||||
|
</ParameterBlock>
|
||||||
|
</when>
|
||||||
|
</choose>
|
||||||
|
|
||||||
|
</Channel>
|
||||||
|
</Dynamic>
|
||||||
|
</ApplicationProgram>
|
||||||
|
</ApplicationPrograms>
|
||||||
|
<Baggages>
|
||||||
|
<Baggage TargetPath="" Name="Help_en.zip" Id="%FILE-HELP-de%">
|
||||||
|
<FileInfo TimeInfo="%DATETIME%" />
|
||||||
|
</Baggage>
|
||||||
|
<Baggage TargetPath="" Name="Help_de.zip" Id="%FILE-HELP-de-DE%">
|
||||||
|
<FileInfo TimeInfo="%DATETIME%" />
|
||||||
|
</Baggage>
|
||||||
|
<Baggage TargetPath="" Name="Help_zh-CN.zip" Id="%FILE-HELP-zh-CN%">
|
||||||
|
<FileInfo TimeInfo="%DATETIME%" />
|
||||||
|
</Baggage>
|
||||||
|
<Baggage TargetPath="" Name="Help_ja-JP.zip" Id="%FILE-HELP-ja-JP%">
|
||||||
|
<FileInfo TimeInfo="%DATETIME%" />
|
||||||
|
</Baggage>
|
||||||
|
<Baggage TargetPath="" Name="Icons.zip" Id="%FILE-ICONS%">
|
||||||
|
<FileInfo TimeInfo="%DATETIME%" />
|
||||||
|
</Baggage>
|
||||||
|
</Baggages>
|
||||||
|
</Manufacturer>
|
||||||
|
</ManufacturerData>
|
||||||
|
</KNX>
|
||||||
@@ -0,0 +1,22 @@
|
|||||||
|
{
|
||||||
|
"name": "OGM-Common",
|
||||||
|
"version": "1.7.2",
|
||||||
|
"dependencies": {
|
||||||
|
"khoih-prog/TimerInterrupt_Generic": "^1.13.0",
|
||||||
|
"nickgammon/Regexp": "^0.1.0",
|
||||||
|
"robtillaart/ANSI": "^0.2.0",
|
||||||
|
"RTTStream": "https://github.com/koendv/RTTStream#1.4.0"
|
||||||
|
},
|
||||||
|
"description": "Common routines and helpers, used in OpenKNX projects",
|
||||||
|
"homepage": "https://openknx.de",
|
||||||
|
"authors": {
|
||||||
|
"name": "OpenKNX",
|
||||||
|
"email": "info@openknx.de",
|
||||||
|
"url": "https://openknx.de",
|
||||||
|
"maintainer": true
|
||||||
|
},
|
||||||
|
"repository": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "https://github.com/OpenKNX/OGM-Common"
|
||||||
|
}
|
||||||
|
}
|
||||||
+6
@@ -0,0 +1,6 @@
|
|||||||
|
### Bei Neustart vom Bus lesen
|
||||||
|
|
||||||
|
Nach einem Neustart können Uhrzeit und Datum auch aktiv über Lesetelegramme abgefragt werden. Mit diesem Parameter wird bestimmt, ob Uhrzeit und Datum nach einem Neustart aktiv gelesen werden.
|
||||||
|
|
||||||
|
Wenn dieser Parameter gesetzt ist, wird die Uhrzeit und das Datum alle 20-30 Sekunden über ein Lesetelegramm vom Bus gelesen, bis eine entsprechende Antwort kommt. Falls keine Uhr im KNX-System vorhanden ist oder die Uhr nicht auf Leseanfragen antworten kann, sollte dieser Parameter auf "Nein" gesetzt werden.
|
||||||
|
|
||||||
+9
@@ -0,0 +1,9 @@
|
|||||||
|
### Beschreibung
|
||||||
|
|
||||||
|
Der hier angegebene Name wird an verschiedenen Stellen verwendet, um diesen Kanal wiederzufinden.
|
||||||
|
|
||||||
|
* Seitenbeschreibung des Kanals
|
||||||
|
* Name vom Kommunikationsobjekt
|
||||||
|
|
||||||
|
Eine aussagekräftige Benennung erlaubt eine einfachere Orientierung innerhalb der Applikation, vor allem wenn man viele Kanäle nutzt.
|
||||||
|
|
||||||
+4
@@ -0,0 +1,4 @@
|
|||||||
|
### Kommentar
|
||||||
|
|
||||||
|
Hier kann man einen Freitext eingeben, der den Kanal beschreibt. Dieser Text kann mehrzeilig sein. Leider unterstütz die ETS von sich aus keine mehrzeiligen Texte. Mit dem Button unter der Textbox kann man alle Eingaben der Zeichenfolge '\n' in neue Zeilen umwandeln lassen.
|
||||||
|
|
||||||
+8
@@ -0,0 +1,8 @@
|
|||||||
|
### Diagnoseobjekt anzeigen
|
||||||
|
|
||||||
|
Man kann bei diesem Gerät ein Diagnoseobjekt (KO 7) einschalten. Dieses Diagnoseobjekt ist primär zum Debuggen vorhanden, kann aber auch einem User bei einigen Fragen weiter helfen.
|
||||||
|
|
||||||
|
Die Grundidee vom Diagnoseobjekt: Man sendet mit der ETS Kommandos an das KO 7 und bekommt eine entsprechende Antwort. Derzeit sind nur wenige Kommandos für die Nutzung durch den Enduser geeignet, allerdings werden im Laufe der Zeit immer weitere Kommandos hinzukommen. Die Kommandos sind von den verwendeten OpenKNX-Modulen abhängig und werden in den dortigen Applikationsbeschreibungen beschrieben.
|
||||||
|
|
||||||
|
Mit einem 'Ja' wird das KO 7 'Diagnoseobjekt' freigeschaltet.
|
||||||
|
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user