jeecg-boot-base-core/src/main/java/org/jeecg/config/WebSocketConfig.java
@@ -32,7 +32,7 @@ FilterRegistrationBean bean = new FilterRegistrationBean(); bean.setFilter(websocketFilter()); //TODO ä¸´æ¶æ³¨éæï¼æµè¯ä¸çº¿ä¸socketæ»æçé®é¢ bean.addUrlPatterns("/websocket/*","/eoaSocket/*","/eoaNewChatSocket/*", "/newsWebsocket/*", "/vxeSocket/*"); bean.addUrlPatterns("/websocket/*","/eoaSocket/*","/eoaNewChatSocket/*", "/newsWebsocket/*", "/vxeSocket/*","/drySocket/*"); return bean; } jeecg-module-dry/jeecg-module-dry-api/pom.xml
@@ -25,6 +25,28 @@ <artifactId>spring-cloud-starter-alibaba-sentinel</artifactId> </dependency> <!-- <dependency>--> <!-- <groupId>org.eclipse.milo</groupId>--> <!-- <artifactId>sdk-client</artifactId>--> <!-- <version>0.6.11</version>--> <!-- </dependency>--> <!-- <dependency>--> <!-- <groupId>org.eclipse.milo</groupId>--> <!-- <artifactId>sdk-server</artifactId>--> <!-- <version>0.6.11</version>--> <!-- </dependency>--> <!-- <dependency>--> <!-- <groupId>org.bouncycastle</groupId>--> <!-- <artifactId>bcprov-jdk15on</artifactId>--> <!-- <version>1.70</version>--> <!-- </dependency>--> <dependency> <groupId>com.kangaroohy</groupId> <artifactId>milo-spring-boot-starter</artifactId> <version>3.0.4</version> </dependency> </dependencies> <build> <plugins> jeecg-module-dry/jeecg-module-dry-api/src/main/java/org/jeecg/modules/dry/common/CommonDict.java
@@ -5,5 +5,18 @@ public class CommonDict { /** * æ éåå ¸ */ public static Map<String, String> faultDict = new HashMap<>(); /** * æ¥è¦åå ¸ */ public static Map<String, String> waringDict = new HashMap<>(); /** * ç¶æåå ¸ */ public static Map<String, String> statusDict = new HashMap<>(); } jeecg-module-dry/jeecg-module-dry-api/src/main/java/org/jeecg/modules/dry/entity/DryOpcDevice.java
¶Ô±ÈÐÂÎļþ @@ -0,0 +1,61 @@ package org.jeecg.modules.dry.entity; import java.io.Serializable; import java.io.UnsupportedEncodingException; import java.util.Date; import java.math.BigDecimal; import com.baomidou.mybatisplus.annotation.*; import lombok.Data; import com.fasterxml.jackson.annotation.JsonFormat; import org.springframework.format.annotation.DateTimeFormat; import org.jeecgframework.poi.excel.annotation.Excel; import org.jeecg.common.aspect.annotation.Dict; import io.swagger.annotations.ApiModel; import io.swagger.annotations.ApiModelProperty; import lombok.EqualsAndHashCode; import lombok.experimental.Accessors; /** * @Description: dry_opc_device * @Author: jeecg-boot * @Date: 2023-11-28 * @Version: V1.0 */ @Data @TableName("dry_opc_device") @Accessors(chain = true) @EqualsAndHashCode(callSuper = false) @ApiModel(value="dry_opc_device对象", description="dry_opc_device") public class DryOpcDevice implements Serializable { private static final long serialVersionUID = 1L; /**id*/ @TableId(type = IdType.ASSIGN_ID) @ApiModelProperty(value = "id") private java.lang.String id; /**åç§°*/ @Excel(name = "åç§°", width = 15) @ApiModelProperty(value = "åç§°") private java.lang.String name; /**ç¹ä½æ è¯*/ @Excel(name = "ç¹ä½æ è¯", width = 15) @ApiModelProperty(value = "ç¹ä½æ è¯") private java.lang.String identifier; /**æåº*/ @Excel(name = "æåº", width = 15) @ApiModelProperty(value = "æåº") private java.lang.Integer sortOrder; /**ç±»åï¼0 ç¯ï¼1 æå头ï¼*/ @Excel(name = "ç±»åï¼0 ç¯ï¼1 æå头ï¼", width = 15, dicCode = "device_type") @Dict(dicCode = "device_type") @ApiModelProperty(value = "ç±»åï¼0 ç¯ï¼1 æå头ï¼") private java.lang.String type; /**é»è¾å é¤*/ @Excel(name = "é»è¾å é¤", width = 15) @ApiModelProperty(value = "é»è¾å é¤") private java.lang.Integer del; @TableField(exist = false) private boolean value; } jeecg-module-dry/jeecg-module-dry-api/src/main/java/org/jeecg/modules/dry/util/DryUtil.java
¶Ô±ÈÐÂÎļþ @@ -0,0 +1,19 @@ package org.jeecg.modules.dry.util; import org.jeecg.common.constant.CommonConstant; import org.jeecg.common.system.util.JwtUtil; import org.jeecg.common.util.RedisUtil; import org.jeecg.common.util.SpringContextUtils; public class DryUtil { public static String getTemporaryToken() { RedisUtil redisUtil = SpringContextUtils.getBean(RedisUtil.class); // 模æç»å½çæToken String token = JwtUtil.sign("admin", "b668043e3ea4bc2d"); // 设置Tokenç¼åæææ¶é´ä¸º 5 åé redisUtil.set(CommonConstant.PREFIX_USER_TOKEN + token, token); redisUtil.expire(CommonConstant.PREFIX_USER_TOKEN + token, 5 * 60 * 1000); return token; } } jeecg-module-dry/jeecg-module-dry-api/src/main/java/org/jeecg/modules/dry/vo/DryOpcMsgVo.java
¶Ô±ÈÐÂÎļþ @@ -0,0 +1,41 @@ package org.jeecg.modules.dry.vo; import com.baomidou.mybatisplus.annotation.IdType; import com.baomidou.mybatisplus.annotation.TableId; import com.baomidou.mybatisplus.annotation.TableName; import io.swagger.annotations.ApiModel; import io.swagger.annotations.ApiModelProperty; import lombok.Data; import lombok.EqualsAndHashCode; import lombok.experimental.Accessors; import org.jeecg.common.aspect.annotation.Dict; import org.jeecgframework.poi.excel.annotation.Excel; import java.io.Serializable; /** * @Description: dry_opc_device * @Author: jeecg-boot * @Date: 2023-11-28 * @Version: V1.0 */ @Data @Accessors(chain = true) @EqualsAndHashCode(callSuper = false) public class DryOpcMsgVo implements Serializable { private static final long serialVersionUID = 1L; /**ç¹ä½æ è¯*/ @ApiModelProperty(value = "ç¹ä½æ è¯") private String identifier; /** ç¹ä½å¼ **/ private boolean value; public DryOpcMsgVo(String id, boolean value) { this.identifier = id; this.value = value; } } jeecg-module-dry/jeecg-module-dry-api/src/main/java/org/jeecg/modules/dry/vo/DryOrderVo.java
@@ -159,7 +159,16 @@ /**è¸æ±½éç¶æ 0ï¼å ³é 1ï¼å¼å¯*/ private Integer state_valve; /**æ¥è¦**/ private String warning; /**ç¶æ**/ private Map<String, Object> eqp_state; /**设å¤ç¶æ**/ private String eqp_status; private String level; public DryOrderVo(RealTimeDataVo realTimeDataVo) { this.id = IdUtil.fastSimpleUUID(); jeecg-module-dry/jeecg-module-dry-api/src/main/java/org/jeecg/modules/dry/vo/RealTimeDataVo.java
@@ -8,6 +8,7 @@ import java.util.Date; import java.util.List; import java.util.Map; @Data @ToString @@ -84,7 +85,7 @@ /**æ é**/ private String fault; private String eqp_fault; private Integer ai_total_time; @@ -111,6 +112,22 @@ /**å·¥åç¶æ*/ private Integer workorder_status; /**åé¨ä½ç¶æ**/ private Map<String, Object> eqp_state; /**设å¤ç¶æ**/ private String eqp_status; /**è®¾å¤æ¥è¦**/ private String eqp_warning; private String level; /**è®¾å¤æ é**/ // private String fault; /**---------------------ç产记å½ç¸å ³å段å®ä¹---s-------------------------*/ private Boolean report_flag; // æäº¤æ å¿ jeecg-module-dry/jeecg-module-dry-biz/src/main/java/org/jeecg/modules/dry/controller/DryEquipmentController.java
@@ -12,8 +12,10 @@ import org.jeecg.common.api.vo.Result; import org.jeecg.common.config.TenantContext; import org.jeecg.common.system.query.QueryGenerator; import org.jeecg.common.util.RedisUtil; import org.jeecg.common.util.oConvertUtils; import org.jeecg.config.mybatis.MybatisPlusSaasConfig; import org.jeecg.modules.dry.common.CacheConstants; import org.jeecg.modules.dry.entity.DryEquipment; import org.jeecg.modules.dry.service.IDryEqpTypeService; import org.jeecg.modules.dry.service.IDryEquipmentService; @@ -57,6 +59,9 @@ @Autowired private IDryEqpTypeService dryEqpTypeService; @Autowired private RedisUtil redisUtil; /** * å页å表æ¥è¯¢ * @@ -134,7 +139,9 @@ @RequiresPermissions("dry:dry_equipment:edit") @RequestMapping(value = "/edit", method = {RequestMethod.PUT,RequestMethod.POST}) public Result<String> edit(@RequestBody DryEquipment dryEquipment) { redisUtil.del(CacheConstants.RedisKeyEnum.EQP_MAP.getCode()); dryEquipmentService.updateById(dryEquipment); return Result.OK("ç¼è¾æå!"); } @@ -149,6 +156,7 @@ @RequiresPermissions("dry:dry_equipment:delete") @DeleteMapping(value = "/delete") public Result<String> delete(@RequestParam(name="id",required=true) String id) { redisUtil.del(CacheConstants.RedisKeyEnum.EQP_MAP.getCode()); dryEquipmentService.removeById(id); return Result.OK("å 餿å!"); } @@ -164,6 +172,7 @@ @RequiresPermissions("dry:dry_equipment:deleteBatch") @DeleteMapping(value = "/deleteBatch") public Result<String> deleteBatch(@RequestParam(name="ids",required=true) String ids) { redisUtil.del(CacheConstants.RedisKeyEnum.EQP_MAP.getCode()); this.dryEquipmentService.removeByIds(Arrays.asList(ids.split(","))); return Result.OK("æ¹éå 餿å!"); } jeecg-module-dry/jeecg-module-dry-biz/src/main/java/org/jeecg/modules/dry/controller/DryOpcDeviceController.java
¶Ô±ÈÐÂÎļþ @@ -0,0 +1,205 @@ package org.jeecg.modules.dry.controller; import java.util.Arrays; import java.util.List; import java.util.Map; import java.util.stream.Collectors; import java.io.IOException; import java.io.UnsupportedEncodingException; import java.net.URLDecoder; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import com.kangaroohy.milo.model.ReadWriteEntity; import com.kangaroohy.milo.service.MiloService; import org.jeecg.common.api.vo.Result; import org.jeecg.common.system.query.QueryGenerator; import org.jeecg.common.util.oConvertUtils; import org.jeecg.modules.dry.entity.DryOpcDevice; import org.jeecg.modules.dry.service.IDryOpcDeviceService; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.core.metadata.IPage; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import lombok.extern.slf4j.Slf4j; import org.jeecgframework.poi.excel.ExcelImportUtil; import org.jeecgframework.poi.excel.def.NormalExcelConstants; import org.jeecgframework.poi.excel.entity.ExportParams; import org.jeecgframework.poi.excel.entity.ImportParams; import org.jeecgframework.poi.excel.view.JeecgEntityExcelView; import org.jeecg.common.system.base.controller.JeecgController; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.*; import org.springframework.web.multipart.MultipartFile; import org.springframework.web.multipart.MultipartHttpServletRequest; import org.springframework.web.servlet.ModelAndView; import com.alibaba.fastjson.JSON; import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; import org.jeecg.common.aspect.annotation.AutoLog; import org.apache.shiro.authz.annotation.RequiresPermissions; /** * @Description: dry_opc_device * @Author: jeecg-boot * @Date: 2023-11-28 * @Version: V1.0 */ @Api(tags="dry_opc_device") @RestController @RequestMapping("/dry/dryOpcDevice") @Slf4j public class DryOpcDeviceController extends JeecgController<DryOpcDevice, IDryOpcDeviceService> { @Autowired private IDryOpcDeviceService dryOpcDeviceService; @Autowired private MiloService miloService; /** * å页å表æ¥è¯¢ * * @param dryOpcDevice * @param pageNo * @param pageSize * @param req * @return */ //@AutoLog(value = "dry_opc_device-å页å表æ¥è¯¢") @ApiOperation(value="dry_opc_device-å页å表æ¥è¯¢", notes="dry_opc_device-å页å表æ¥è¯¢") @GetMapping(value = "/list") public Result<IPage<DryOpcDevice>> queryPageList(DryOpcDevice dryOpcDevice, @RequestParam(name="pageNo", defaultValue="1") Integer pageNo, @RequestParam(name="pageSize", defaultValue="10") Integer pageSize, HttpServletRequest req) { QueryWrapper<DryOpcDevice> queryWrapper = QueryGenerator.initQueryWrapper(dryOpcDevice, req.getParameterMap()); Page<DryOpcDevice> page = new Page<DryOpcDevice>(pageNo, pageSize); IPage<DryOpcDevice> pageList = dryOpcDeviceService.page(page, queryWrapper); return Result.OK(pageList); } @GetMapping(value = "/listAll") public Result<List<DryOpcDevice>> queryList(DryOpcDevice dryOpcDevice, HttpServletRequest req) { QueryWrapper<DryOpcDevice> queryWrapper = QueryGenerator.initQueryWrapper(dryOpcDevice, req.getParameterMap()); queryWrapper.orderByAsc("sort_order"); List<DryOpcDevice> list = dryOpcDeviceService.list(queryWrapper); list.forEach(item -> { try { ReadWriteEntity readWriteEntity = miloService.readFromOpcUa(item.getIdentifier()); item.setValue((Boolean) readWriteEntity.getValue()); } catch (Exception e) { throw new RuntimeException(e); } }); return Result.OK(list); } /** * æ·»å * * @param dryOpcDevice * @return */ @AutoLog(value = "dry_opc_device-æ·»å ") @ApiOperation(value="dry_opc_device-æ·»å ", notes="dry_opc_device-æ·»å ") @RequiresPermissions("dry:dry_opc_device:add") @PostMapping(value = "/add") public Result<String> add(@RequestBody DryOpcDevice dryOpcDevice) { dryOpcDeviceService.save(dryOpcDevice); return Result.OK("æ·»å æåï¼"); } /** * ç¼è¾ * * @param dryOpcDevice * @return */ @AutoLog(value = "dry_opc_device-ç¼è¾") @ApiOperation(value="dry_opc_device-ç¼è¾", notes="dry_opc_device-ç¼è¾") @RequiresPermissions("dry:dry_opc_device:edit") @RequestMapping(value = "/edit", method = {RequestMethod.PUT,RequestMethod.POST}) public Result<String> edit(@RequestBody DryOpcDevice dryOpcDevice) { dryOpcDeviceService.updateById(dryOpcDevice); return Result.OK("ç¼è¾æå!"); } /** * éè¿idå é¤ * * @param id * @return */ @AutoLog(value = "dry_opc_device-éè¿idå é¤") @ApiOperation(value="dry_opc_device-éè¿idå é¤", notes="dry_opc_device-éè¿idå é¤") @RequiresPermissions("dry:dry_opc_device:delete") @DeleteMapping(value = "/delete") public Result<String> delete(@RequestParam(name="id",required=true) String id) { dryOpcDeviceService.removeById(id); return Result.OK("å 餿å!"); } /** * æ¹éå é¤ * * @param ids * @return */ @AutoLog(value = "dry_opc_device-æ¹éå é¤") @ApiOperation(value="dry_opc_device-æ¹éå é¤", notes="dry_opc_device-æ¹éå é¤") @RequiresPermissions("dry:dry_opc_device:deleteBatch") @DeleteMapping(value = "/deleteBatch") public Result<String> deleteBatch(@RequestParam(name="ids",required=true) String ids) { this.dryOpcDeviceService.removeByIds(Arrays.asList(ids.split(","))); return Result.OK("æ¹éå 餿å!"); } /** * éè¿idæ¥è¯¢ * * @param id * @return */ //@AutoLog(value = "dry_opc_device-éè¿idæ¥è¯¢") @ApiOperation(value="dry_opc_device-éè¿idæ¥è¯¢", notes="dry_opc_device-éè¿idæ¥è¯¢") @GetMapping(value = "/queryById") public Result<DryOpcDevice> queryById(@RequestParam(name="id",required=true) String id) { DryOpcDevice dryOpcDevice = dryOpcDeviceService.getById(id); if(dryOpcDevice==null) { return Result.error("æªæ¾å°å¯¹åºæ°æ®"); } return Result.OK(dryOpcDevice); } /** * 导åºexcel * * @param request * @param dryOpcDevice */ @RequiresPermissions("dry:dry_opc_device:exportXls") @RequestMapping(value = "/exportXls") public ModelAndView exportXls(HttpServletRequest request, DryOpcDevice dryOpcDevice) { return super.exportXls(request, dryOpcDevice, DryOpcDevice.class, "dry_opc_device"); } /** * éè¿excelå¯¼å ¥æ°æ® * * @param request * @param response * @return */ @RequiresPermissions("dry:dry_opc_device:importExcel") @RequestMapping(value = "/importExcel", method = RequestMethod.POST) public Result<?> importExcel(HttpServletRequest request, HttpServletResponse response) { return super.importExcel(request, response, DryOpcDevice.class); } } jeecg-module-dry/jeecg-module-dry-biz/src/main/java/org/jeecg/modules/dry/controller/OpcController.java
¶Ô±ÈÐÂÎļþ @@ -0,0 +1,67 @@ package org.jeecg.modules.dry.controller; import com.kangaroohy.milo.model.ReadWriteEntity; import com.kangaroohy.milo.service.MiloService; import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; import lombok.extern.slf4j.Slf4j; import org.eclipse.milo.opcua.sdk.client.OpcUaClient; import org.eclipse.milo.opcua.stack.core.types.builtin.DataValue; import org.eclipse.milo.opcua.stack.core.types.builtin.NodeId; import org.eclipse.milo.opcua.stack.core.types.builtin.StatusCode; import org.eclipse.milo.opcua.stack.core.types.builtin.Variant; import org.jeecg.common.api.vo.Result; import org.jeecg.modules.dry.common.OPCUA; import org.jeecg.modules.dry.entity.DryOpcDevice; import org.jeecg.modules.dry.service.IDryOpcDeviceService; import org.jeecg.modules.dry.vo.CommandMessageVo; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; import java.util.List; import java.util.concurrent.ExecutionException; /** * opcæ§å¶å¨ï¼ç¨äºæ§å¶ç°åºæåå¤´çµæºï¼ç¯çå¼å ³ */ @Api(tags="OPCæ§å¶å¨") @RestController @RequestMapping("/dry/opc") @Slf4j public class OpcController { @Autowired private MiloService miloService; @Autowired private IDryOpcDeviceService opcDeviceService; @ApiOperation(value="å鿧嶿令", notes="åæå¡ç«¯å鿧嶿令ï¼ç±æå¡ç«¯è½¬åç»æ§å¶æ¨¡å") @PostMapping("/sendWriteCommand") public Result<?> sendWriteCommand(@RequestBody CommandMessageVo msgVo) throws Exception { miloService.writeToOpcUa(ReadWriteEntity.builder() .identifier(msgVo.getCode()) //Kep䏿¯Booleanç±»å .value(Boolean.valueOf(msgVo.getMsg())) .build()); return Result.OK(); } @ApiOperation(value="å鿧嶿令", notes="åæå¡ç«¯å鿧嶿令ï¼ç±æå¡ç«¯è½¬åç»æ§å¶æ¨¡å") @PostMapping("/initDevice") public Result<?> initDevice() throws Exception { List<DryOpcDevice> list = opcDeviceService.list(); list.forEach(item -> { }); return Result.OK(); } } jeecg-module-dry/jeecg-module-dry-biz/src/main/java/org/jeecg/modules/dry/listener/InitListener.java
@@ -4,8 +4,10 @@ import com.alibaba.fastjson.JSONArray; import com.alibaba.fastjson.JSONObject; import com.google.common.io.ByteStreams; import org.eclipse.milo.opcua.sdk.client.OpcUaClient; import org.jeecg.modules.dry.common.CacheConstants; import org.jeecg.modules.dry.common.CommonDict; import org.jeecg.modules.dry.common.OPCUA; import org.jeecg.modules.dry.vo.DryFault; import org.springframework.boot.context.event.ApplicationStartedEvent; import org.springframework.context.ApplicationListener; @@ -17,10 +19,17 @@ import java.util.List; import java.util.Map; @Component //@Component public class InitListener implements ApplicationListener<ApplicationStartedEvent> { @Override public void onApplicationEvent(ApplicationStartedEvent event) { // try { // OpcUaClient client = OPCUA.createClient(); // client.connect().get(); // OPCUA.managedSubscriptionEvent(client); // } catch (Exception e) { // throw new RuntimeException(e); // } InputStream fault = getClass().getResourceAsStream("/fault.json"); try { JSONObject jsonObject = JSONObject.parseObject(fault, JSONObject.class); jeecg-module-dry/jeecg-module-dry-biz/src/main/java/org/jeecg/modules/dry/mapper/DryOpcDeviceMapper.java
¶Ô±ÈÐÂÎļþ @@ -0,0 +1,17 @@ package org.jeecg.modules.dry.mapper; import java.util.List; import org.apache.ibatis.annotations.Param; import org.jeecg.modules.dry.entity.DryOpcDevice; import com.baomidou.mybatisplus.core.mapper.BaseMapper; /** * @Description: dry_opc_device * @Author: jeecg-boot * @Date: 2023-11-28 * @Version: V1.0 */ public interface DryOpcDeviceMapper extends BaseMapper<DryOpcDevice> { } jeecg-module-dry/jeecg-module-dry-biz/src/main/java/org/jeecg/modules/dry/mapper/xml/DryOpcDeviceMapper.xml
¶Ô±ÈÐÂÎļþ @@ -0,0 +1,5 @@ <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <mapper namespace="org.jeecg.modules.dry.mapper.DryOpcDeviceMapper"> </mapper> jeecg-module-dry/jeecg-module-dry-biz/src/main/java/org/jeecg/modules/dry/runner/OpcCustomRunner.java
¶Ô±ÈÐÂÎļþ @@ -0,0 +1,58 @@ package org.jeecg.modules.dry.runner; import com.alibaba.fastjson.JSON; import com.kangaroohy.milo.service.MiloService; import lombok.extern.slf4j.Slf4j; import org.jeecg.modules.dry.entity.DryOpcDevice; import org.jeecg.modules.dry.service.IDryOpcDeviceService; import org.jeecg.modules.dry.vo.DryOpcMsgVo; import org.jeecg.modules.dry.websocket.DrySocket; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.ApplicationArguments; import org.springframework.boot.ApplicationRunner; import org.springframework.stereotype.Component; import java.util.ArrayList; import java.util.List; @Component @Slf4j public class OpcCustomRunner implements ApplicationRunner { @Autowired private MiloService miloService; @Autowired private IDryOpcDeviceService dryOpcDeviceService; @Autowired private DrySocket drySocket; @Override public void run(ApplicationArguments args) throws Exception { subscript(); } private void subscript() throws Exception { List<String> ids = new ArrayList<>(); List<DryOpcDevice> list = dryOpcDeviceService.list(); list.forEach(item -> { ids.add(item.getIdentifier()); }); // ids.add("éé 1.è®¾å¤ 1.æ è®° 1"); // ids.add("éé 1.è®¾å¤ 1.æ è®° 2"); // ids.add("channel1.device1.tag1"); // ids.add("channel1.device1.tag2"); // ids.add("channel1.device1.tag3"); // ids.add("channel1.device1.tag4"); // ids.add("channel1.device1.tag5"); // ids.add("channel1.device1.tag6"); miloService.subscriptionFromOpcUa(ids, (id,value)->{ log.info("subscription ç¹ä½ï¼{} 订é å°æ¶æ¯ï¼{}", id, value); DryOpcMsgVo dryOpcMsgVo = new DryOpcMsgVo(id, (Boolean) value); drySocket.pushMessage("1003", JSON.toJSONString(dryOpcMsgVo)); } ); } } jeecg-module-dry/jeecg-module-dry-biz/src/main/java/org/jeecg/modules/dry/service/IDryOpcDeviceService.java
¶Ô±ÈÐÂÎļþ @@ -0,0 +1,14 @@ package org.jeecg.modules.dry.service; import org.jeecg.modules.dry.entity.DryOpcDevice; import com.baomidou.mybatisplus.extension.service.IService; /** * @Description: dry_opc_device * @Author: jeecg-boot * @Date: 2023-11-28 * @Version: V1.0 */ public interface IDryOpcDeviceService extends IService<DryOpcDevice> { } jeecg-module-dry/jeecg-module-dry-biz/src/main/java/org/jeecg/modules/dry/service/impl/DryOpcDeviceServiceImpl.java
¶Ô±ÈÐÂÎļþ @@ -0,0 +1,19 @@ package org.jeecg.modules.dry.service.impl; import org.jeecg.modules.dry.entity.DryOpcDevice; import org.jeecg.modules.dry.mapper.DryOpcDeviceMapper; import org.jeecg.modules.dry.service.IDryOpcDeviceService; import org.springframework.stereotype.Service; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; /** * @Description: dry_opc_device * @Author: jeecg-boot * @Date: 2023-11-28 * @Version: V1.0 */ @Service public class DryOpcDeviceServiceImpl extends ServiceImpl<DryOpcDeviceMapper, DryOpcDevice> implements IDryOpcDeviceService { } jeecg-module-dry/jeecg-module-dry-biz/src/main/java/org/jeecg/modules/dry/service/impl/DryRealTimeDataServiceImpl.java
@@ -8,14 +8,21 @@ import org.apache.mina.core.service.IoAcceptor; import org.apache.mina.core.service.IoHandler; import org.apache.mina.core.session.IoSession; import org.jeecg.common.api.CommonAPI; import org.jeecg.common.api.vo.Result; import org.jeecg.common.config.TenantContext; import org.jeecg.common.config.mqtoken.UserTokenContext; import org.jeecg.common.constant.CommonConstant; import org.jeecg.common.system.util.JwtUtil; import org.jeecg.common.util.RedisUtil; import org.jeecg.common.util.SpringContextUtils; import org.jeecg.modules.dry.api.JeecgSystemApi; import org.jeecg.modules.dry.common.CacheConstants; import org.jeecg.modules.dry.entity.*; import org.jeecg.modules.dry.service.*; import org.jeecg.modules.dry.socket.ServerHandler; import org.jeecg.modules.dry.socket.SocketServerConfig; import org.jeecg.modules.dry.util.DryUtil; import org.jeecg.modules.dry.vo.*; import org.jetbrains.annotations.NotNull; import org.springframework.beans.factory.annotation.Autowired; @@ -52,13 +59,31 @@ private IDryProdRecordService prodRecordService; @Autowired private IoAcceptor ioAcceptor; private CommonAPI commonAPI; private String token; public String getTemporaryToken() { if (token == null) { RedisUtil redisUtil = SpringContextUtils.getBean(RedisUtil.class); // 模æç»å½çæToken token = JwtUtil.sign("admin", "b668043e3ea4bc2d"); // 设置Tokenç¼åæææ¶é´ä¸º 5 åé redisUtil.set(CommonConstant.PREFIX_USER_TOKEN + token, token); redisUtil.expire(CommonConstant.PREFIX_USER_TOKEN + token, 5 * 60 * 1000); } return token; } @Override @Transactional public Result<?> realTimeDataHandle(RealTimeDataVo realTimeDataVo) { TenantContext.setTenant(realTimeDataVo.getTenantid()+""); log.info("宿¶æ°æ®ï¼"+realTimeDataVo.toString()); // 1 æ¥è¯¢æå建工å // 1.1 ä»redisååºå·¥åç¼å @@ -99,12 +124,12 @@ orderVo.setState_windbox(realTimeDataVo.getState_windbox()); orderVo.setState_valve(realTimeDataVo.getState_valve()); orderVo.setOrderStatus(realTimeDataVo.getWorkorder_status()); orderVo.setEqp_status(realTimeDataVo.getEqp_status()); orderVo.setEqp_state(realTimeDataVo.getEqp_state()); orderVo.setWarning(realTimeDataVo.getEqp_warning()); orderVo.setFault(realTimeDataVo.getEqp_fault()); orderVo.setLevel(realTimeDataVo.getLevel()); String fault = realTimeDataVo.getFault(); // String[] split = fault.split(","); // for (String s : split) { // // } DryOrderTrendVo trendVo = new DryOrderTrendVo(realTimeDataVo); // 2.2 ä¿åå·¥å嫿°´çåå æ ééåå @@ -293,6 +318,7 @@ LambdaQueryWrapper<DryEquipment> queryWrapper = new LambdaQueryWrapper<>(); queryWrapper.eq(DryEquipment::getTenantId, realTimeDataVo.getTenantid()); queryWrapper.eq(DryEquipment::getEnable, "Y"); jeecg-module-dry/jeecg-module-dry-biz/src/main/java/org/jeecg/modules/dry/websocket/DrySocket.java
@@ -1,214 +1,146 @@ package org.jeecg.modules.dry.websocket; import cn.hutool.core.bean.BeanUtil; import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSONObject; import lombok.extern.slf4j.Slf4j; import org.jeecg.common.constant.DrySocketConst; import org.jeecg.common.util.SpringContextUtils; import org.jeecg.modules.dry.service.IDryRealTimeDataService; import org.jeecg.modules.dry.vo.RealTimeDataVo; import org.springframework.beans.factory.annotation.Autowired; import org.jeecg.common.constant.WebsocketConst; import org.springframework.stereotype.Component; import javax.websocket.OnClose; import javax.websocket.OnMessage; import javax.websocket.OnOpen; import javax.websocket.Session; import javax.websocket.*; import javax.websocket.server.PathParam; import javax.websocket.server.ServerEndpoint; import java.util.Collection; import java.util.HashMap; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; @Slf4j /** * @Author scott * @Date 2019/11/29 9:41 * @Description: æ¤æ³¨è§£ç¸å½äºè®¾ç½®è®¿é®URL */ @Component @ServerEndpoint("/drySocket/{tenantId}/{machineId}") @Slf4j @ServerEndpoint("/drySocket/{tenantId}") public class DrySocket { /** * å½å session */ private Session session; /** * å½åç§æ·id */ private String tenantId; /** * 设å¤idï¼ç¨äºæ è¯åä¸ç§æ·ï¼ä¸å设å¤çæ°æ® */ private String machineId; /** * å½åsocketå¯ä¸id */ private String socketId; /**线ç¨å®å ¨Map*/ private static ConcurrentHashMap<String, Session> sessionPool = new ConcurrentHashMap<>(); /** * ç§æ·è¿æ¥æ± ï¼å å«åä¸ªç§æ·çææsocketè¿æ¥ï¼ * å 为ä¸ä¸ªç§æ·å¯è½æå¼å¤ä¸ªè®¾å¤ï¼å¤ä¸ªè®¾å¤å°±ä¼æå¤ä¸ªè¿æ¥ï¼ * keyæ¯tenantIdï¼valueæ¯Map对象ï¼åMapçkeyæ¯machineIdï¼valueæ¯drySocket对象 */ private static Map<String, Map<String, DrySocket>> tenantPool = new HashMap<>(); /** * è¿æ¥æ± ï¼å 嫿æWebSocketè¿æ¥ï¼ * keyæ¯socketIdï¼valueæ¯drySocket对象 */ private static Map<String, DrySocket> machinePool = new HashMap<>(); /** * è·åæä¸ªç§æ·ææçè®¾å¤ */ public static Map<String, DrySocket> getTenantPool(String tenantId) { return tenantPool.computeIfAbsent(tenantId, k -> new HashMap<>(5)); } /** * åå½åç§æ·åéæ¶æ¯ * * @param message æ¶æ¯å 容 */ public void sendMessage(String message) { try { this.session.getAsyncRemote().sendText(message); } catch (Exception e) { log.error("ãdrySocketãæ¶æ¯åé失败ï¼" + e.getMessage()); } } /** * å°è£ æ¶æ¯json * * @param data æ¶æ¯å 容 */ public static String packageMessage(String type, Object data) { JSONObject message = new JSONObject(); message.put(DrySocketConst.TYPE, type); message.put(DrySocketConst.DATA, data); return message.toJSONString(); } /** * åæå®ç§æ·çææè®¾å¤åéæ¶æ¯ * * @param tenantId æ¥æ¶æ¶æ¯çç§æ·ID * @param message æ¶æ¯å 容 */ public static void sendMessageTo(String tenantId, String message) { Collection<DrySocket> values = getTenantPool(tenantId).values(); if (values.size() > 0) { for (DrySocket socketItem : values) { socketItem.sendMessage(message); } } else { log.warn("ãdrySocketãæ¶æ¯åé失败ï¼tenantId\"" + tenantId + "\"ä¸å卿æªå¨çº¿ï¼"); } } /** * åæå®ç§æ·çæå®è®¾å¤åéæ¶æ¯ * * @param tenantId æ¥æ¶æ¶æ¯çç§æ·ID * @param message æ¶æ¯å 容 */ public static void sendMessageTo(String tenantId, String machineId, String message) { DrySocket socketItem = getTenantPool(tenantId).get(machineId); if (socketItem != null) { socketItem.sendMessage(message); } else { log.warn("ãdrySocketãæ¶æ¯åé失败ï¼tenantId\"" + tenantId + "\"çmachineId\"" + machineId + "\"ä¸å卿æªå¨çº¿ï¼"); } } /** * åå¤ä¸ªç§æ·çææè®¾å¤åéæ¶æ¯ * * @param tenantIds æ¥æ¶æ¶æ¯çç§æ·IDæ°ç» * @param message æ¶æ¯å 容 */ public static void sendMessageTo(String[] tenantIds, String message) { for (String tenantId : tenantIds) { DrySocket.sendMessageTo(tenantId, message); } } /** * åææç§æ·çææè®¾å¤åéæ¶æ¯ * * @param message æ¶æ¯å 容 */ public static void sendMessageToAll(String message) { for (DrySocket socketItem : machinePool.values()) { socketItem.sendMessage(message); } } /** * websocket å¼å¯è¿æ¥ */ //==========ãwebsocketæ¥åãæ¨éæ¶æ¯çæ¹æ³ ââ å ·ä½æå¡èç¹æ¨éwsæ¶æ¯ã======================================================================================== @OnOpen public void onOpen(Session session, @PathParam("tenantId") String tenantId, @PathParam("machineId") String machineId) { public void onOpen(Session session, @PathParam(value = "tenantId") String tenantId) { try { this.tenantId = tenantId; this.machineId = machineId; this.socketId = tenantId + machineId; this.session = session; machinePool.put(this.socketId, this); getTenantPool(tenantId).put(this.machineId, this); log.info("ãdrySocketãææ°çè¿æ¥ï¼æ»æ°ä¸º:" + machinePool.size()); } catch (Exception ignored) { sessionPool.put(tenantId, session); log.info("ãç³»ç» WebSocketãææ°çè¿æ¥ï¼æ»æ°ä¸º:" + sessionPool.size()); } catch (Exception e) { } } /** * websocket æå¼è¿æ¥ */ @OnClose public void onClose() { public void onClose(@PathParam("tenantId") String tenantId) { try { machinePool.remove(this.socketId); getTenantPool(this.tenantId).remove(this.machineId); log.info("ãdrySocketãè¿æ¥æå¼ï¼æ»æ°ä¸º:" + machinePool.size()); } catch (Exception ignored) { sessionPool.remove(tenantId); log.info("ãç³»ç» WebSocketãè¿æ¥æå¼ï¼æ»æ°ä¸º:" + sessionPool.size()); } catch (Exception e) { e.printStackTrace(); } } /** * websocket æ¶å°æ¶æ¯ * wsæ¨éæ¶æ¯ * * @param tenantId * @param message */ public void pushMessage(String tenantId, String message) { for (Map.Entry<String, Session> item : sessionPool.entrySet()) { //userId keyå¼= {ç¨æ·id + "_"+ ç»å½tokençmd5串} //TODO vue2æªæ¹keyæ°è§åï¼ææ¶ä¸å½±åé»è¾ if (item.getKey().contains(tenantId)) { Session session = item.getValue(); try { //update-begin-author:taoyan date:20211012 for: websocketæ¥é https://gitee.com/jeecg/jeecg-boot/issues/I4C0MU synchronized (session){ log.info("ãç³»ç» WebSocketãæ¨éåäººæ¶æ¯:" + message); session.getBasicRemote().sendText(message); } //update-end-author:taoyan date:20211012 for: websocketæ¥é https://gitee.com/jeecg/jeecg-boot/issues/I4C0MU } catch (Exception e) { log.error(e.getMessage(),e); } } } } /** * wséåç¾¤åæ¶æ¯ */ public void pushMessage(String message) { try { for (Map.Entry<String, Session> item : sessionPool.entrySet()) { try { item.getValue().getAsyncRemote().sendText(message); } catch (Exception e) { log.error(e.getMessage(), e); } } log.info("ãç³»ç» WebSocketãç¾¤åæ¶æ¯:" + message); } catch (Exception e) { log.error(e.getMessage(), e); } } /** * wsæ¥å客æ·ç«¯æ¶æ¯ */ @OnMessage public void onMessage(String message) { log.info("ãdrySocketãonMessage:" + message); IDryRealTimeDataService realTimeDataService = SpringContextUtils.getBean(IDryRealTimeDataService.class); JSONObject json; try { json = JSON.parseObject(message); } catch (Exception e) { log.warn("ãdrySocketãæ¶å°ä¸åæ³çæ¶æ¯:" + message); return; } String type = json.getString(DrySocketConst.TYPE); switch (type) { // å¿è·³æ£æµ case DrySocketConst.TYPE_HB: this.sendMessage(DrySocket.packageMessage(type, true)); break; // 宿¶æ°æ®å¤ç case DrySocketConst.TYPE_RDT: Object o = json.get(DrySocketConst.DATA); RealTimeDataVo realTimeDataVo = BeanUtil.toBean(o, RealTimeDataVo.class); realTimeDataService.realTimeDataHandle(realTimeDataVo); break; default: log.warn("ãdrySocketãæ¶å°ä¸è¯å«çæ¶æ¯ç±»å:" + type); break; public void onMessage(String message, @PathParam(value = "tenantId") String tenantId) { if(!"ping".equals(message) && !WebsocketConst.CMD_CHECK.equals(message)){ log.info("ãç³»ç» WebSocketãæ¶å°å®¢æ·ç«¯æ¶æ¯:" + message); }else{ log.debug("ãç³»ç» WebSocketãæ¶å°å®¢æ·ç«¯æ¶æ¯:" + message); } // //------------------------------------------------------------------------------ // JSONObject obj = new JSONObject(); // //ä¸å¡ç±»å // obj.put(WebsocketConst.MSG_CMD, WebsocketConst.CMD_CHECK); // //æ¶æ¯å 容 // obj.put(WebsocketConst.MSG_TXT, "å¿è·³ååº"); // this.pushMessage(userId, obj.toJSONString()); // //------------------------------------------------------------------------------ } /** * é ç½®é误信æ¯å¤ç * * @param session * @param t */ @OnError public void onError(Session session, Throwable t) { log.warn("ãç³»ç» WebSocketãæ¶æ¯åºç°é误"); t.printStackTrace(); } //==========ãç³»ç» WebSocketæ¥åãæ¨éæ¶æ¯çæ¹æ³ ââ å ·ä½æå¡èç¹æ¨éwsæ¶æ¯ã======================================================================================== //==========ãéç¨redisåå¸è®¢é 模å¼ââæ¨éæ¶æ¯ã======================================================================================== /** * æ¤ä¸ºåç¹æ¶æ¯(å¤äºº) redis * * @param userIds * @param message */ // public void sendMessage(String[] userIds, String message) { // for (String userId : userIds) { // sendMessage(userId, message); // } // } //=======ãéç¨redisåå¸è®¢é 模å¼ââæ¨éæ¶æ¯ã========================================================================================== } jeecg-module-dry/jeecg-module-dry-start/src/main/resources/application.yml
jeecg-module-system/jeecg-system-start/src/main/resources/application.yml
@@ -3,3 +3,6 @@ name: jeecg-system profiles: active: '@profile.name@' cloud: inetutils: preferred-networks: 192.168