优化驱动缓存的操作

This commit is contained in:
pnoker
2020-02-28 22:47:28 +08:00
parent 45105edde3
commit 60a87368df
8 changed files with 205 additions and 159 deletions
@@ -62,21 +62,15 @@ public interface Common {
}
/**
* 驱动 SDK Job Bean 前缀 和 三个固定调度任务
* 数据类型
*/
interface Sdk {
String JOB_PREFIX = "com.pnoker.common.sdk.quartz.job.";
String CUSTOMIZER_JOB = "自定义调度任务";
String READ_JOB = "定时采集任务";
}
/**
* 属性常量
*/
interface Property {
short READ_ONLY = 0;
short WRITE_ONLY = 1;
short READ_WRITE = 2;
interface ValueType {
String STRING = "string";
String INT = "int";
String DOUBLE = "double";
String FLOAT = "float";
String LONG = "long";
String BOOLEAN = "boolean";
}
/**
@@ -2,6 +2,7 @@ package com.pnoker.common.sdk.bean;
import com.pnoker.common.model.Device;
import com.pnoker.common.model.Point;
import lombok.Getter;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
@@ -11,6 +12,7 @@ import java.util.Map;
* @author pnoker
*/
@Slf4j
@Getter
@Component
public class DriverContext {
@@ -41,51 +43,26 @@ public class DriverContext {
*/
private volatile Map<Long, Map<Long, Map<String, AttributeInfo>>> pointInfoMap;
public synchronized long getDriverId() {
return driverId;
}
public synchronized void setDriverId(long driverId) {
this.driverId = driverId;
}
public synchronized Map<Long, Map<String, AttributeInfo>> getDriverInfoMap() {
return driverInfoMap;
}
public synchronized void setDriverInfoMap(Map<Long, Map<String, AttributeInfo>> driverInfoMap) {
this.driverInfoMap = driverInfoMap;
}
public synchronized Map<Long, Device> getDeviceIdMap() {
return deviceIdMap;
}
public synchronized void setDeviceIdMap(Map<Long, Device> deviceIdMap) {
this.deviceIdMap = deviceIdMap;
}
public synchronized Map<String, Long> getDeviceCodeMap() {
return deviceCodeMap;
}
public synchronized void setDeviceCodeMap(Map<String, Long> deviceCodeMap) {
this.deviceCodeMap = deviceCodeMap;
}
public synchronized Map<Long, Map<Long, Point>> getPointMap() {
return pointMap;
}
public synchronized void setPointMap(Map<Long, Map<Long, Point>> pointMap) {
this.pointMap = pointMap;
}
public synchronized Map<Long, Map<Long, Map<String, AttributeInfo>>> getPointInfoMap() {
return pointInfoMap;
}
public synchronized void setPointInfoMap(Map<Long, Map<Long, Map<String, AttributeInfo>>> pointInfoMap) {
this.pointInfoMap = pointInfoMap;
}
@@ -16,6 +16,8 @@
package com.pnoker.common.sdk.service;
import com.pnoker.common.model.Device;
import com.pnoker.common.model.Point;
import com.pnoker.common.sdk.bean.AttributeInfo;
import java.util.Map;
@@ -36,9 +38,11 @@ public interface DriverService {
*
* @param driverInfo
* @param pointInfo
* @param device
* @param point
* @return
*/
String read(Map<String, AttributeInfo> driverInfo, Map<String, AttributeInfo> pointInfo);
String read(Map<String, AttributeInfo> driverInfo, Map<String, AttributeInfo> pointInfo, Device device, Point point);
/**
* 写操作
@@ -1,6 +1,8 @@
package com.pnoker.common.sdk.service.impl;
import cn.hutool.core.convert.Convert;
import com.pnoker.common.bean.driver.PointValue;
import com.pnoker.common.constant.Common;
import com.pnoker.common.exception.ServiceException;
import com.pnoker.common.model.Device;
import com.pnoker.common.model.Point;
@@ -9,7 +11,6 @@ import com.pnoker.common.sdk.bean.DriverContext;
import com.pnoker.common.sdk.service.DriverCommandService;
import com.pnoker.common.sdk.service.DriverService;
import com.pnoker.common.sdk.service.message.DriverMessageSender;
import com.pnoker.common.sdk.util.DriverUtils;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
@@ -33,9 +34,9 @@ public class DriverCommandServiceImpl implements DriverCommandService {
@Override
@SneakyThrows
public PointValue read(Long deviceId, Long pointId) {
String rawValue = driverService.read(getDriverInfo(deviceId), getPointInfo(deviceId, pointId));
Point point = getPoint(deviceId, pointId);
PointValue pointValue = new PointValue(deviceId, pointId, rawValue, DriverUtils.processValue(rawValue, point));
Device device = getDevice(deviceId);
String rawValue = driverService.read(getDriverInfo(device), getPointInfo(deviceId, pointId), device, getPoint(device, pointId));
PointValue pointValue = new PointValue(deviceId, pointId, rawValue, processValue(rawValue, getPoint(device, pointId)));
driverMessageSender.driverSender(pointValue);
return pointValue;
}
@@ -43,28 +44,58 @@ public class DriverCommandServiceImpl implements DriverCommandService {
@Override
@SneakyThrows
public Boolean write(Long deviceId, Long pointId, String value) {
return driverService.write(getDriverInfo(deviceId), getPointInfo(deviceId, pointId),
new AttributeInfo(value, getPoint(deviceId, pointId).getType()));
Device device = getDevice(deviceId);
return driverService.write(getDriverInfo(device), getPointInfo(deviceId, pointId),
new AttributeInfo(value, getPoint(device, pointId).getType()));
}
/**
* 获取设备
*
* @param deviceId
* @return
*/
private Device getDevice(Long deviceId) {
Device device = driverContext.getDeviceIdMap().get(deviceId);
if (null == device) {
throw new ServiceException("device does not exist");
}
return device;
}
/**
* 获取 驱动信息
*
* @param deviceId
* @param device
* @return
*/
private Map<String, AttributeInfo> getDriverInfo(Long deviceId) {
Device device = driverContext.getDeviceIdMap().get(deviceId);
if (null == device) {
throw new ServiceException("device does not exist");
}
private Map<String, AttributeInfo> getDriverInfo(Device device) {
Map<String, AttributeInfo> infoMap = driverContext.getDriverInfoMap().get(device.getProfileId());
if (null == infoMap) {
throw new ServiceException("device driver info does not exist");
throw new ServiceException("device profile driver info does not exist");
}
return infoMap;
}
/**
* 获取位号
*
* @param device
* @param pointId
* @return
*/
private Point getPoint(Device device, Long pointId) {
Map<Long, Point> pointMap = driverContext.getPointMap().get(device.getProfileId());
if (null == pointMap) {
throw new ServiceException("device profile does not exist");
}
Point point = pointMap.get(pointId);
if (null == point) {
throw new ServiceException("device point does not exist");
}
return point;
}
/**
* 获取位号信息
*
@@ -73,31 +104,58 @@ public class DriverCommandServiceImpl implements DriverCommandService {
* @return
*/
private Map<String, AttributeInfo> getPointInfo(Long deviceId, Long pointId) {
Map<String, AttributeInfo> infoMap = driverContext.getPointInfoMap().get(deviceId).get(pointId);
Map<Long, Map<String, AttributeInfo>> tmpMap = driverContext.getPointInfoMap().get(deviceId);
if (null == tmpMap) {
throw new ServiceException("device point info does not exist");
}
Map<String, AttributeInfo> infoMap = tmpMap.get(pointId);
if (null == infoMap) {
throw new ServiceException("device point info does not exist");
}
return infoMap;
}
/**
* 获取设备
*
* @param deviceId
* @return
*/
private Device getDevice(Long deviceId) {
return driverContext.getDeviceIdMap().get(deviceId);
}
/**
* 获取位号
* 处理数值
*
* @param deviceId
* @param pointId
* @param value
* @param point point.type : string/int/double/float/long/boolean
* @return
*/
private Point getPoint(Long deviceId, Long pointId) {
return driverContext.getPointMap().get(getDevice(deviceId).getProfileId()).get(pointId);
public String processValue(String value, Point point) {
value = value.trim();
switch (point.getType()) {
case Common.ValueType.STRING:
break;
case Common.ValueType.INT:
case Common.ValueType.LONG:
try {
value = String.format("%.0f",
(Convert.convert(Double.class, value) + point.getBase()) * point.getMultiple());
} catch (Exception e) {
log.warn(e.getMessage());
}
break;
case Common.ValueType.DOUBLE:
case Common.ValueType.FLOAT:
try {
value = String.format(point.getFormat(),
(Convert.convert(Double.class, value) + point.getBase()) * point.getMultiple());
} catch (Exception e) {
log.warn(e.getMessage());
}
break;
case Common.ValueType.BOOLEAN:
try {
value = String.valueOf(Boolean.parseBoolean(value));
} catch (Exception e) {
log.warn(e.getMessage());
}
break;
default:
throw new ServiceException("invalid device point value type");
}
return value;
}
}
@@ -39,6 +39,7 @@ import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.net.InetAddress;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
@@ -185,6 +186,9 @@ public class DriverCommonServiceImpl implements DriverCommonService {
if (rp.isOk()) {
PointInfo info = rp.getData();
PointAttribute attribute = this.pointAttributeMap.get(info.getPointAttributeId());
if (null == driverContext.getPointInfoMap().get(info.getDeviceId())) {
driverContext.getPointInfoMap().put(info.getDeviceId(), new ConcurrentHashMap<>(16));
}
Map<Long, Map<String, AttributeInfo>> map = driverContext.getPointInfoMap().get(info.getDeviceId());
if (null == map.get(info.getPointId())) {
map.put(info.getPointId(), new ConcurrentHashMap<>(16));
@@ -195,7 +199,7 @@ public class DriverCommonServiceImpl implements DriverCommonService {
@Override
public void deletePointInfo(Long pointId, Long attributeId, Long deviceId) {
String attributeName = this.pointAttributeMap.get(deviceId).getName();
String attributeName = this.pointAttributeMap.get(attributeId).getName();
driverContext.getPointInfoMap().get(deviceId).get(pointId).entrySet().removeIf(next -> next.getKey().equals(attributeName));
driverContext.getPointInfoMap().get(deviceId).entrySet().removeIf(next -> next.getValue().size() < 1);
}
@@ -222,6 +226,22 @@ public class DriverCommonServiceImpl implements DriverCommonService {
return registerDriver() && registerDriverAttribute() && registerPointAttribute();
}
/**
* 加载数据
*/
public void loadData() {
log.info("driver initial basic data ……");
List<Long> profileList = getProfileList(driverContext.getDriverId());
this.driverAttributeMap = getDriverAttributeMap(driverContext.getDriverId());
this.pointAttributeMap = getPointAttributeMap(driverContext.getDriverId());
driverContext.setDriverInfoMap(getDriverInfoMap(profileList));
getDeviceMap(profileList);
driverContext.setPointMap(getPointMap(profileList));
driverContext.setPointInfoMap(getPointInfoMap(driverContext.getDeviceIdMap()));
log.info("driver initial basic data is complete");
}
public String getHost() {
try {
InetAddress address = InetAddress.getLocalHost();
@@ -376,21 +396,6 @@ public class DriverCommonServiceImpl implements DriverCommonService {
return true;
}
/**
* 加载数据
*/
public void loadData() {
log.info("driver initial basic data ……");
List<Long> profileList = getProfileList(driverContext.getDriverId());
this.driverAttributeMap = getDriverAttributeMap(driverContext.getDriverId());
driverContext.setDriverInfoMap(getDriverInfoMap(profileList));
getDeviceMap(profileList);
driverContext.setPointMap(getPointMap(profileList));
this.pointAttributeMap = getPointAttributeMap(driverContext.getDriverId());
driverContext.setPointInfoMap(getPointInfoMap(driverContext.getDeviceIdMap()));
log.info("driver initial basic data is complete");
}
/**
* 获取驱动 driver 配置
*
@@ -398,7 +403,7 @@ public class DriverCommonServiceImpl implements DriverCommonService {
* @return
*/
public Map<Long, DriverAttribute> getDriverAttributeMap(long driverId) {
Map<Long, DriverAttribute> infoMap = new ConcurrentHashMap<>(16);
Map<Long, DriverAttribute> infoMap = new HashMap<>(16);
DriverAttributeDto connectInfoDto = new DriverAttributeDto();
connectInfoDto.setPage(new Pages().setSize(-1L)).setDriverId(driverId);
R<Page<DriverAttribute>> rp = driverAttributeClient.list(connectInfoDto);
@@ -417,7 +422,7 @@ public class DriverCommonServiceImpl implements DriverCommonService {
* @return
*/
public Map<Long, PointAttribute> getPointAttributeMap(long driverId) {
Map<Long, PointAttribute> infoMap = new ConcurrentHashMap<>(16);
Map<Long, PointAttribute> infoMap = new HashMap<>(16);
PointAttributeDto pointAttributeDto = new PointAttributeDto();
pointAttributeDto.setPage(new Pages().setSize(-1L)).setDriverId(driverId);
R<Page<PointAttribute>> rp = pointAttributeClient.list(pointAttributeDto);
@@ -1,71 +0,0 @@
package com.pnoker.common.sdk.util;
import com.pnoker.common.exception.ServiceException;
import com.pnoker.common.model.Point;
import lombok.extern.slf4j.Slf4j;
import java.math.BigDecimal;
/**
* @author pnoker
*/
@Slf4j
public class DriverUtils {
/**
* 参数类型
*/
public interface ValueType {
String STRING = "string";
String INT = "int";
String DOUBLE = "double";
String FLOAT = "float";
String LONG = "long";
String BOOLEAN = "boolean";
}
/**
* 处理数值
*
* @param value
* @param point point.type : string/int/double/float/long/boolean
* @return
*/
public static String processValue(String value, Point point) {
value = value.trim();
switch (point.getType()) {
case ValueType.STRING:
break;
case ValueType.INT:
case ValueType.LONG:
try {
value = String.format("%.0f", (getDoubleValue(value) + point.getBase()) * point.getMultiple());
} catch (Exception e) {
log.error(e.getMessage());
}
break;
case ValueType.DOUBLE:
case ValueType.FLOAT:
try {
value = String.format(point.getFormat(), (getDoubleValue(value) + point.getBase()) * point.getMultiple());
} catch (Exception e) {
log.error(e.getMessage());
}
break;
case ValueType.BOOLEAN:
try {
value = String.valueOf(Boolean.parseBoolean(value));
} catch (Exception e) {
log.error(e.getMessage());
}
break;
default:
throw new ServiceException("invalid point value type");
}
return value;
}
private static double getDoubleValue(String value) {
BigDecimal decimal = new BigDecimal(value);
return decimal.doubleValue();
}
}
@@ -0,0 +1,71 @@
package com.pnoker.common.sdk.util;
import cn.hutool.core.convert.Convert;
import com.pnoker.common.constant.Common;
import com.pnoker.common.sdk.bean.AttributeInfo;
import lombok.extern.slf4j.Slf4j;
import java.util.Map;
/**
* @author pnoker
*/
@Slf4j
public class Utils {
/**
* 获取 属性值
*
* @param infoMap
* @param attribute
* @param <T>
* @return
*/
public static <T> T attribute(Map<String, AttributeInfo> infoMap, String attribute) {
return convertValue(infoMap.get(attribute).getType(), infoMap.get(attribute).getValue());
}
/**
* 通过类型转换数据
*
* @param type
* @param value
* @param <T>
* @return
*/
public static <T> T convertValue(String type, String value) {
return Convert.convertByClassName(getTypeClassName(type), value);
}
/**
* 获取基本类型 Class Name
*
* @param type
* @return
*/
private static String getTypeClassName(String type) {
String className = "java.lang.String";
switch (type.toLowerCase()) {
case Common.ValueType.INT:
className = "java.lang.Integer";
break;
case Common.ValueType.DOUBLE:
className = "java.lang.Double";
break;
case Common.ValueType.FLOAT:
className = "java.lang.Float";
break;
case Common.ValueType.LONG:
className = "java.lang.Long";
break;
case Common.ValueType.BOOLEAN:
className = "java.lang.Boolean";
break;
default:
break;
}
return className;
}
}
@@ -1,6 +1,8 @@
package com.pnoker.driver.service.impl;
import cn.hutool.core.util.RandomUtil;
import com.pnoker.common.model.Device;
import com.pnoker.common.model.Point;
import com.pnoker.common.sdk.bean.AttributeInfo;
import com.pnoker.common.sdk.service.DriverService;
import lombok.extern.slf4j.Slf4j;
@@ -8,6 +10,8 @@ import org.springframework.stereotype.Service;
import java.util.Map;
import static com.pnoker.common.sdk.util.Utils.attribute;
/**
* @author pnoker
*/
@@ -21,8 +25,12 @@ public class DriverServiceImpl implements DriverService {
}
@Override
public String read(Map<String, AttributeInfo> driverInfo, Map<String, AttributeInfo> pointInfo) {
String value = String.valueOf(RandomUtil.randomDouble());
public String read(Map<String, AttributeInfo> driverInfo, Map<String, AttributeInfo> pointInfo, Device device, Point point) {
String host = attribute(driverInfo, "host");
Integer port = attribute(driverInfo, "port");
String tag = attribute(pointInfo, "tag");
String value = String.valueOf(RandomUtil.randomDouble(100));
log.info("driverInfo:{},{},pointInfo:{},device:{}.{},point:{}.{},value:{}", host, port, tag, device.getId(), device.getName(), point.getId(), point.getName(), value);
return value;
}