NetworkingCar/src/main/java/com/muyu/vehicle/VehicleInstance.java

275 lines
8.5 KiB
Java

package com.muyu.vehicle;
import com.muyu.common.SystemConstant;
import com.muyu.common.ThreadPool;
import com.muyu.domain.Vehicle;
import com.muyu.domain.model.PositionModel;
import com.muyu.utils.CalculateCheckDigit;
import com.muyu.utils.ConversionUtil;
import com.muyu.utils.VehicleUtils;
import com.muyu.vehicle.model.VehicleData;
import com.muyu.vehicle.model.properties.MqttProperties;
import com.muyu.vehicle.thread.VehicleThread;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.extern.log4j.Log4j2;
import org.eclipse.paho.client.mqttv3.MqttClient;
import org.eclipse.paho.client.mqttv3.MqttConnectOptions;
import org.eclipse.paho.client.mqttv3.MqttException;
import org.eclipse.paho.client.mqttv3.MqttMessage;
import org.eclipse.paho.client.mqttv3.persist.MemoryPersistence;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.List;
import java.util.Objects;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ScheduledFuture;
import static com.muyu.common.SystemConstant.*;
/**
* @author DongZeLiang
* @version 1.0
* @description 车辆实例
* @date 2023/11/16
*/
@Data
@Log4j2
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class VehicleInstance {
/**
* 路径队列
*/
private final LinkedBlockingQueue<PositionModel> positionQueue = new LinkedBlockingQueue<>();
/**
* 车辆
*/
private Vehicle vehicle;
/**
* 实例数据
*/
private VehicleData vehicleData;
/**
* 上一个定位点
*/
private PositionModel lastPosition;
/**
* 车辆工作线程
*/
private VehicleThread vehicleThread;
/**
* 线程提交回调
*/
private ScheduledFuture<?> scheduledFuture;
/**
* 链接上报
*/
private MqttClient client = null;
/**
* Mqtt配置
*/
private MqttProperties mqttProperties;
public VehicleInstance(MqttProperties mqttProperties) {
this.mqttProperties = mqttProperties;
}
/***
* 获取当前车辆VIN
* @return VIN
*/
public String getVin() {
return this.vehicle.getVin();
}
/**
* 发送消息
* @param msg 消息
*/
public void sendMsg(String msg) {
//得到16进制报文
String sHex = ConversionUtil.strToSixteen(msg);
//计算校验和
String makeCheck = CalculateCheckDigit.makeCheck(sHex);
msg = MSG_START + sHex + makeCheck + " " + MSG_END;
// 创建消息并设置 QoS
MqttMessage message = new MqttMessage(msg.getBytes());
message.setQos(this.mqttProperties.getQos());
// 发布消息
try {
client.publish(this.mqttProperties.getTopic(), message);
} catch (MqttException e) {
throw new RuntimeException(e);
}
}
/**
* 初始化客户端
*/
public void initCline() {
try {
client = new MqttClient(mqttProperties.getBroker(), mqttProperties.getClientId(), new MemoryPersistence());
// 连接参数
MqttConnectOptions options = new MqttConnectOptions();
// 设置用户名和密码
if (Objects.nonNull(mqttProperties.getUsername()) && Objects.nonNull(mqttProperties.getPassword())) {
options.setUserName(mqttProperties.getUsername());
options.setPassword(mqttProperties.getPassword().toCharArray());
}
options.setConnectionTimeout(60);
options.setKeepAliveInterval(60);
// 连接
client.connect(options);
log.info("车辆:[{}] 客户端初始化成功", getVin());
} catch (MqttException e) {
log.error("车辆:[{}] 客户端初始化异常", getVin(), e);
}
}
/**
* 初始化车辆路线
* @param positionModelList 路线集合
*/
public void settingPosition(List<PositionModel> positionModelList){
positionModelList.forEach(positionQueue::offer);
log.info("车辆:{} 设置路径成功", this.getVin());
}
/**
* 初始化线程
*/
public void initVehicleThread() {
VehicleThread vehicleThread = new VehicleThread();
vehicleThread.setVehicleInstance(this);
this.setVehicleThread(vehicleThread);
this.vehicleThread.pause();
ScheduledFuture<?> scheduledFuture = ThreadPool.submit(vehicleThread);
this.setScheduledFuture(scheduledFuture);
log.info("初始化车辆上报模拟线程开始:[{}]", this.getVin());
}
/**
* 开始上报线程
*/
public void startSend() {
this.vehicleThread.resume();
}
/**
* 暂停上报线程
*/
public void pauseSend() {
this.vehicleThread.pause();
}
/**
* 结束发送
*/
public void stopSend() {
this.vehicleThread.stop();
}
/**
* 取消执行
*/
public void cancelExecution() {
scheduledFuture.cancel(true);
this.vehicleThread = null;
this.scheduledFuture = null;
}
/**
* 模拟车辆数据
*/
public String imitateData() {
String gear = this.vehicleData.getGear();
if (!"D".equals(gear)){
log.info("车辆不是动车档位,不进行模拟数据");
return null;
}
// 获取上一次定位点
PositionModel lastPositionModel = this.lastPosition == null ? positionQueue.poll() : this.lastPosition;
// 获取当前定位点
PositionModel currentPositionModel = positionQueue.poll();
if (currentPositionModel == null) {
return "表示当前定位点已经跑完,需要其他操作";
}
// 两点之间的距离
BigDecimal distance = VehicleUtils.distance(lastPositionModel, currentPositionModel);
// 车辆总里程 相加
vehicleData.setMileage(vehicleData.getMileage().add(distance));
// 定位点填写
vehicleData.setLongitude(currentPositionModel.getLongitude());
vehicleData.setLatitude(currentPositionModel.getLatitude());
// 当前电量减少
// 电池浮动
BigDecimal batteryFloat = VehicleUtils.batteryFloat();
// 百公里占比
BigDecimal hundredKMScale = distance.divide(SystemConstant.hundredKilometers).setScale(3, RoundingMode.HALF_UP);
// 使用电量
BigDecimal powerUsage = powerConsumption.multiply(hundredKMScale)
.multiply(batteryFloat)
.setScale(2, RoundingMode.HALF_UP);
// 剩余电量
vehicleData.setRemainingBattery(vehicleData.getRemainingBattery().subtract(powerUsage));
// 百公里消耗量
vehicleData.setFuelConsumptionRate(
powerConsumption.multiply(batteryFloat).divide(new BigDecimal(1000)).setScale(2, RoundingMode.HALF_UP).toString()
);
// 计算总速度
vehicleData.setSpeed(
distance.divide(new BigDecimal(2))
.multiply(new BigDecimal("3600"))
.setScale(2, RoundingMode.HALF_UP).toString()
);
vehicleData.imitateBase();
vehicleData.imitateMotor();
vehicleData.imitateBatteryPack();
return null;
}
/**
* 更改车辆档位
* @param d
*/
public void setGear (String gear) {
this.vehicleData.setGear(gear);
}
/*public static void main (String[] args) {
PositionModel lastPositionModel = PositionModel.builder()
.longitude("116.664053")
.latitude("39.531791")
.build();
PositionModel currentPositionModel = PositionModel.builder()
.longitude("116.655091")
.latitude("39.52091")
.build();
// 两点之间的距离
BigDecimal distance = VehicleUtils.distance(lastPositionModel, currentPositionModel);
// 当前电量减少
// 电池浮动
BigDecimal batteryFloat = VehicleUtils.batteryFloat();
BigDecimal divide = distance.divide(SystemConstant.hundredKilometers).setScale(4, RoundingMode.HALF_UP);
BigDecimal multiply = SystemConstant.powerConsumption.multiply(divide)
.multiply(batteryFloat)
.setScale(2, RoundingMode.HALF_UP);
System.out.println("移动距离:" + distance);
System.out.println("浮动量:" + batteryFloat);
System.out.println("百公里占比:" + divide);
System.out.println("当前减少电池量:" + multiply);
}*/
}