| | |
| | | try { |
| | | String addressMapping = extractAddressMapping(device); |
| | | if (addressMapping == null || addressMapping.isEmpty()) { |
| | | log.error("设备配置中addressMapping为空: deviceId={}", device.getId()); |
| | | return; |
| | | String errorMsg = "设备配置中addressMapping为空: deviceId=" + device.getId(); |
| | | log.error(errorMsg); |
| | | throw new IllegalArgumentException(errorMsg); |
| | | } |
| | | |
| | | // 解析addressMapping JSON配置 |
| | |
| | | String dbArea = extractDbArea(device); |
| | | List<S7Parameter> parameters = buildS7ParametersWithValuesForDevice(device, dbArea, addressMappingObj, dataMap); |
| | | |
| | | if (parameters.isEmpty()) { |
| | | log.warn("没有有效的字段需要写入PLC: deviceId={}", device.getId()); |
| | | return; |
| | | } |
| | | |
| | | // 写入PLC |
| | | s7Serializer.write(parameters); |
| | | } catch (Exception e) { |
| | | log.error("写入PLC数据失败,请检查:1.PLC IP地址是否正确[{}] 2.PLC设备是否在线 3.网络连接是否正常,deviceId: {}, 详细错误: {}", |
| | | device.getPlcIp(), device.getId(), e.getMessage(), e); |
| | | String errorMsg = String.format("写入PLC数据失败,请检查:1.PLC IP地址是否正确[%s] 2.PLC设备是否在线 3.网络连接是否正常,deviceId: %s, 详细错误: %s", |
| | | device.getPlcIp(), device.getId(), e.getMessage()); |
| | | log.error(errorMsg, e); |
| | | throw new RuntimeException(errorMsg, e); |
| | | } |
| | | } |
| | | |
| | |
| | | EDataType dataType = fieldConfig.dataType != null ? fieldConfig.dataType : determineFieldTypeByName(fieldName); |
| | | int count = fieldConfig.count > 0 ? fieldConfig.count : determineFieldCountByName(fieldName); |
| | | |
| | | // 根据字段类型转换值 |
| | | Object convertedValue = convertValueByType(value, dataType); |
| | | |
| | | // 创建S7Parameter,设置值 |
| | | S7Parameter parameter = new S7Parameter(fullAddress, dataType, count); |
| | | parameter.setValue(value); |
| | | parameter.setValue(convertedValue); |
| | | parameters.add(parameter); |
| | | } |
| | | |
| | |
| | | lowerName.startsWith("plcglassid")) { |
| | | return EDataType.STRING; |
| | | } |
| | | |
| | | // 联机状态等布尔标记 |
| | | if (lowerName.contains("online")) { |
| | | return EDataType.BOOL; |
| | | } |
| | | // 默认返回UINT16 |
| | | return EDataType.UINT16; |
| | | } |
| | | |
| | | /** |
| | | * 根据字段类型转换值 |
| | | * 主要处理:Integer -> Boolean (对于BOOL类型) |
| | | * |
| | | * @param value 原始值 |
| | | * @param dataType 目标数据类型 |
| | | * @return 转换后的值 |
| | | */ |
| | | private Object convertValueByType(Object value, EDataType dataType) { |
| | | if (value == null) { |
| | | return null; |
| | | } |
| | | |
| | | // 如果已经是目标类型,直接返回 |
| | | if (dataType == EDataType.BOOL) { |
| | | if (value instanceof Boolean) { |
| | | return value; |
| | | } |
| | | // 将 Integer/Number 转换为 Boolean |
| | | if (value instanceof Number) { |
| | | int intValue = ((Number) value).intValue(); |
| | | return intValue != 0; |
| | | } |
| | | // 尝试从字符串转换 |
| | | if (value instanceof String) { |
| | | String str = ((String) value).trim().toLowerCase(); |
| | | return "true".equals(str) || "1".equals(str) || "on".equals(str); |
| | | } |
| | | // 其他类型,尝试转换为数字再转Boolean |
| | | try { |
| | | int intValue = Integer.parseInt(String.valueOf(value)); |
| | | return intValue != 0; |
| | | } catch (NumberFormatException e) { |
| | | log.warn("无法将值转换为Boolean: {}", value); |
| | | return false; |
| | | } |
| | | } |
| | | |
| | | // 对于其他类型,如果已经是目标类型或兼容类型,直接返回 |
| | | // 例如:UINT16 可以接受 Integer, Short, Byte 等 |
| | | if (dataType == EDataType.UINT16 || dataType == EDataType.INT16) { |
| | | if (value instanceof Number) { |
| | | return value; |
| | | } |
| | | // 尝试从字符串转换 |
| | | if (value instanceof String) { |
| | | try { |
| | | return Integer.parseInt((String) value); |
| | | } catch (NumberFormatException e) { |
| | | log.warn("无法将值转换为Integer: {}", value); |
| | | return 0; |
| | | } |
| | | } |
| | | } |
| | | |
| | | // 对于其他类型,直接返回原值 |
| | | return value; |
| | | } |
| | | |
| | | /** |
| | | * 根据字段名推断字段长度/数量 |
| | | */ |
| | | private int determineFieldCountByName(String fieldName) { |