Browse Source

---优化PLC心跳回写
---优化设备读写日志查询
---库位视图添加初始化空托功能

zhifei 1 year ago
parent
commit
b7bee4d18c

+ 6 - 0
ruoyi-admin/src/main/java/com/ruoyi/web/controller/warewms/ams/LocationViewController.java

@@ -75,6 +75,12 @@ public class LocationViewController extends BaseController {
         return AjaxResult.success(invLotLocIdLotattVOS);
     }
 
+    @GetMapping(value = "/initEmptyTray/{locationId}")
+    public AjaxResult initEmptyTray(@PathVariable("locationId") Long locationId) {
+        return invLotLocIdService.initEmptyTray(locationId);
+    }
+
+
     @GetMapping("/lotattConfigList")
     public AjaxResult lotattConfigList() {
         return AjaxResult.success(lotattConfigService.queryLotattConfigList());

+ 45 - 8
ruoyi-admin/src/main/java/com/ruoyi/web/controller/warewms/test/ModbusTestController.java

@@ -1,21 +1,58 @@
 package com.ruoyi.web.controller.warewms.test;
 
+import com.ruoyi.hard.modbus.tcp.ChargingMachineClient;
 import io.swagger.annotations.Api;
-import org.springframework.web.bind.annotation.RequestMapping;
-import org.springframework.web.bind.annotation.RestController;
+import io.swagger.annotations.ApiOperation;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+
+import java.util.Map;
 
 /**
- * @author JWK
- * @version 1.0
- * @date 2022/11/14 14:52
+ * Created by IntelliJ IDEA.
+ * User: jwk
+ * Date: 2022/9/10
  */
-@Api("Modbus测试")
+@Api(description = "充电机调试")
+@Slf4j
 @RestController
 @RequestMapping("/api/modbus")
 public class ModbusTestController {
 
-    public static void main(String[] args) {
-        System.out.println("test");
+    @Autowired(required = false)
+    private ChargingMachineClient modbusTcpChargerClient;
+
+
+    @ApiOperation("充电机状态")
+    @RequestMapping(value = "chargerStatus", method = RequestMethod.GET)
+    public Map<String, Boolean> chargerStatus(String machineNo) throws Exception {
+        if (modbusTcpChargerClient == null) {
+            return null;
+        }
+        ChargingMachineClient.MACHINE_NO value = ChargingMachineClient.MACHINE_NO.valueOf(machineNo);
+        if (value == null) {
+            return null;
+        }
+        return modbusTcpChargerClient.getStatusNameMapping(value);
     }
 
+    @ApiOperation("开启充电机")
+    @PostMapping("start")
+    public boolean start01(){
+        return modbusTcpChargerClient.operation(ChargingMachineClient.CHARGER_ADDRESS_MEANING.START
+                , ChargingMachineClient.MACHINE_NO.B);
+    }
+    @ApiOperation("关闭充电机")
+    @PostMapping("stop")
+    public boolean stop01(){
+        return modbusTcpChargerClient.operation(ChargingMachineClient.CHARGER_ADDRESS_MEANING.STOP
+                , ChargingMachineClient.MACHINE_NO.B);
+    }
+    @ApiOperation("充电机放电")
+    @PostMapping("charge")
+    public boolean charge01(){
+        return modbusTcpChargerClient.operation(ChargingMachineClient.CHARGER_ADDRESS_MEANING.DISCHARGE
+                , ChargingMachineClient.MACHINE_NO.B);
+    }
 }

+ 8 - 8
ruoyi-admin/src/main/resources/application-prod.yml

@@ -82,26 +82,26 @@ plc:
         enable: true
         name: packingMachine_1Plc
         ePlcType: S1200
-        heartbeat: DB5000.2
-        confirmTheStatus:
+        heartbeat: DB5001.2.0
+        confirmTheStatus: DB5000.2.0
     plcList[1]:
         ip: 192.168.10.102
         enable: true
         name: packingMachine_2Plc
         ePlcType: S1200
-        heartbeat: DB5000.2
-        confirmTheStatus:
+        heartbeat: DB5001.2.0
+        confirmTheStatus: DB5000.2.0
     plcList[2]:
         ip: 192.168.10.103
         enable: true
         name: packingMachine_3Plc
         ePlcType: S1200
-        heartbeat: DB5000.2
-        confirmTheStatus:
+        heartbeat: DB5001.2.0
+        confirmTheStatus: DB5000.2.0
     plcList[3]:
         ip: 192.168.10.104
         enable: true
         name: stackingMachinePlc
         ePlcType: S1200
-        heartbeat: DB5000.2
-        confirmTheStatus:
+        heartbeat: DB5001.2.0
+        confirmTheStatus: DB5000.2.0

+ 1 - 1
ruoyi-admin/src/main/resources/application.yml

@@ -37,7 +37,7 @@ spring:
     # 国际化资源文件路径
     basename: i18n/messages
   profiles:
-    active: prod
+    active: dev
   # 文件上传
   servlet:
     multipart:

+ 4 - 4
ruoyi-dongfangyaiye/src/main/java/com/ruoyi/taiye/service/impl/DeviceLogServiceImpl.java

@@ -76,6 +76,10 @@ public class DeviceLogServiceImpl implements IDeviceLogService
     public int insertDeviceLog(DeviceLog deviceLog)
     {
         deviceLog.setCreateTime(DateUtils.getNowDate());
+        if (StringUtils.isEmpty( deviceLog.getDeviceName())){
+            DeviceEnum deviceEnum = DeviceEnum.valueOf(deviceLog.getDeviceId());
+            deviceLog.setDeviceName(deviceEnum.getMetadata());
+        }
         return deviceLogMapper.insertDeviceLog(deviceLog);
     }
 
@@ -89,10 +93,6 @@ public class DeviceLogServiceImpl implements IDeviceLogService
     public int updateDeviceLog(DeviceLog deviceLog)
     {
         deviceLog.setUpdateTime(DateUtils.getNowDate());
-        if (StringUtils.isEmpty( deviceLog.getDeviceName())){
-            DeviceEnum deviceEnum = DeviceEnum.valueOf(deviceLog.getDeviceId());
-            deviceLog.setDeviceName(deviceEnum.getMetadata());
-        }
         return deviceLogMapper.updateDeviceLog(deviceLog);
     }
 

+ 1 - 0
ruoyi-dongfangyaiye/src/main/resources/mapper/taiye/DeviceLogMapper.xml

@@ -27,6 +27,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
             <if test="deviceId != null  and deviceId != ''"> and device_id = #{deviceId}</if>
             <if test="deviceName != null  and deviceName != ''"> and device_name like concat('%', #{deviceName}, '%')</if>
         </where>
+        order by create_time desc
     </select>
 
     <select id="selectDeviceLogByDeviceLogId" parameterType="Long" resultMap="DeviceLogResult">

+ 1 - 0
ruoyi-framework/src/main/java/com/ruoyi/framework/config/SecurityConfig.java

@@ -120,6 +120,7 @@ public class SecurityConfig extends WebSecurityConfigurerAdapter
                 // 库位视图
                 .antMatchers("/ams/locationView/**").permitAll()
                 .antMatchers("/device/log/**").permitAll()
+                .antMatchers("/api/modbus/**").permitAll()
                 // 除上面外的所有请求全部需要鉴权认证
                 .anyRequest().authenticated()
                 .and()

+ 0 - 4
ruoyi-system/src/main/java/com/ruoyi/system/config/PlcConfig.java

@@ -29,9 +29,5 @@ public class PlcConfig {
 
     private String confirmTheStatus;
 
-    public void setSiemensPLCS(String  ePlcType) {
-        this.ePlcType = EPlcType.valueOf(ePlcType);
-    }
-
 
 }

+ 1 - 1
ruoyi-system/src/main/java/com/ruoyi/system/enums/PLCEnum.java

@@ -161,7 +161,7 @@ public enum PLCEnum {
     /**
      * 一号包装机上空请求允许进入信号
      */
-    PACKING_MACHINE_UP_EMPTY_REQUEST_ENTER_1("DB5000.1.0"),
+    PACKING_MACHINE_UP_EMPTY_REQUEST_ENTER_1("DB5000.0.0"),
 
     /**
      * 二号包装机上空请求允许进入信号

+ 18 - 12
ruoyi-system/src/main/java/com/ruoyi/system/init/PlcConnectServiceRunner.java

@@ -10,8 +10,6 @@ import com.ruoyi.common.exception.ServiceException;
 import com.ruoyi.common.utils.StringUtils;
 import com.ruoyi.system.config.PlcConfig;
 import com.ruoyi.system.config.PlcProperties;
-import com.ruoyi.system.enums.PLCConnectNameEnum;
-import com.ruoyi.system.enums.PLCEnum;
 import lombok.extern.slf4j.Slf4j;
 import org.springframework.boot.CommandLineRunner;
 import org.springframework.core.annotation.Order;
@@ -23,6 +21,7 @@ import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.concurrent.ExecutionException;
 import java.util.concurrent.ScheduledExecutorService;
+import java.util.concurrent.ScheduledFuture;
 import java.util.concurrent.TimeUnit;
 
 /**
@@ -44,6 +43,8 @@ public class PlcConnectServiceRunner implements CommandLineRunner {
     @Resource
     private ScheduledExecutorService scheduledExecutorService;
 
+    private HashMap<String, ScheduledFuture<?>> heartbeatThreads = new HashMap<>();
+
     @Override
     public void run(String... args) throws Exception {
         initConnect();
@@ -67,6 +68,7 @@ public class PlcConnectServiceRunner implements CommandLineRunner {
                     if (s7PLC.checkConnected()){
                         plcToolsMap.put(plcConfig.getName(),s7PLC);
                         log.info("plc:{},ip:{},The connection was successful",plcConfig.getName(),plcConfig.getIp());
+                        plcConnectsTheHeartbeat(plcConfig,s7PLC);
                     }
                 }catch (Exception e){
                     log.info("plc:{},ip:{},Connection failed",plcConfig.getName(),plcConfig.getIp());
@@ -78,8 +80,12 @@ public class PlcConnectServiceRunner implements CommandLineRunner {
     }
 
     public void retry(PlcConfig plcConfig) {
-        SpringUtil.getApplicationContext().publishEvent(new DeviceLog(plcConfig.getName(),"PLC设备已恢复连接,请联系管理员","2"));
+        SpringUtil.getApplicationContext().publishEvent(new DeviceLog(plcConfig.getName(),"PLC设备已断开连接,请联系管理员","2"));
         reTryPlc.add(plcConfig.getName());
+        ScheduledFuture<?> scheduledFuture = heartbeatThreads.get(plcConfig.getName());
+        if (ObjectUtil.isNotNull(scheduledFuture)){
+            scheduledFuture.cancel(true);
+        }
         threadPoolTaskExecutor.execute (() -> {
             Retryer<Boolean> retryer = RetryerBuilder.<Boolean>newBuilder()
                     .retryIfResult(Boolean.FALSE::equals)
@@ -95,7 +101,6 @@ public class PlcConnectServiceRunner implements CommandLineRunner {
                         s7PLC.connect();
                         if (s7PLC.checkConnected()){
                             SpringUtil.getApplicationContext().publishEvent(new DeviceLog(plcConfig.getName(),"PLC设备已恢复连接","1"));
-
                             plcToolsMap.put(plcConfig.getName(),s7PLC);
                             log.info("plc:{},ip:{},Retry the connection succeeded",plcConfig.getName(),plcConfig.getIp());
                             reTryPlc.remove(plcConfig.getName());
@@ -120,18 +125,19 @@ public class PlcConnectServiceRunner implements CommandLineRunner {
      * @param s7PLC
      */
     private void plcConnectsTheHeartbeat(PlcConfig plcConfig,S7PLC s7PLC){
-        String heartbeatAdd = plcConfig.getHeartbeat();
-        if (StringUtils.isNotEmpty(heartbeatAdd)){
-            scheduledExecutorService.scheduleWithFixedDelay(()->{
-                if (!reTryPlc.contains(plcConfig.getName())){
+        if (StringUtils.isNotEmpty( plcConfig.getHeartbeat())){
+            ScheduledFuture<?> scheduledFuture = scheduledExecutorService.scheduleWithFixedDelay(() -> {
+                if (!reTryPlc.contains(plcConfig.getName())) {
                     try {
-                        s7PLC.readByte(plcConfig.getHeartbeat());
-                    }catch (Exception e){
-                        log.error("device:{},The connection is lost",plcConfig.getName());
+                        byte b = s7PLC.readByte(plcConfig.getHeartbeat());
+                        s7PLC.writeByte(plcConfig.getConfirmTheStatus(), b);
+                    } catch (Exception e) {
+                        log.error("device:{},The connection is lost", plcConfig.getName());
                         retry(plcConfig);
                     }
                 }
-            },0,3,TimeUnit.SECONDS);
+            }, 0, 1, TimeUnit.SECONDS);
+            heartbeatThreads.put(plcConfig.getName(),scheduledFuture);
         }
     }
 

+ 12 - 0
ruoyi-ui/src/api/ams/locationView.js

@@ -67,3 +67,15 @@ export function queryWarehouseDict() {
     method: 'get',
   })
 }
+
+/**
+ * 初始化空托
+ * @param id
+ * @returns {*}
+ */
+export function initEmptyTray(id) {
+  return request({
+    url: '/ams/locationView/initEmptyTray/'+id,
+    method: 'get'
+  })
+}

+ 17 - 3
ruoyi-ui/src/views/ams/inv/locationView/index.vue

@@ -164,7 +164,7 @@
           <el-button type="primary" @click="lockLoc()">锁定/解锁</el-button>
           <el-button type="primary" @click="occupyLoc()">有货/无货</el-button>
           <el-button type="primary" @click="clearLoc()">清空</el-button>
-          <!--<el-button type="primary" @click="submitForm">初始化一个空托盘</el-button>-->
+          <el-button type="primary" @click="submitForm">初始化一个空托盘</el-button>
         </el-form-item>
       </el-form>
       <el-divider content-position="center">批次属性信息</el-divider>
@@ -209,8 +209,8 @@ import {
   lotattConfigList,
   lotattInfo,
   occupyLocRequest,
-  queryWarehouseDict,
-} from "@/api/ams/locationView";
+  queryWarehouseDict, initEmptyTray
+} from '@/api/ams/locationView'
 
 export default {
   data() {
@@ -391,6 +391,20 @@ export default {
         this.warehouseCombo = response.data;
       });
     },
+    submitForm(){
+      let that = this;
+      this.$modal.confirm("是否确认要生成一个空托盘?").then(function () {
+        initEmptyTray(that.currentSelect).then((response) => {
+          if (response.code === 200) {
+            that.open = false;
+            that.$modal.msgSuccess(response.msg);
+            that.search();
+          } else {
+            that.$modal.msgError(response.msg);
+          }
+        });
+      });
+    }
   },
 };
 </script>

+ 11 - 12
ruoyi-ui/src/views/ams/task/index.vue

@@ -148,15 +148,15 @@
           v-hasPermi="['ams:wcsTask:add']"
         >新增</el-button>
       </el-col>
-<!--      <el-col :span="1.5">-->
-<!--        <el-button-->
-<!--          type="primary"-->
-<!--          plain-->
-<!--          icon="el-icon-plus"-->
-<!--          size="mini"-->
-<!--          @click="handleCharge"-->
-<!--        >充电任务</el-button>-->
-<!--      </el-col>-->
+      <el-col :span="1.5">
+        <el-button
+          type="primary"
+          plain
+          icon="el-icon-plus"
+          size="mini"
+          @click="handleCharge"
+        >充电任务</el-button>
+      </el-col>
       <!--<el-col :span="1.5">
         <el-button
           type="success"
@@ -520,9 +520,8 @@ export default {
         {'label':'普通任务','value':'01'}
       ],
       chargeCombo: [
-        {'label':'迷你堆垛A','value':'1'},
-        {'label':'迷你堆垛B','value':'2'},
-        {'label':'三向车','value':'3'}
+        {'label':'AGV-1','value':'1'},
+        {'label':'AGV-2','value':'2'},
       ],
       taskTypeCombo: [
         {'label':'是','value':'Y'},

+ 2 - 2
ruoyi-ui/src/views/login.vue

@@ -72,8 +72,8 @@ export default {
     return {
       codeUrl: "",
       loginForm: {
-        username: "admin",
-        password: "admin123",
+        username: "",
+        password: "",
         rememberMe: false,
         code: "",
         uuid: ""

+ 2 - 0
warewms-ams/src/main/java/com/ruoyi/ams/inv/service/IInvLotLocIdService.java

@@ -282,4 +282,6 @@ public interface IInvLotLocIdService {
      * @return true 代表质检没有问题,可以出库
      */
     boolean verifyInventoryCanOutbound(String locationId);
+
+    AjaxResult initEmptyTray(Long locationId);
 }

+ 22 - 0
warewms-ams/src/main/java/com/ruoyi/ams/inv/service/impl/InvLotLocIdServiceImpl.java

@@ -32,6 +32,7 @@ import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
 
 import java.math.BigDecimal;
+import java.util.ArrayList;
 import java.util.Date;
 import java.util.List;
 import java.util.Objects;
@@ -669,4 +670,25 @@ public class InvLotLocIdServiceImpl implements IInvLotLocIdService {
         List<InvLotLocIdLotattVO> lotattVOList = selectInvLocIdLotattList(invLocIdSearchFrom);
         return lotattVOList.stream().allMatch(v -> !v.getLotatt05().equals("DJ"));
     }
+
+    @Override
+    public AjaxResult initEmptyTray(Long locationId) {
+        Boolean isIdle = baseLocationInfoService.verifyLocationIsIdle(String.valueOf(locationId), Constant.WAREHOUSE_ID);
+        if (!isIdle) {
+            return AjaxResult.error("库位需要空闲状态!");
+        }
+        List<InvLotLocId> invLotLocIds = invLotLocIdService.selectInvLotLocIdList(locationId);
+        if (!invLotLocIds.isEmpty()){
+            return AjaxResult.error("该库位库存信息不为空!");
+        }
+        List<AgvCallItemDTO> agvCallItemDTOList = new ArrayList<>();
+        AgvCallItemDTO agvCallItemDTO = new AgvCallItemDTO();
+        agvCallItemDTO.setSku("EMPTY_TRAY"); // 空托
+        agvCallItemDTO.setQty(1.0);
+        agvCallItemDTOList.add(agvCallItemDTO);
+        AgvCallDTO agvCallDTO = new AgvCallDTO();
+        agvCallDTO.setAgvCallItemDTOList(agvCallItemDTOList);
+        invLotLocIdService.initInv(String.valueOf(locationId), agvCallDTO);
+        return AjaxResult.success();
+    }
 }

+ 7 - 0
warewms-ams/src/main/java/com/ruoyi/ams/locationView/service/LocationViewService.java

@@ -1,7 +1,10 @@
 package com.ruoyi.ams.locationView.service;
 
+import com.ruoyi.ams.config.domain.dto.AgvCallDTO;
+import com.ruoyi.ams.config.domain.dto.AgvCallItemDTO;
 import com.ruoyi.ams.inv.domain.vo.InvLotLocIdLotattVO;
 import com.ruoyi.ams.inv.mapper.InvLotLocIdMapper;
+import com.ruoyi.ams.inv.service.IInvLotLocIdService;
 import com.ruoyi.ams.locationView.domain.form.LocationViewForm;
 import com.ruoyi.ams.locationView.domain.vo.LocationViewInfoVO;
 import com.ruoyi.ams.locationView.domain.vo.LocationViewLotattVO;
@@ -13,6 +16,7 @@ import com.ruoyi.base.domain.dto.BasLocationGuiExtDTO;
 import com.ruoyi.base.domain.dto.BaseLocationGuiDTO;
 import com.ruoyi.base.mapper.BaseLocationInfoMapper;
 import com.ruoyi.base.mapper.BaseLocationZoneMapper;
+import com.ruoyi.common.core.domain.AjaxResult;
 import com.ruoyi.common.utils.StringUtils;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
@@ -33,6 +37,8 @@ public class LocationViewService {
     private InvLotLocIdMapper invLotLocIdMapper;
     @Autowired
     private BaseLocationZoneMapper baseLocationZoneMapper;
+    @Autowired
+    private IInvLotLocIdService invLotLocIdService;
 
     public LocationViewVO locationView(LocationViewForm locationViewForm) {
         LocationViewVO locationViewVO = new LocationViewVO();
@@ -206,4 +212,5 @@ public class LocationViewService {
         }
         return guiDTOS;
     }
+
 }