From 7871c2ac7018b42838da0c156cf1e0477a82466f Mon Sep 17 00:00:00 2001 From: zc Date: Thu, 30 Apr 2026 14:49:53 +0800 Subject: [PATCH] =?UTF-8?q?=E6=BB=A1=E8=BD=A6=E4=BD=8D=E9=94=81=E6=9D=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../server/controller/ServerController.java | 26 ++++++-- .../mica/mqtt/server/entity/CarInfo.java | 3 + .../mica/mqtt/server/entity/CarParkItem.java | 13 ++++ .../mqtt/server/entity/CarPassGather.java | 3 + .../mqtt/server/entity/CarPassRecord.java | 5 +- .../mica/mqtt/server/entity/Equipment.java | 3 + .../server/listener/CarMessageListener.java | 44 ++++++++++++-- .../mqtt/server/mapper/CarParkItemMapper.java | 5 +- .../server/pojo/DeviceIOLockRequestPO.java | 45 ++++++++++++++ .../mqtt/server/pojo/OpenFloodgatePO.java | 39 ++++++++++++ .../server/service/ICarParkItemService.java | 4 ++ .../service/impl/CarParkItemServiceImpl.java | 8 ++- .../server/service/impl/ServerService.java | 60 +++++++++++++++++++ 13 files changed, 246 insertions(+), 12 deletions(-) create mode 100644 example/mqtt-car/src/main/java/org/dromara/mica/mqtt/server/pojo/DeviceIOLockRequestPO.java create mode 100644 example/mqtt-car/src/main/java/org/dromara/mica/mqtt/server/pojo/OpenFloodgatePO.java diff --git a/example/mqtt-car/src/main/java/org/dromara/mica/mqtt/server/controller/ServerController.java b/example/mqtt-car/src/main/java/org/dromara/mica/mqtt/server/controller/ServerController.java index 5832440..7be844a 100644 --- a/example/mqtt-car/src/main/java/org/dromara/mica/mqtt/server/controller/ServerController.java +++ b/example/mqtt-car/src/main/java/org/dromara/mica/mqtt/server/controller/ServerController.java @@ -3,10 +3,7 @@ package org.dromara.mica.mqtt.server.controller; import com.alibaba.fastjson2.JSONObject; import org.dromara.mica.mqtt.server.service.impl.ServerService; 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 org.springframework.web.bind.annotation.*; @RequestMapping("/mqtt/server") @RestController @@ -52,4 +49,25 @@ public class ServerController { return service.set_time(body); } + //手动触发抬杆 + @PostMapping("/openFloodgate") + public boolean openFloodgate(@RequestBody JSONObject js) { + String sn = js.getString("sn"); + return service.openFloodgate(sn); + } + + //锁杆&解锁 + @PostMapping("/set_io_lock_status") + public JSONObject lock(@RequestBody JSONObject js) { + String sn = js.getString("sn"); + Integer status = js.getInteger("status"); + boolean publish = service.locked(sn, status); + JSONObject jsonObject = new JSONObject(); + if (publish) { + jsonObject.put("code", 200); + } else { + jsonObject.put("code", 500); + } + return jsonObject; + } } diff --git a/example/mqtt-car/src/main/java/org/dromara/mica/mqtt/server/entity/CarInfo.java b/example/mqtt-car/src/main/java/org/dromara/mica/mqtt/server/entity/CarInfo.java index 917e7ca..6b70ab6 100644 --- a/example/mqtt-car/src/main/java/org/dromara/mica/mqtt/server/entity/CarInfo.java +++ b/example/mqtt-car/src/main/java/org/dromara/mica/mqtt/server/entity/CarInfo.java @@ -1,5 +1,7 @@ package org.dromara.mica.mqtt.server.entity; +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; import com.baomidou.mybatisplus.annotation.TableName; import com.fasterxml.jackson.annotation.JsonFormat; import lombok.Data; @@ -16,6 +18,7 @@ public class CarInfo implements Serializable { private static final long serialVersionUID = 1L; /** customer_id */ + @TableId(type = IdType.AUTO) private Long customerId; /** 白名单生效时间 */ diff --git a/example/mqtt-car/src/main/java/org/dromara/mica/mqtt/server/entity/CarParkItem.java b/example/mqtt-car/src/main/java/org/dromara/mica/mqtt/server/entity/CarParkItem.java index 1237010..ef23b1b 100644 --- a/example/mqtt-car/src/main/java/org/dromara/mica/mqtt/server/entity/CarParkItem.java +++ b/example/mqtt-car/src/main/java/org/dromara/mica/mqtt/server/entity/CarParkItem.java @@ -1,5 +1,7 @@ package org.dromara.mica.mqtt.server.entity; +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; import com.baomidou.mybatisplus.annotation.TableName; import com.fasterxml.jackson.annotation.JsonFormat; import lombok.Data; @@ -22,6 +24,7 @@ public class CarParkItem implements Serializable { /** * id */ + @TableId(type = IdType.AUTO) private Long id; /** @@ -44,4 +47,14 @@ public class CarParkItem implements Serializable { */ private String area; + /** + * 车位数量 + */ + private Integer carsNum; + + /** + * 满车位自动锁杆:0:不锁,1:锁 + */ + private Integer autoLock; + } diff --git a/example/mqtt-car/src/main/java/org/dromara/mica/mqtt/server/entity/CarPassGather.java b/example/mqtt-car/src/main/java/org/dromara/mica/mqtt/server/entity/CarPassGather.java index e94c8e4..0168dc3 100644 --- a/example/mqtt-car/src/main/java/org/dromara/mica/mqtt/server/entity/CarPassGather.java +++ b/example/mqtt-car/src/main/java/org/dromara/mica/mqtt/server/entity/CarPassGather.java @@ -1,5 +1,7 @@ package org.dromara.mica.mqtt.server.entity; +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; import com.baomidou.mybatisplus.annotation.TableName; import com.fasterxml.jackson.annotation.JsonFormat; import lombok.Data; @@ -22,6 +24,7 @@ public class CarPassGather implements Serializable { /** * id */ + @TableId(type = IdType.AUTO ) private Long id; /** diff --git a/example/mqtt-car/src/main/java/org/dromara/mica/mqtt/server/entity/CarPassRecord.java b/example/mqtt-car/src/main/java/org/dromara/mica/mqtt/server/entity/CarPassRecord.java index 9158868..b462323 100644 --- a/example/mqtt-car/src/main/java/org/dromara/mica/mqtt/server/entity/CarPassRecord.java +++ b/example/mqtt-car/src/main/java/org/dromara/mica/mqtt/server/entity/CarPassRecord.java @@ -1,10 +1,10 @@ package org.dromara.mica.mqtt.server.entity; +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; import com.baomidou.mybatisplus.annotation.TableName; import com.fasterxml.jackson.annotation.JsonFormat; import lombok.Data; -import org.apache.commons.lang3.builder.ToStringBuilder; -import org.apache.commons.lang3.builder.ToStringStyle; import java.io.Serial; import java.io.Serializable; @@ -24,6 +24,7 @@ public class CarPassRecord implements Serializable { /** * id */ + @TableId(type = IdType.AUTO) private Long id; /** diff --git a/example/mqtt-car/src/main/java/org/dromara/mica/mqtt/server/entity/Equipment.java b/example/mqtt-car/src/main/java/org/dromara/mica/mqtt/server/entity/Equipment.java index f3a5bdf..7c37fb1 100644 --- a/example/mqtt-car/src/main/java/org/dromara/mica/mqtt/server/entity/Equipment.java +++ b/example/mqtt-car/src/main/java/org/dromara/mica/mqtt/server/entity/Equipment.java @@ -1,6 +1,8 @@ package org.dromara.mica.mqtt.server.entity; +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; import com.baomidou.mybatisplus.annotation.TableName; import lombok.Data; @@ -16,6 +18,7 @@ public class Equipment implements Serializable { /** 设备Id */ + @TableId(type = IdType.AUTO) private Long id; /** 所属产品Id */ diff --git a/example/mqtt-car/src/main/java/org/dromara/mica/mqtt/server/listener/CarMessageListener.java b/example/mqtt-car/src/main/java/org/dromara/mica/mqtt/server/listener/CarMessageListener.java index 2a18d9c..ee3cee5 100644 --- a/example/mqtt-car/src/main/java/org/dromara/mica/mqtt/server/listener/CarMessageListener.java +++ b/example/mqtt-car/src/main/java/org/dromara/mica/mqtt/server/listener/CarMessageListener.java @@ -5,6 +5,7 @@ import cn.hutool.core.date.DateUtil; import cn.hutool.http.HttpUtil; import com.alibaba.fastjson2.JSON; import com.alibaba.fastjson2.JSONObject; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.StringUtils; import org.dromara.mica.mqtt.core.annotation.MqttServerFunction; @@ -20,6 +21,7 @@ import org.dromara.mica.mqtt.server.service.ICarParkItemService; import org.dromara.mica.mqtt.server.service.ICarParkRecordService; import org.dromara.mica.mqtt.server.service.ICarPassGatherService; import org.dromara.mica.mqtt.server.service.ICarPassRecordService; +import org.dromara.mica.mqtt.server.service.impl.ServerService; import org.dromara.mica.mqtt.server.utils.AESUtil; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; @@ -29,6 +31,7 @@ import org.tio.utils.hutool.StrUtil; import java.nio.charset.StandardCharsets; import java.util.Date; import java.util.HashMap; +import java.util.List; import java.util.Map; import java.util.concurrent.TimeUnit; @@ -56,6 +59,10 @@ public class CarMessageListener { @Autowired ICarPassGatherService carPassGatherService; + @Autowired + private ServerService service; + + private static String key = "1234567898765432"; //xa、jl、td、xj @@ -116,6 +123,17 @@ public class CarMessageListener { public void ivs_result(String topic, Map topicVars, byte[] message) throws Exception { String sn = topicVars.get("sn"); log.info("接收到车辆识别消息 -> Topic: {}", topic); + + //如果开启了锁杆,且车位满了 + CarParkItem carParkItem = carParkItemService.selectBySn(sn); + long count = carPassGatherService.count(new QueryWrapper().eq("park_id", carParkItem.getParkId())); + if (StrUtil.equals(carParkItem.getWay(), "0") //入场 + && carParkItem.getAutoLock() == 1 //开启了锁杆 + && count >= carParkItem.getCarsNum()) { //车位满了 + log.info("车位满了,不记录入场数据"); + return; + } + String data = new String(message, StandardCharsets.UTF_8); JSONObject jsonObject = JSONObject.parseObject(data); JSONObject payload = jsonObject.getJSONObject("payload"); @@ -163,14 +181,15 @@ public class CarMessageListener { } record.setSn(sn); record.setUniqueNo(id); + record.setParkId(carParkItem.getParkId()); record.setTriggerType(plateResult.getString("triggerType")); record.setType(carBrand.getString("type")); carPassRecordService.save(record); //保存/删除在场数据 - CarParkItem carParkItem = carParkItemService.selectBySn(sn); + boolean isExist = carPassGatherService.exists(new QueryWrapper().eq("license", license)); //入场新增数据 - if (StrUtil.equals(carParkItem.getWay(), "0")) { + if (StrUtil.equals(carParkItem.getWay(), "0") && !isExist) { CarPassGather carPassGather = new CarPassGather(); carPassGather.setLicense(license); carPassGather.setParkId(carParkItem.getParkId()); @@ -178,8 +197,23 @@ public class CarMessageListener { carPassGather.setJoinTime(record.getPassTime()); carPassGather.setSn(sn); carPassGatherService.save(carPassGather); - } else {//出场删除数据 + + //最后一辆车进场 + if (carParkItem.getAutoLock() == 1 && (count + 1) >= carParkItem.getCarsNum()) { + List snList = carParkItemService.selectSnByParkId(carParkItem.getParkId()); + for (String s : snList) { + service.locked(s, 2); + } + } + } else if (StrUtil.equals(carParkItem.getWay(), "1") && isExist) {//出场删除数据 carPassGatherService.deleteByLicense(license); + //出去一辆车,有空位 + if (carParkItem.getAutoLock() == 1 && count == carParkItem.getCarsNum()) { + List snList = carParkItemService.selectSnByParkId(carParkItem.getParkId()); + for (String s : snList) { + service.locked(s, 0); + } + } } } @@ -270,7 +304,9 @@ public class CarMessageListener { public void set_io_lock_status(String topic, byte[] message) { log.info("IO锁定事件监听消息 -> Topic: {}, message: {}", topic, new String(message)); String data = new String(message, StandardCharsets.UTF_8); - log.info("IO锁定事件监听:{}", data); + JSONObject jsonObject = JSONObject.parseObject(data); + + } /** diff --git a/example/mqtt-car/src/main/java/org/dromara/mica/mqtt/server/mapper/CarParkItemMapper.java b/example/mqtt-car/src/main/java/org/dromara/mica/mqtt/server/mapper/CarParkItemMapper.java index 04d5c14..1963eac 100644 --- a/example/mqtt-car/src/main/java/org/dromara/mica/mqtt/server/mapper/CarParkItemMapper.java +++ b/example/mqtt-car/src/main/java/org/dromara/mica/mqtt/server/mapper/CarParkItemMapper.java @@ -12,6 +12,9 @@ import java.util.List; @Mapper public interface CarParkItemMapper extends BaseMapper { - @Select("SELECT p.id,p.park_id parkId,p.way,p.equipment_id equipmentId,p.area FROM car_park_item p left join sys_equipment e on p.equipment_id = e.id where e.sequence = #{sn} and e.product_id = 4 limit 1") + @Select("SELECT p.id,p.park_id parkId,k.auto_lock autoLock,k.cars_num carsNum,p.way,p.equipment_id equipmentId,p.area FROM car_park_item p left join sys_equipment e on p.equipment_id = e.id LEFT JOIN car_park k on p.park_id = k.id where e.sequence = #{sn} and e.product_id = 4 limit 1") CarParkItem selectBySn(@Param("sn") String sn); + + @Select("SELECT e.sequence FROM car_park_item p left join sys_equipment e on p.equipment_id = e.id where p.park_id = #{parkId} and p.way = 0 and e.product_id = 4") + List selectSnByParkId(@Param("parkId") String parkId); } diff --git a/example/mqtt-car/src/main/java/org/dromara/mica/mqtt/server/pojo/DeviceIOLockRequestPO.java b/example/mqtt-car/src/main/java/org/dromara/mica/mqtt/server/pojo/DeviceIOLockRequestPO.java new file mode 100644 index 0000000..5705348 --- /dev/null +++ b/example/mqtt-car/src/main/java/org/dromara/mica/mqtt/server/pojo/DeviceIOLockRequestPO.java @@ -0,0 +1,45 @@ +package org.dromara.mica.mqtt.server.pojo; + +import com.alibaba.fastjson2.JSONObject; +import com.fasterxml.jackson.annotation.JsonProperty; +import lombok.Data; + +@Data +public class DeviceIOLockRequestPO { + /** + * 消息ID,用于关联具体消息 + */ + @JsonProperty("id") + private String id; + + /** + * 设备序列号 + */ + @JsonProperty("sn") + private String sn; + + /** + * 消息名称 + */ + @JsonProperty("name") + private String name; + + /** + * 消息版本,目前都填1.0 + */ + @JsonProperty("version") + private String version = "1.0"; + + /** + * 时间戳 + */ + @JsonProperty("timestamp") + private long timestamp = System.currentTimeMillis() / 1000; + + /** + * 消息负载 + */ + @JsonProperty("payload") + private JSONObject payload; + +} diff --git a/example/mqtt-car/src/main/java/org/dromara/mica/mqtt/server/pojo/OpenFloodgatePO.java b/example/mqtt-car/src/main/java/org/dromara/mica/mqtt/server/pojo/OpenFloodgatePO.java new file mode 100644 index 0000000..43a694e --- /dev/null +++ b/example/mqtt-car/src/main/java/org/dromara/mica/mqtt/server/pojo/OpenFloodgatePO.java @@ -0,0 +1,39 @@ +package org.dromara.mica.mqtt.server.pojo; + + +import lombok.Data; +import com.alibaba.fastjson2.JSONObject; + +@Data +public class OpenFloodgatePO { + /** + * 消息ID,用于关联具体消息 + */ + private String id; + + /** + * 设备序列号 + */ + private String sn; + + /** + * 消息名称(固定为gpio_out) + */ + private String name; + + /** + * 消息版本(目前都填1.0) + */ + private String version = "1.0"; + + /** + * 时间戳 + */ + private Long timestamp = System.currentTimeMillis() / 1000; + + /** + * 消息负载 + */ + private JSONObject payload; + +} diff --git a/example/mqtt-car/src/main/java/org/dromara/mica/mqtt/server/service/ICarParkItemService.java b/example/mqtt-car/src/main/java/org/dromara/mica/mqtt/server/service/ICarParkItemService.java index bb3c419..49b0863 100644 --- a/example/mqtt-car/src/main/java/org/dromara/mica/mqtt/server/service/ICarParkItemService.java +++ b/example/mqtt-car/src/main/java/org/dromara/mica/mqtt/server/service/ICarParkItemService.java @@ -3,7 +3,11 @@ package org.dromara.mica.mqtt.server.service; import com.baomidou.mybatisplus.extension.service.IService; import org.dromara.mica.mqtt.server.entity.CarParkItem; +import java.util.List; + public interface ICarParkItemService extends IService { CarParkItem selectBySn(String sn); + + List selectSnByParkId(String parkId); } diff --git a/example/mqtt-car/src/main/java/org/dromara/mica/mqtt/server/service/impl/CarParkItemServiceImpl.java b/example/mqtt-car/src/main/java/org/dromara/mica/mqtt/server/service/impl/CarParkItemServiceImpl.java index 97bb4c0..05ce5f1 100644 --- a/example/mqtt-car/src/main/java/org/dromara/mica/mqtt/server/service/impl/CarParkItemServiceImpl.java +++ b/example/mqtt-car/src/main/java/org/dromara/mica/mqtt/server/service/impl/CarParkItemServiceImpl.java @@ -1,6 +1,5 @@ package org.dromara.mica.mqtt.server.service.impl; -import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import org.dromara.mica.mqtt.server.entity.CarParkItem; import org.dromara.mica.mqtt.server.mapper.CarParkItemMapper; @@ -8,6 +7,8 @@ import org.dromara.mica.mqtt.server.service.ICarParkItemService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; +import java.util.List; + @Service public class CarParkItemServiceImpl extends ServiceImpl implements ICarParkItemService { @@ -18,4 +19,9 @@ public class CarParkItemServiceImpl extends ServiceImpl selectSnByParkId(String parkId) { + return carParkItemMapper.selectSnByParkId(parkId); + } } diff --git a/example/mqtt-car/src/main/java/org/dromara/mica/mqtt/server/service/impl/ServerService.java b/example/mqtt-car/src/main/java/org/dromara/mica/mqtt/server/service/impl/ServerService.java index 0e998b0..764931d 100644 --- a/example/mqtt-car/src/main/java/org/dromara/mica/mqtt/server/service/impl/ServerService.java +++ b/example/mqtt-car/src/main/java/org/dromara/mica/mqtt/server/service/impl/ServerService.java @@ -1,12 +1,18 @@ package org.dromara.mica.mqtt.server.service.impl; +import com.alibaba.fastjson2.JSON; import com.alibaba.fastjson2.JSONObject; import lombok.extern.slf4j.Slf4j; +import org.dromara.mica.mqtt.server.pojo.DeviceIOLockRequestPO; +import org.dromara.mica.mqtt.server.pojo.OpenFloodgatePO; +import org.dromara.mica.mqtt.server.utils.UuidUtil; import org.dromara.mica.mqtt.spring.server.MqttServerTemplate; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import java.nio.charset.StandardCharsets; +import java.time.LocalDateTime; +import java.time.ZoneId; /** * @author wsq @@ -55,4 +61,58 @@ public class ServerService { log.info("发布离线数据数量body:{},result:{}", body, result); return result; } + + + public boolean openFloodgate(String sn) { + String operUrl = "device/%s/message/down/gpio_out"; + String topic = String.format(operUrl, sn); + OpenFloodgatePO openFloodgatePO = new OpenFloodgatePO(); + String uuid = "open_" + UuidUtil.getUuid(); + openFloodgatePO.setId(uuid); + openFloodgatePO.setSn(sn); + openFloodgatePO.setName("gpio_out"); + LocalDateTime now = LocalDateTime.now(); + long timestamp = now.atZone(ZoneId.systemDefault()).toEpochSecond(); + openFloodgatePO.setTimestamp(timestamp); + openFloodgatePO.setPayload(this.buildPayloadOpen()); + boolean result = server.publish(sn,topic, JSON.toJSONString(openFloodgatePO).getBytes(StandardCharsets.UTF_8)); + log.info("抬杠设备编码:{},result:{},请求体{}", sn,result,openFloodgatePO); + return result; + } + + public boolean locked(String sn, Integer status) { + String operUrl = "device/%s/message/down/set_io_lock_status"; + String topic = String.format(operUrl, sn); + DeviceIOLockRequestPO deviceIOLockRequestPO = new DeviceIOLockRequestPO(); + String uuid = "locked_" + UuidUtil.getUuid(); + deviceIOLockRequestPO.setId(uuid); + deviceIOLockRequestPO.setSn(sn); + deviceIOLockRequestPO.setName("set_io_lock_status"); + deviceIOLockRequestPO.setPayload(this.buildPayloadLocked(status)); + boolean result = server.publish(sn,topic, JSON.toJSONString(deviceIOLockRequestPO).getBytes(StandardCharsets.UTF_8)); + return result; + } + + private JSONObject buildPayloadOpen() { + JSONObject body = new JSONObject(); + body.put("delay", 10000); + body.put("io", 0); + body.put("value",2); + JSONObject payload = new JSONObject(); + payload.put("type", "gpio_out"); + payload.put("body", body); + return payload; + } + + private JSONObject buildPayloadLocked(Integer status) { + JSONObject payload = new JSONObject(); + payload.put("type", "set_io_lock_status"); + JSONObject body = new JSONObject(); + //io口,摄像头接线口 + body.put("ioout", 0); + //0解锁 1高电平锁定(保持常抬) 2低电平锁定(保持常关) + body.put("status", status); + payload.put("body", body); + return payload; + } }