#pragma once #include "bridge.hpp" #include "bridge_model.hpp" #include "model_value.hpp" #include #include #include #include #include namespace gateway { constexpr uint16_t kGatewayModbusDefaultTcpPort = 1502; constexpr size_t kGatewayModbusMaxPduBytes = 252; constexpr uint16_t kGatewayModbusMaxReadBits = 2000; constexpr uint16_t kGatewayModbusMaxReadRegisters = 125; constexpr uint16_t kGatewayModbusMaxWriteBits = 1968; constexpr uint16_t kGatewayModbusMaxWriteRegisters = 123; struct GatewayModbusConfig { std::string transport{"tcp-server"}; std::string host; uint16_t port{kGatewayModbusDefaultTcpPort}; uint8_t unit_id{1}; }; enum class GatewayModbusSpace : uint8_t { kCoil = 1, kDiscreteInput = 2, kHoldingRegister = 3, kInputRegister = 4, }; enum class GatewayModbusAccess : uint8_t { kReadOnly = 0, kWriteOnly = 1, kReadWrite = 2, }; enum class GatewayModbusGeneratedKind : uint8_t { kNone = 0, kShortOn, kShortOff, kShortRecallMax, kShortRecallMin, kShortDiscovered, kShortOnline, kShortSupportsDt1, kShortSupportsDt4, kShortSupportsDt5, kShortSupportsDt6, kShortSupportsDt8, kShortGroupMaskKnown, kShortActualLevelKnown, kShortSceneKnown, kShortSettingsKnown, kShortControlGearPresent, kShortLampFailure, kShortLampPowerOn, kShortLimitError, kShortFadingCompleted, kShortResetState, kShortMissingShortAddress, kShortPowerSupplyFault, kShortBrightness, kShortColorTemperature, kShortGroupMask, kShortPowerOnLevel, kShortSystemFailureLevel, kShortMinLevel, kShortMaxLevel, kShortFadeTime, kShortFadeRate, kShortInventoryState, kShortPrimaryType, kShortTypeMask, kShortActualLevel, kShortSceneId, kShortRawStatus, kShortDiagnosticBit, }; struct GatewayModbusPoint { GatewayModbusSpace space{GatewayModbusSpace::kHoldingRegister}; GatewayModbusAccess access{GatewayModbusAccess::kReadWrite}; uint16_t address{0}; std::string id; std::string name; bool generated{false}; GatewayModbusGeneratedKind generated_kind{GatewayModbusGeneratedKind::kNone}; int short_address{-1}; std::string model_id; BridgeOperation operation{BridgeOperation::unknown}; std::optional bit_index; std::string diagnostic_snapshot; std::string diagnostic_bool; int diagnostic_device_type{-1}; }; struct GatewayModbusPointBinding { std::string model_id; GatewayModbusSpace space{GatewayModbusSpace::kHoldingRegister}; uint16_t address{0}; std::string id; std::string name; bool generated{false}; GatewayModbusGeneratedKind generated_kind{GatewayModbusGeneratedKind::kNone}; int short_address{-1}; GatewayModbusAccess access{GatewayModbusAccess::kReadWrite}; std::optional bit_index; std::string diagnostic_snapshot; std::string diagnostic_bool; int diagnostic_device_type{-1}; }; std::optional GatewayModbusConfigFromValue(const DaliValue* value); DaliValue GatewayModbusConfigToValue(const GatewayModbusConfig& config); const char* GatewayModbusSpaceToString(GatewayModbusSpace space); const char* GatewayModbusAccessToString(GatewayModbusAccess access); const char* GatewayModbusGeneratedKindToString(GatewayModbusGeneratedKind kind); int GatewayModbusHumanAddressFromWire(GatewayModbusSpace space, uint16_t zero_based_address); std::optional GatewayModbusReadSpaceForFunction(uint8_t function_code); std::optional GatewayModbusWriteSpaceForFunction(uint8_t function_code); class GatewayModbusBridge { public: explicit GatewayModbusBridge(DaliBridgeEngine& engine); void setConfig(const GatewayModbusConfig& config); const GatewayModbusConfig& config() const; void rebuildMap(); std::optional findPoint(GatewayModbusSpace space, uint16_t address) const; std::vector describePoints() const; std::vector describeHoldingRegisters() const; DaliBridgeResult readModelPoint(const GatewayModbusPoint& point) const; DaliBridgeResult writeRegisterPoint(const GatewayModbusPoint& point, uint16_t value) const; DaliBridgeResult writeCoilPoint(const GatewayModbusPoint& point, bool value) const; private: DaliBridgeResult executeModelPoint(const GatewayModbusPoint& point, std::optional value) const; DaliBridgeEngine& engine_; GatewayModbusConfig config_; std::vector points_; }; } // namespace gateway