package com.muyu.service.impl; import com.muyu.common.PageList; import com.muyu.common.Result; import com.muyu.domain.Vehicle; import com.muyu.domain.model.MqttServerModel; import com.muyu.domain.model.PositionModel; import com.muyu.domain.req.CheckPositionReq; import com.muyu.domain.req.GearReq; import com.muyu.domain.req.MsgReq; import com.muyu.domain.req.VehicleInstanceListReq; import com.muyu.domain.resp.VehicleInstanceResp; import com.muyu.service.PositionRouteService; import com.muyu.service.VehicleInstanceService; import com.muyu.utils.MD5Util; import com.muyu.utils.ReflectUtils; import com.muyu.vehicle.VehicleInstance; import com.muyu.vehicle.api.ClientAdmin; import com.muyu.vehicle.api.req.VehicleConnectionReq; import com.muyu.vehicle.core.LocalContainer; import com.muyu.vehicle.model.VehicleData; import com.muyu.vehicle.model.properties.MqttProperties; import lombok.extern.log4j.Log4j2; import org.apache.commons.lang3.StringUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import java.util.Comparator; import java.util.List; import java.util.UUID; import java.util.stream.Stream; /** * @author DongZeLiang * @version 1.0 * @description 车辆实例业务实现层 * @date 2023/11/22 */ @Log4j2 @Service public class VehicleInstanceServiceImpl implements VehicleInstanceService { @Autowired private PositionRouteService positionRouteService; @Autowired private ClientAdmin clientAdmin; /** * 根据车辆生成车辆实例 * * @param vehicle 车辆信息 */ @Override public void init(Vehicle vehicle) { VehicleInstance vehicleInstance = new VehicleInstance(); vehicleInstance.setVehicle(vehicle); vehicleInstance.setVehicleData(VehicleData.vehicleBuild(vehicle)); LocalContainer.setVehicleInstance(vehicleInstance); log.debug("构建车辆对象: [{}]", vehicle.getVin()); } /** * 车辆结果对象 * * @param vehicleInstanceListReq 车辆查询 * * @return 车辆对象 */ @Override public PageList queryList (VehicleInstanceListReq vehicleInstanceListReq) { Stream stream = LocalContainer.vehicleDataMap.values() .stream(); if (StringUtils.isNotBlank(vehicleInstanceListReq.getVin())){ stream = stream.filter(vehicleInstance -> vehicleInstance.getVin().contains(vehicleInstanceListReq.getVin())); } if (vehicleInstanceListReq.isOnline()){ stream = stream.sorted(Comparator.comparingInt(o -> (o.isOnline() ? 0 : 1))); } return PageList.builder() .total(LocalContainer.total()) .rows( stream .map(VehicleInstanceResp::instanceBuild) .skip((vehicleInstanceListReq.getPage() - 1) * vehicleInstanceListReq.getPageSize()) .limit(vehicleInstanceListReq.getPageSize()) .toList() ) .build(); } /** * 车辆客户端初始化 * * @param vin vin */ @Override public void vehicleClientInit (String vin) { log.info("vin[{}],开始上线", vin); VehicleInstance vehicleInstance = LocalContainer.getVehicleInstance(vin); if (vehicleInstance == null){ throw new RuntimeException("没有【"+vin+"】车辆"); } String timestamp = String.valueOf(System.currentTimeMillis()); VehicleConnectionReq connectionReq = VehicleConnectionReq.builder() .vin(vin) .timestamp(timestamp) .userName(MD5Util.encrypted(vin+timestamp)) .nonce(MD5Util.encrypted(UUID.randomUUID().toString().replace("-", ""))) .build(); Result result = clientAdmin.vehicleConnection(connectionReq); if (result.getCode() != 200){ log.error("车辆:[{}],申请上线异常:[{}]", vin, result.getMsg()); throw new RuntimeException("远程服务器没有【"+vin+"】车辆"); } MqttServerModel mqttServerModel = result.getData(); MqttProperties mqttProperties = MqttProperties.builder() .broker(mqttServerModel.getBroker()) .topic(mqttServerModel.getTopic()) .clientId(vin) .username(connectionReq.getUserName()) .password(vin + connectionReq.getTimestamp() + connectionReq.getNonce()) .build(); vehicleInstance.setMqttProperties(mqttProperties); vehicleInstance.initClient(); log.info("vin[{}],上线成功", vin); } /** * 车辆客户端关闭 * * @param vin vin */ @Override public void vehicleClientClose (String vin) { VehicleInstance vehicleInstance = LocalContainer.getVehicleInstance(vin); vehicleInstance.closeClient(); } /** * 选择车辆轨迹 * * @param checkPositionReq 切换轨迹 */ @Override public void checkPosition (CheckPositionReq checkPositionReq) { VehicleInstance vehicleInstance = LocalContainer.getVehicleInstance(checkPositionReq.getVin()); List positionModelList = this.positionRouteService.getPositionModelByRouteName(checkPositionReq.getPositionCode()); vehicleInstance.settingPosition(positionModelList); vehicleInstance.setPositionCode(checkPositionReq.getPositionCode()); } /** * 车辆消息操作 * * @param msgReq */ @Override public void msg (MsgReq msgReq) { VehicleInstance vehicleInstance = LocalContainer.getVehicleInstance(msgReq.getVin()); switch (msgReq.getMsgCode()){ case "上报" -> { if(vehicleInstance.getVehicleThread() == null){ vehicleInstance.initVehicleThread(); } vehicleInstance.startSend(); } case "暂停" -> vehicleInstance.pauseSend(); case "停止" -> vehicleInstance.stopSend(); default -> throw new RuntimeException("车辆消息事件错误"); } } /** * 设置档位 * * @param gearReq */ @Override public void gear (GearReq gearReq) { VehicleInstance vehicleInstance = LocalContainer.getVehicleInstance(gearReq.getVin()); vehicleInstance.setGear(gearReq.getGear()); } /** * 修改车辆报文 * * @param vin vin * @param statusKey 状态键 * @param statusValue 状态值 */ @Override public void editStatus (String vin, String statusKey, Integer statusValue) { VehicleInstance vehicleInstance = LocalContainer.getVehicleInstance(vin); VehicleData vehicleData = vehicleInstance.getVehicleData(); ReflectUtils.invokeSetter(vehicleData, statusKey, statusValue); } // private final AtomicBoolean unifiedStatus = new AtomicBoolean(Boolean.TRUE); }