diff --git a/service/modbus_qc_mapping.go b/service/modbus_qc_mapping.go index 494bcc5..f9a0b76 100644 --- a/service/modbus_qc_mapping.go +++ b/service/modbus_qc_mapping.go @@ -74,9 +74,14 @@ func (s *modbusQcService) WriteQdBytes(bytes []byte) error { } func NewModbusQcService(config *sproto.ModbusConfig, qd []byte, cj []byte) (IotQcMappingService, error) { + // 基础配置检查 if err := checkConfig(config); err != nil { return nil, err } + // 映射范围配置检查 + if err := checkConfigMappingRange(config, qd, cj); err != nil { + return nil, err + } _, ok := modbus.GetClient(config.Url) if ok { return nil, fmt.Errorf("modbus客户端已存在,url=%s", config.Url) @@ -173,15 +178,6 @@ func (m *modbusQcService) onWrite(dt sproto.DataType, bytes []byte) error { // } // } -func isWriteFunction(modbus_Function sproto.Modbus_Function) bool { - return modbus_Function == sproto.Modbus_WriteCoil || - modbus_Function == sproto.Modbus_WriteCoils || - modbus_Function == sproto.Modbus_WriteRegister || - modbus_Function == sproto.Modbus_WriteRegisters || - modbus_Function == sproto.Modbus_RWCoils || - modbus_Function == sproto.Modbus_RWRegisters -} - func (m *modbusQcService) run(ctx context.Context) { defer close(m.done) mainLoop: @@ -369,6 +365,41 @@ func checkConfig(config *sproto.ModbusConfig) error { return nil } +func checkConfigMappingRange(modbusConfig *sproto.ModbusConfig, qd []byte, cj []byte) error { + for _, mdm := range modbusConfig.Mapping { + if mdm.Type == sproto.DataType_CollectTable { + err := checkMappingOutRange(mdm, cj) + if err != nil { + return err + } + } else if mdm.Type == sproto.DataType_DriveTable { + err := checkMappingOutRange(mdm, qd) + if err != nil { + return err + } + } + } + return nil +} + +func checkMappingOutRange(mdm *sproto.ModbusDcMapping, bytes []byte) error { + f := mdm.Function + start := mdm.Start + quantity := mdm.Quantity + if isCoilFunction(f) { + end := start + quantity + if end > uint32(len(bytes)*8) { + return fmt.Errorf("modbus地址映射配置错误,采集表地址超出范围: 功能=%s,起始位地址=%d,位数量=%d,实际位长度=%d", f, start, quantity, len(bytes)*8) + } + } else { + end := start + quantity*2 + if end > uint32(len(bytes)) { + return fmt.Errorf("modbus地址映射配置错误,采集表地址超出范围: 功能=%s,起始字节地址=%d,字数量=%d,实际位长度=%d", f, start, quantity, len(bytes)) + } + } + return nil +} + func convertEndianness(endianness sproto.Modbus_Endianness) modbus.Endianness { switch endianness { case sproto.Modbus_BigEndian: @@ -378,3 +409,28 @@ func convertEndianness(endianness sproto.Modbus_Endianness) modbus.Endianness { } return modbus.BigEndian } + +func isWriteFunction(modbus_Function sproto.Modbus_Function) bool { + return modbus_Function == sproto.Modbus_WriteCoil || + modbus_Function == sproto.Modbus_WriteCoils || + modbus_Function == sproto.Modbus_WriteRegister || + modbus_Function == sproto.Modbus_WriteRegisters || + modbus_Function == sproto.Modbus_RWCoils || + modbus_Function == sproto.Modbus_RWRegisters +} + +func isCoilFunction(modbus_Function sproto.Modbus_Function) bool { + return modbus_Function == sproto.Modbus_ReadCoil || + modbus_Function == sproto.Modbus_ReadDiscreteInput || + modbus_Function == sproto.Modbus_RWCoils || + modbus_Function == sproto.Modbus_WriteCoil || + modbus_Function == sproto.Modbus_WriteCoils +} + +// func isRegisterFunction(modbus_Function sproto.Modbus_Function) bool { +// return modbus_Function == sproto.Modbus_ReadInputRegister || +// modbus_Function == sproto.Modbus_ReadHoldingRegister || +// modbus_Function == sproto.Modbus_RWRegisters || +// modbus_Function == sproto.Modbus_WriteRegister || +// modbus_Function == sproto.Modbus_WriteRegisters +// }