作者 钟来

模块整理

正在显示 42 个修改的文件 包含 1097 行增加258 行删除
... ... @@ -188,4 +188,32 @@ public class ByteUtil {
crc = crc.substring(2, 4) + crc.substring(0, 2);
return crc.toUpperCase();
}
/**
* 用于从一个 long 值中指定的起始位置和结束位置读取位数据。该方法使用位掩码操作来获取指定位范围内的数据。
* @param value
* @param startPosition
* @param endPosition
* @return
*/
public static long readBits(long value, int startPosition, int endPosition) {
long mask = (1L << (endPosition - startPosition + 1)) - 1;
return (value >> startPosition) & mask;
}
/**
* 用于简化给变量的不同位赋值的操作。该方法接收四个参数:value 是要被赋值的变量,bitValue 是要赋给指定位的值,startPosition 和 endPosition 是指定位的起始位置和结束位置。
* @param value
* @param bitValue
* @param startPosition
* @param endPosition
* @return
*/
public static int assignBits(int value, int bitValue, int startPosition, int endPosition) {
int mask = ((1 << (endPosition - startPosition + 1)) - 1) << startPosition;
value &= ~mask;
value |= (bitValue << startPosition);
return value;
}
}
... ...
... ... @@ -161,6 +161,7 @@ public class BusinessDataUpdateService {
{
String id = olddevice.getClient_id()+"_"+key;
SaveDataDto saveDataDto = dataModeAnalysisService.analysisThingsModelValue( id,olddevice.getMqtt_username(),jsData,serverDto);
IotTerminal terminal = new IotTerminal();
terminal.setId(id);
terminal.setDevice_id(olddevice.getClient_id());
... ... @@ -169,6 +170,11 @@ public class BusinessDataUpdateService {
//更新数据
IotTerminal oldterminal = cacheService.getIotTerminal(id);
if(null == saveDataDto)
{
logger.info("无法解析到入库数据");
return terminal;
}
//记录操作日志
if(null != oldterminal && ("ADD".equals(type.name())|| "READ".equals(type.name())))
{
... ... @@ -184,6 +190,7 @@ public class BusinessDataUpdateService {
String str = (null!=oldterminal?oldterminal.getThings_model_config():null);
terminal.setThings_model_config(deviceService.getNewAdddate(id,str,saveDataDto.getConfig(),serverDto.getLogDeviceOperationList(),operationType,isLog).toJSONString());
terminal.setName(oldterminal.getName());
return terminal;
}
... ...
... ... @@ -9,7 +9,6 @@ import org.springframework.context.annotation.ComponentScan;
@ComponentScan(basePackages = {
"com.zhonglai.luhui.mqtt.comm.config",
"com.zhonglai.luhui.device.analysis",
"com.zhonglai.luhui.mqtt.comm.service",
"com.zhonglai.luhui.mqtt.comm.rocketMq",
... ...
... ... @@ -29,6 +29,7 @@ public class TopicUtil {
String cf = config[i].replace("{{","").replace("}}","");
try {
Field field = topicObject.getClass().getDeclaredField(cf);
field.setAccessible(true);
field.set(topicObject,sts[i]);
} catch (NoSuchFieldException e) {
log.info("{}生成topic时没有属性{}",topic,cf);
... ...
... ... @@ -46,7 +46,7 @@ mqtt:
clientId: ${random.uuid}
#公司id
roleid: 2
mqtt_usernames: NWDB_2023
mqtt_usernames: 12_ZNZY
#订阅的topic
topics: ADD_POST,ALL_POST,DB_TOPIC_DISTRIBUTE,GET/+,online,PUT_REQ/+,READ_REQ/+
sub_clientid: '+'
... ...
#!/bin/bash
# 如果编码格式有问题执行:sed -i 's/\r$//' guard.sh
# 定义要检查的 JAR 文件名和启动命令
JAR_FILE="lh-smart-feeder.jar"
START_COMMAND="java -jar $JAR_FILE"
# 检查 JAR 程序是否在运行
is_running() {
pgrep -f "$JAR_FILE" >/dev/null 2>&1
}
# 启动 JAR 程序
start_program() {
/opt/lh-smart-feeder/lh-smart-feeder/start.sh
}
# 检查 JAR 程序是否在运行
if ! is_running; then
echo "JAR程序未启动,将在3秒后自动启动..."
sleep 3
start_program
else
echo "JAR程序已启动"
fi
... ...
#!/bin/bash
# 设置Java运行环境的路径
export JAVA_HOME=/opt/lh-smart-feeder/jdk1.8.0_202/
# 设置jar文件路径和名称
JAR_FILE=/opt/lh-smart-feeder/lh-smart-feeder/lh-smart-feeder.jar
# 配置文件路径和名称
CONFIG_FILE=/opt/lh-smart-feeder/lh-smart-feeder/application.yml
# 设置opencv的驱动路径
OPENCV_JAVA_PATH=/opt/lh-smart-feeder/lh-smart-feeder/libopencv_java451.so
# 执行jar文件
$JAVA_HOME/bin/java -jar -Xms1024m -Xmx1024m -Xss512k $JAR_FILE $OPENCV_JAVA_PATH --spring.config.location=$CONFIG_FILE 2>&1 &
\ No newline at end of file
... ...
#!/bin/bash
# 查找并杀死jar文件的进程
PID=$(ps aux | grep lh-smart-feeder.jar | grep -v grep | awk '{print $2}')
if [[ -n $PID ]]; then
kill $PID
fi
... ...
... ... @@ -9,8 +9,6 @@ import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.FilterType;
import org.springframework.scheduling.annotation.EnableScheduling;
... ...
... ... @@ -14,18 +14,19 @@ import java.util.ArrayList;
import java.util.List;
@Configuration
public class HttpMessageConverterConfig {
@Autowired
public void configureHttpMessageConverters(HttpMessageConverters converters, Gson gson) {
List<HttpMessageConverter<?>> converterList = new ArrayList<>(converters.getConverters());
for (HttpMessageConverter<?> converter : converterList) {
if (converter instanceof MappingJackson2HttpMessageConverter) {
converterList.remove(converter);
break;
}
}
converterList.add(new GsonHttpMessageConverter(gson));
}
}
//@Configuration
//public class HttpMessageConverterConfig {
// @Autowired
// public void configureHttpMessageConverters(HttpMessageConverters converters, Gson gson) {
// List<HttpMessageConverter<?>> converterList = new ArrayList<>(converters.getConverters());
// for (HttpMessageConverter<?> converter : converterList) {
// if (converter instanceof MappingJackson2HttpMessageConverter) {
// converterList.remove(converter);
// break;
// }
// }
//
// converterList.add(new GsonHttpMessageConverter(gson));
// }
//
//}
... ...
... ... @@ -52,15 +52,15 @@ public class SwaggerConfig {
}
/**
* 解决/v2/api-docs返回多了一层value的问题
* @return
*/
@Bean
public FilterRegistrationBean someFilterRegistration() {
FilterRegistrationBean registration = new FilterRegistrationBean();
registration.setFilter(new ResponseFilter());
// 过滤的地址
registration.addUrlPatterns("/v2/api-docs");
return registration;
}
// * 解决/v2/api-docs返回多了一层value的问题
// * @return
// */
// @Bean
// public FilterRegistrationBean someFilterRegistration() {
// FilterRegistrationBean registration = new FilterRegistrationBean();
// registration.setFilter(new ResponseFilter());
// // 过滤的地址
// registration.addUrlPatterns("/v2/api-docs");
// return registration;
// }
}
\ No newline at end of file
... ...
package com.zhonglai.luhui.smart.feeder.config.manager;
import com.zhonglai.luhui.smart.feeder.service.DeviceService;
import com.zhonglai.luhui.smart.feeder.service.EhCacheService;
import com.zhonglai.luhui.smart.feeder.service.TerminalService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
... ... @@ -21,11 +23,19 @@ public class ShutdownManager
@Autowired
private EhCacheService ehCacheService;
@Autowired
private DeviceService deviceService;
@Autowired
private TerminalService terminalService;
@PreDestroy
public void destroy()
{
shutdownAsyncManager();
terminalService.close();
deviceService.close();
ehCacheService.shutdown();
shutdownAsyncManager();
}
/**
... ...
... ... @@ -4,6 +4,8 @@ import com.ruoyi.common.core.domain.AjaxResult;
import com.zhonglai.luhui.smart.feeder.config.WebSocketClien;
import com.zhonglai.luhui.smart.feeder.dto.ModbusDto;
import com.zhonglai.luhui.smart.feeder.service.DeviceService;
import com.zhonglai.luhui.smart.feeder.util.FeederCommd06ResponseType;
import com.zhonglai.luhui.smart.feeder.util.FeederCommdUtil;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
... ... @@ -62,6 +64,20 @@ public class CameraController {
return AjaxResult.success();
}
@ApiOperation("强行打开串口")
@ApiImplicitParams({
@ApiImplicitParam(value = "串口名称",name = "portName"),
@ApiImplicitParam(value = "波特率",name = "baudrate"),
@ApiImplicitParam(value = "数据位",name = "dataBits"),
@ApiImplicitParam(value = "停止位",name = "stopBits"),
@ApiImplicitParam(value = "校验位",name = "parity"),
})
@GetMapping("/nowOpenSerial")
public AjaxResult nowOpenSerial(String portName, Integer baudrate, Integer dataBits, Integer stopBits,Integer parity) throws Exception {
deviceService.nowOpenSerial(portName,baudrate,dataBits,stopBits,parity);
return AjaxResult.success();
}
@ApiOperation("串口发送指令")
@GetMapping("/sendSerialData")
public AjaxResult sendSerialData(String hexStr) throws IOException {
... ... @@ -70,6 +86,13 @@ public class CameraController {
return AjaxResult.success(commdDto);
}
@ApiOperation("地址发送指令")
@GetMapping("/controlData")
public AjaxResult controlData(FeederCommd06ResponseType feederCommd06ResponseType,int value) throws IOException {
ModbusDto commdDto = deviceService.sendData(FeederCommdUtil.controlData( feederCommd06ResponseType, value));
return AjaxResult.success(commdDto);
}
@ApiOperation("获取所有串口")
@GetMapping("/getAllSerial")
public AjaxResult getAllSerial() {
... ...
... ... @@ -26,71 +26,72 @@ public class RegisterConreoller {
{
List<Register> list = new ArrayList<>();
int startaddress = 23;
for(int i=0;i<24;i++)
for(int i=0;i<48;i+=2)
{
int timerNumber = i/2+1;
Register register = new Register();
register.setAddress(startaddress+i);
register.setClas("java.lang.String");
register.setClas("com.zhonglai.luhui.smart.feeder.dto.commd.FeederTimer");
register.setName("开启分钟");
register.setStart_char(0);
register.setChar_lenth(8);
register.setField_name("timer"+(register.getAddress()-22+1)+"_start_m");
register.setField_name("timer"+timerNumber+"_start_m");
Register register1 = new Register();
register1.setAddress(startaddress+i);
register1.setClas("java.lang.String");
register1.setClas("com.zhonglai.luhui.smart.feeder.dto.commd.FeederTimer");
register1.setName("开启小时");
register1.setStart_char(8);
register1.setChar_lenth(6);
register1.setField_name("timer"+(register1.getAddress()-22+1)+"_start_h");
register1.setField_name("timer"+timerNumber+"_start_h");
Register register2 = new Register();
register2.setAddress(startaddress+i);
register2.setClas("java.lang.Integer");
register2.setClas("com.zhonglai.luhui.smart.feeder.dto.commd.FeederTimer");
register2.setName("使能");
register2.setStart_char(14);
register2.setChar_lenth(1);
register2.setField_name("timer"+(register2.getAddress()-22+1)+"_if_start");
register2.setField_name("timer"+timerNumber+"_if_start");
Register register3 = new Register();
register3.setAddress(startaddress+i);
register3.setClas("java.lang.Integer");
register3.setClas("com.zhonglai.luhui.smart.feeder.dto.commd.FeederTimer");
register3.setName("有效");
register3.setStart_char(15);
register3.setChar_lenth(1);
register3.setField_name("timer"+(register3.getAddress()-22+1)+"_is_start");
register3.setField_name("timer"+timerNumber+"_is_start");
Register register4 = new Register();
register4.setAddress(startaddress+i);
register4.setClas("java.lang.String");
register4.setAddress(startaddress+1+i);
register4.setClas("com.zhonglai.luhui.smart.feeder.dto.commd.FeederTimer");
register4.setName("关闭分钟");
register4.setStart_char(0);
register4.setChar_lenth(8);
register4.setField_name("timer"+(register4.getAddress()-22+1)+"_close_m");
register4.setField_name("timer"+timerNumber+"_close_m");
Register register5 = new Register();
register5.setAddress(startaddress+i);
register5.setClas("java.lang.String");
register5.setAddress(startaddress+1+i);
register5.setClas("com.zhonglai.luhui.smart.feeder.dto.commd.FeederTimer");
register5.setName("关闭小时");
register5.setStart_char(8);
register5.setChar_lenth(6);
register5.setField_name("timer"+(register5.getAddress()-22+1)+"_close_h");
register5.setField_name("timer"+timerNumber+"_close_h");
Register register6 = new Register();
register6.setAddress(startaddress+i);
register6.setClas("java.lang.Integer");
register6.setAddress(startaddress+1+i);
register6.setClas("com.zhonglai.luhui.smart.feeder.dto.commd.FeederTimer");
register6.setName("使能");
register6.setStart_char(14);
register6.setChar_lenth(1);
register6.setField_name("timer"+(register6.getAddress()-22+1)+"_if_close");
register6.setField_name("timer"+timerNumber+"_if_close");
Register register7 = new Register();
register7.setAddress(startaddress+i);
register7.setClas("java.lang.Integer");
register7.setAddress(startaddress+1+i);
register7.setClas("com.zhonglai.luhui.smart.feeder.dto.commd.FeederTimer");
register7.setName("有效");
register7.setStart_char(15);
register7.setChar_lenth(1);
register7.setField_name("timer"+(register7.getAddress()-22+1)+"_is_close");
register7.setField_name("timer"+timerNumber+"_is_close");
list.add(register);
list.add(register1);
... ...
... ... @@ -8,12 +8,12 @@ import java.util.HashMap;
public enum ConfigurationParameter {
ifUpLoadData(false, Boolean.class,"sys_config","是否上报数据",true),//是否上报数据
ifVeiw(false, Boolean.class,"sys_config","是否显示",true),//是否显示
captureNumber(0, Integer.class,"sys_config","摄像头编号",true),//摄像头编号
reflectionThreshold(100, Integer.class,"sys_config","反光阈值",true),//反光阈值
kernelSize(3, Integer.class,"sys_config","去噪调整内核大小,用来消除小的物体或噪声",true),//去噪调整内核大小,用来消除小的物体或噪声
maxValue(255, Integer.class,"sys_config","最大反光阈值",true), //最大反光阈值
gear_command (new HashMap<String,String>(),HashMap.class,"gear_command","档位对应的指令",true), //档位对应的指令
absValue_command (new ArrayList<FishCurveControlCondition>(),ArrayList.class,"absValue_command","斜率范围对应的档位",true), //斜率范围对应的档位
VeiwDto_isFrame(false, Boolean.class,"sys_config","是否显示原图",true), //是否显示原图
VeiwDto_isBinaryImage(false, Boolean.class,"sys_config","是否显示临时图",true), //是否显示临时图
... ... @@ -21,17 +21,17 @@ public enum ConfigurationParameter {
VeiwDto_isAbsValue(false, Boolean.class,"sys_config","是否显示斜率",true), //是否显示斜率
absValue(0.0, Double.class,"sys_config","显示斜率",false), //斜率
FishGroupImageRecognition(true, Boolean.class,"sys_config","鱼群图像识别是否开启",true), //鱼群图像识别是否开启
FeedingControl(true, Boolean.class,"sys_config","鱼群图像识别投料控制是否开启",true), //鱼群图像识别投料控制是否开启
FeedingControl(true, Boolean.class,"sys_config","鱼群图像识别控制投料控制是否开启",true), //鱼群图像识别投料控制是否开启
SerialPortConfig(new SerialPortConfig().defaultSerialPortConfig(),com.zhonglai.luhui.smart.feeder.dto.SerialPortConfig.class,"sys_config","串口配置",true),//串口配置
;
private Object value;
private Class<?> valuType;
private String tableName;
private Object value; //值
private Class<?> valuType; //数据类型
private String tableName; //表名
private String describe;
private String describe; //描述
private Boolean persistence;
private Boolean persistence; //是否需要持久化
ConfigurationParameter(Object value,Class valuType,String tableName,String describe,Boolean persistence) {
this.value = value;
... ... @@ -72,6 +72,10 @@ public enum ConfigurationParameter {
case "java.lang.Double":
return o+"";
case "com.zhonglai.luhui.smart.feeder.dto.SerialPortConfig":
if(o instanceof String)
{
return (String) o;
}
return JSONObject.toJSONString(o);
default:
throw new RuntimeException("配置参数类型不正确" + name() + o);
... ...
... ... @@ -24,6 +24,11 @@ public class ModbusDto implements Serializable {
public ModbusDto(Integer address,Integer commdcode,byte[] data)
{
toModbusDto(address,commdcode,data);
}
protected void toModbusDto(Integer address,Integer commdcode,byte[] data)
{
this.address = address;
this.commdcode = commdcode;
this.data = data;
... ... @@ -71,22 +76,11 @@ public class ModbusDto implements Serializable {
// 计算CRC校验码
public static String generateLRC(byte[] data)
{
return ByteUtil.toHexString(ByteUtil.intToBytesASC(getLRC(data),1));
return ByteUtil.getCRC16(data);
}
public static byte getLRC(byte[] data) {
int tmp = 0;
for (int i = 0; i < data.length; i++) {
tmp = tmp + (byte) data[i];
}
tmp = ~tmp;
tmp = (tmp & (0xff));
tmp += 1;
return (byte) tmp;
}
public static void main(String[] args) {
String hexData = "01 03 8E 00 01 00 04 FF E0 00 00 00 00 00 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 01 00 07 00 03 00 00 00 1D 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00".replace(" ","");
String hexData = "01 03 00 0D 00 01".replace(" ","");
String crc = ByteUtil.getCRC16(ByteUtil.hexStringToByte(hexData));
System.out.println(crc);
... ...
... ... @@ -20,10 +20,10 @@ public class SerialPortConfig implements Serializable {
public SerialPortConfig defaultSerialPortConfig()
{
portName = "COM6";
baudrate = 9600;
portName = "COM3";
baudrate = 19200;
dataBits = 8;
stopBits = 0;
stopBits = 1;
parity = 0;
return this;
}
... ...
package com.zhonglai.luhui.smart.feeder.dto;
/**
* 状态数据
*/
public class StateData {
private Integer faultcode; //故障代码
private Integer fodderstate; //饲料状态
private Integer runmode; //运行模式
private Integer runspeed; //投料量
private Integer worktime; //投料时间
private Integer interval; //间隔时间
private Integer switch_status; //开/关
private Integer stopfeedcnt; //停投料倒计时
public Integer getFaultcode() {
return faultcode;
}
public void setFaultcode(Integer faultcode) {
this.faultcode = faultcode;
}
public Integer getFodderstate() {
return fodderstate;
}
public void setFodderstate(Integer fodderstate) {
this.fodderstate = fodderstate;
}
public Integer getRunmode() {
return runmode;
}
public void setRunmode(Integer runmode) {
this.runmode = runmode;
}
public Integer getRunspeed() {
return runspeed;
}
public void setRunspeed(Integer runspeed) {
this.runspeed = runspeed;
}
public Integer getWorktime() {
return worktime;
}
public void setWorktime(Integer worktime) {
this.worktime = worktime;
}
public Integer getInterval() {
return interval;
}
public void setInterval(Integer interval) {
this.interval = interval;
}
public Integer getSwitch_status() {
return switch_status;
}
public void setSwitch_status(Integer switch_status) {
this.switch_status = switch_status;
}
public Integer getStopfeedcnt() {
return stopfeedcnt;
}
public void setStopfeedcnt(Integer stopfeedcnt) {
this.stopfeedcnt = stopfeedcnt;
}
}
... ...
... ... @@ -20,4 +20,19 @@ public class FeederCommd03Request implements FeederCommd {
}
}
public Integer getLenth() {
return lenth;
}
public void setLenth(Integer lenth) {
this.lenth = lenth;
}
public Map<Integer, byte[]> getAddressValue() {
return addressValue;
}
public void setAddressValue(Map<Integer, byte[]> addressValue) {
this.addressValue = addressValue;
}
}
... ...
package com.zhonglai.luhui.smart.feeder.dto.commd;
/**
* 读取用指令对象
*/
public class FeederCommd03Response implements FeederCommd{
private static final long serialVersionUID = -5498638326172560045L;
private static final long serialVersionUID = 7305511069956383139L;
private Integer start_char;
private Integer char_lenth;
... ...
package com.zhonglai.luhui.smart.feeder.dto.commd;
import com.ruoyi.common.utils.ByteUtil;
import org.apache.commons.lang3.ArrayUtils;
import java.util.HashMap;
import java.util.Map;
public class FeederCommd06Request implements FeederCommd {
private static final long serialVersionUID = -6014991157685504839L;
private Integer register_address; //寄存器地址位
private Integer value; //值
public FeederCommd06Request(byte[] data)
{
register_address = new Long(ByteUtil.bytesToLongDESC(data,0,2)).intValue();
value = new Long(ByteUtil.bytesToLongDESC(data,2,2)).intValue();
}
public Integer getRegister_address() {
return register_address;
}
public void setRegister_address(Integer register_address) {
this.register_address = register_address;
}
public Integer getValue() {
return value;
}
public void setValue(Integer value) {
this.value = value;
}
}
... ...
package com.zhonglai.luhui.smart.feeder.dto.commd;
/**
* 单个写入用指令对象
*/
public class FeederCommd06Response implements FeederCommd{
private static final long serialVersionUID = 3192313530334923453L;
private Integer register_address; //寄存器地址位
private Integer value; //值
public FeederCommd06Response(Integer register_address, Integer value)
{
this.register_address = register_address;
this.value = value;
}
public Integer getRegister_address() {
return register_address;
}
public void setRegister_address(Integer register_address) {
this.register_address = register_address;
}
public Integer getValue() {
return value;
}
public void setValue(Integer value) {
this.value = value;
}
}
... ...
package com.zhonglai.luhui.smart.feeder.dto.commd;
import com.ruoyi.common.utils.ByteUtil;
import org.apache.commons.lang3.ArrayUtils;
import java.util.HashMap;
import java.util.Map;
public class FeederCommd10Request implements FeederCommd {
private static final long serialVersionUID = -1133094844579154481L;
private Integer start_char; //起始地址位
private Integer register_number; //寄存器个数
private Integer byte_lenth; //字节个数
private byte[] data; //数据
public FeederCommd10Request(byte[] data)
{
start_char = new Long(ByteUtil.bytesToLongDESC(data,0,2)).intValue();
register_number = new Long(ByteUtil.bytesToLongDESC(data,2,2)).intValue();
byte_lenth = new Long(ByteUtil.bytesToLongDESC(data,4,2)).intValue();
data = ArrayUtils.subarray(data,6,6+byte_lenth);
}
public Integer getStart_char() {
return start_char;
}
public void setStart_char(Integer start_char) {
this.start_char = start_char;
}
public Integer getRegister_number() {
return register_number;
}
public void setRegister_number(Integer register_number) {
this.register_number = register_number;
}
public Integer getByte_lenth() {
return byte_lenth;
}
public void setByte_lenth(Integer byte_lenth) {
this.byte_lenth = byte_lenth;
}
public byte[] getData() {
return data;
}
public void setData(byte[] data) {
this.data = data;
}
}
... ...
package com.zhonglai.luhui.smart.feeder.dto.commd;
/**
* 多个写入用指令对象
*/
public class FeederCommd10Response implements FeederCommd{
private static final long serialVersionUID = 7575699996080249797L;
private Integer start_char; //起始地址位
private Integer register_number; //寄存器个数
private Integer byte_lenth; //字节个数
private byte[] data; //数据
public FeederCommd10Response(Integer start_char, Integer register_number,Integer byte_lenth,byte[] data)
{
this.start_char = start_char;
this.register_number = register_number;
this.byte_lenth = byte_lenth;
this.data = data;
}
public Integer getStart_char() {
return start_char;
}
public void setStart_char(Integer start_char) {
this.start_char = start_char;
}
public Integer getRegister_number() {
return register_number;
}
public void setRegister_number(Integer register_number) {
this.register_number = register_number;
}
public Integer getByte_lenth() {
return byte_lenth;
}
public void setByte_lenth(Integer byte_lenth) {
this.byte_lenth = byte_lenth;
}
public byte[] getData() {
return data;
}
public void setData(byte[] data) {
this.data = data;
}
}
... ...
package com.zhonglai.luhui.smart.feeder.dto.commd;
import cn.hutool.core.util.ArrayUtil;
import com.ruoyi.common.utils.ByteUtil;
import com.zhonglai.luhui.smart.feeder.dto.ModbusDto;
import lombok.Data;
import java.util.HashMap;
import java.util.Map;
/**
* 投料机协议Modbus
... ... @@ -12,38 +10,49 @@ import java.util.Map;
public class FeederCommdDto extends ModbusDto {
private static final long serialVersionUID = -2783135648395348130L;
private Integer quantity; //寄存器数量
private Map<Integer,byte[]> value = new HashMap<>(); //
private FeederCommd feederCommd;
public static FeederCommdDto initRead(byte[] requesBytes)
public FeederCommdDto(FeederCommd03Response feederCommdResponse)
{
FeederCommdDto feederCommdDto = new FeederCommdDto(requesBytes);
switch (feederCommdDto.getCommdcode())
{
case 0x03:
feederCommdDto.setFeederCommd(new FeederCommd03Request(feederCommdDto.getData()));
break;
case 0x06:
break;
case 0x10:
break;
}
return feederCommdDto;
byte[] start_bytes = ByteUtil.intToBytesDESC(feederCommdResponse.getStart_char(),2);
byte[] lenth_bytes = ByteUtil.intToBytesDESC( feederCommdResponse.getChar_lenth(),2);
super.toModbusDto(0x01,0x03, ArrayUtil.addAll(start_bytes,lenth_bytes));
this.feederCommd = feederCommdResponse;
}
public FeederCommdDto initWrite(FeederCommd03Response feederCommdResponse)
public FeederCommdDto(FeederCommd06Response feederCommd06Response)
{
this.feederCommd = feederCommdResponse;
feederCommdResponse.getStart_char();
feederCommdResponse.getChar_lenth();
byte[] start_bytes = ByteUtil.intToBytesDESC(feederCommd06Response.getRegister_address(),2);
byte[] lenth_bytes = ByteUtil.intToBytesDESC( feederCommd06Response.getValue(),2);
super.toModbusDto(0x01,0x06, ArrayUtil.addAll(start_bytes,lenth_bytes));
this.feederCommd = feederCommd06Response;
}
return new FeederCommdDto(requesBytes);
public FeederCommdDto(FeederCommd10Response feederCommd10Response)
{
byte[] start_bytes = ByteUtil.intToBytesDESC(feederCommd10Response.getStart_char(),2);
byte[] number_bytes = ByteUtil.intToBytesDESC( feederCommd10Response.getRegister_number(),2);
byte[] lenth_bytes = ByteUtil.intToBytesDESC( feederCommd10Response.getByte_lenth(),2);
byte[] data = feederCommd10Response.getData();
super.toModbusDto(0x01,0x10, ArrayUtil.addAll(start_bytes,number_bytes,lenth_bytes,data));
this.feederCommd = feederCommd10Response;
}
public FeederCommdDto(byte[] requesBytes) {
super(requesBytes);
switch (super.getCommdcode())
{
case 0x03:
feederCommd = new FeederCommd03Request(super.getData());
break;
case 0x06:
feederCommd = new FeederCommd06Request(super.getData());
break;
case 0x10:
feederCommd = new FeederCommd10Request(super.getData());
break;
}
}
public FeederCommdDto() {
... ... @@ -54,22 +63,6 @@ public class FeederCommdDto extends ModbusDto {
super(str);
}
public Integer getQuantity() {
return quantity;
}
public void setQuantity(Integer quantity) {
this.quantity = quantity;
}
public Map<Integer, byte[]> getValue() {
return value;
}
public void setValue(Map<Integer, byte[]> value) {
this.value = value;
}
public FeederCommd getFeederCommd() {
return feederCommd;
}
... ... @@ -77,4 +70,14 @@ public class FeederCommdDto extends ModbusDto {
public void setFeederCommd(FeederCommd feederCommd) {
this.feederCommd = feederCommd;
}
public static void main(String[] args) {
FeederCommdDto feederCommdDto03 = new FeederCommdDto(new FeederCommd03Response(0,71));
FeederCommdDto feederCommdDto06 = new FeederCommdDto(new FeederCommd06Response(0,1));
// FeederCommdDto feederCommdDto10 = new FeederCommdDto(new FeederCommd10Response(21,4,8,));
System.out.println(feederCommdDto03);
System.out.println(feederCommdDto06);
// System.out.println(feederCommdDto10);
}
}
... ...
package com.zhonglai.luhui.smart.feeder.dto.commd;
/**
* 定时器
*/
public class FeederTimer {
private Integer timer_start_m;
private Integer timer_start_h;
private Integer timer_if_start;
private Integer timer_is_start;
private Integer timer_close_m;
private Integer timer_close_h;
private Integer timer_if_close;
private Integer timer_is_close;
public void setObjectValue(String field,long value)
{
switch (field)
{
case "timer_start_m":
timer_start_m = Integer.valueOf(Long.toString(value));
break;
case "timer_start_h":
timer_start_h =Integer.valueOf(Long.toString(value));
break;
case "timer_if_start":
timer_if_start =Integer.valueOf(Long.toString(value));
break;
case "timer_is_start":
timer_is_start =Integer.valueOf(Long.toString(value));
break;
case "timer_close_m":
timer_close_m =Integer.valueOf(Long.toString(value));
break;
case "timer_close_h":
timer_close_h =Integer.valueOf(Long.toString(value));
break;
case "timer_if_close":
timer_if_close =Integer.valueOf(Long.toString(value));
break;
case "timer_is_close":
timer_is_close =Integer.valueOf(Long.toString(value));
break;
}
}
public Integer getTimer_start_m() {
return timer_start_m;
}
public void setTimer_start_m(Integer timer_start_m) {
this.timer_start_m = timer_start_m;
}
public Integer getTimer_start_h() {
return timer_start_h;
}
public void setTimer_start_h(Integer timer_start_h) {
this.timer_start_h = timer_start_h;
}
public Integer getTimer_if_start() {
return timer_if_start;
}
public void setTimer_if_start(Integer timer_if_start) {
this.timer_if_start = timer_if_start;
}
public Integer getTimer_is_start() {
return timer_is_start;
}
public void setTimer_is_start(Integer timer_is_start) {
this.timer_is_start = timer_is_start;
}
public Integer getTimer_close_m() {
return timer_close_m;
}
public void setTimer_close_m(Integer timer_close_m) {
this.timer_close_m = timer_close_m;
}
public Integer getTimer_close_h() {
return timer_close_h;
}
public void setTimer_close_h(Integer timer_close_h) {
this.timer_close_h = timer_close_h;
}
public Integer getTimer_if_close() {
return timer_if_close;
}
public void setTimer_if_close(Integer timer_if_close) {
this.timer_if_close = timer_if_close;
}
public Integer getTimer_is_close() {
return timer_is_close;
}
public void setTimer_is_close(Integer timer_is_close) {
this.timer_is_close = timer_is_close;
}
}
... ...
package com.zhonglai.luhui.smart.feeder.service;
import cn.hutool.core.bean.BeanUtil;
import com.google.gson.JsonObject;
import com.ruoyi.common.utils.ByteUtil;
import com.zhonglai.luhui.smart.feeder.Main;
import com.zhonglai.luhui.smart.feeder.domain.Register;
import com.zhonglai.luhui.smart.feeder.dto.ModbusDto;
import com.zhonglai.luhui.smart.feeder.dto.commd.FeederCommd;
import com.zhonglai.luhui.smart.feeder.dto.commd.FeederCommd03Request;
import com.zhonglai.luhui.smart.feeder.dto.commd.FeederCommdDto;
import com.zhonglai.luhui.smart.feeder.dto.commd.FeederTimer;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* 数据解析服务
*/
@Service
public class AnalysisDataService {
private static final Logger logger = LoggerFactory.getLogger(AnalysisDataService.class);
@Autowired
private ConfigurationParameterService configurationParameterService;
public Map<String,Object> analysis(ModbusDto modbusDto)
{
if(modbusDto instanceof FeederCommdDto)
{
FeederCommdDto feederCommdDto = (FeederCommdDto) modbusDto;
FeederCommd feederCommd = feederCommdDto.getFeederCommd();
if (feederCommd instanceof FeederCommd03Request)
{
Map<Integer, List<Register>> configMap = configurationParameterService.getRegisterMap();
Map<String,Object> valueMap = new HashMap<>();
FeederCommd03Request feederCommd03Request = (FeederCommd03Request) feederCommd;
Map<Integer, byte[]> map = feederCommd03Request.getAddressValue();
for (Integer adrress:map.keySet())
{
byte[] bytes = map.get(adrress);
List<Register> registers = configMap.get(adrress);
if(null != registers)
{
for (Register register:registers)
{
try {
registerTo(valueMap,bytes,register);
}catch (Exception e)
{
logger.error("根据字典解析异常",e);
}
}
}else{
logger.error("未读取到"+adrress+"的地址读取配置");
}
}
return valueMap;
}
}
return null;
}
private void registerTo(Map<String,Object> valueMap,byte[] bytes,Register register)
{
String field = register.getField_name();
long value = ByteUtil.readBits(ByteUtil.bytesToLongDESC(bytes,0,2),register.getStart_char(),register.getChar_lenth());
switch (register.getClas())
{
case "java.lang.Integer":
valueMap.put(field,Integer.valueOf(Long.toString(value)));
break;
case "java.lang.Boolean":
valueMap.put(field,Boolean.valueOf(Long.toString(value)));
break;
case "java.lang.Float":
valueMap.put(field,Float.valueOf(Long.toString(value)));
break;
case "com.zhonglai.luhui.smart.feeder.dto.commd.FeederTimer":
String timerKey = field.split("_")[0];
FeederTimer feederTimer = (FeederTimer) valueMap.get(timerKey);
if(!valueMap.containsKey(timerKey))
{
feederTimer = new FeederTimer();
valueMap.put(timerKey,feederTimer);
}
feederTimer.setObjectValue(field,value);
break;
}
}
}
... ...
... ... @@ -71,14 +71,6 @@ public class CameraService {
// }
}
/**
* 守护摄像头
*/
@PostConstruct
private void guardCapture()
{
start();
}
/**
* 检测摄像头是否打开
... ...
package com.zhonglai.luhui.smart.feeder.service;
import cn.hutool.core.bean.BeanUtil;
import com.zhonglai.luhui.smart.feeder.domain.Register;
import com.zhonglai.luhui.smart.feeder.dto.ConfigurationParameter;
import com.zhonglai.luhui.smart.feeder.dto.FishCurveControlCondition;
import com.zhonglai.luhui.smart.feeder.dto.StateData;
import org.ehcache.Cache;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
... ... @@ -18,16 +20,20 @@ import java.util.Map;
*/
@Service
public class ConfigurationParameterService {
private Map<Integer,List<Register>> registerMap = new HashMap<>();
@Autowired
private EhCacheService ehCacheService;
@Autowired
private SqliteService sqliteService;
@PostConstruct
private StateData stateData;
public void initConfigurationParameter()
{
//系统配置
List<Map<String,Object>> sysConfigList = sqliteService.getAllSysConfig();
if(null != sysConfigList && sysConfigList.size() != 0)
{
... ... @@ -38,25 +44,30 @@ public class ConfigurationParameterService {
}
}
List<Map<String,Object>> gearCommandList = sqliteService.getAllGearCommand();
Map<String,String> gearCommandMap = new HashMap<String,String>();
if(null != gearCommandList && gearCommandList.size() != 0)
{
for(Map<String,Object> map:gearCommandList)
{
gearCommandMap.put(map.get("gear")+"",(String)map.get("command"));
}
}
ehCacheService.writeToCache(ConfigurationParameter.gear_command,gearCommandMap);
//斜率对应的档位
List<FishCurveControlCondition> absValueCommandList = sqliteService.getAllAbsValueCommand();
ehCacheService.writeToCache(ConfigurationParameter.absValue_command,new ArrayList<>());
if(null != absValueCommandList && absValueCommandList.size() != 0)
{
ehCacheService.writeToCache(ConfigurationParameter.absValue_command,absValueCommandList);
}
//数据解析字典
List<Map<String,Object>> registerList = sqliteService.getAllRegister();
if(null != registerList && registerList.size() != 0)
{
for (Map<String,Object> map:registerList)
{
Register register = BeanUtil.mapToBean(map,Register.class,false,null);
List<Register> list = registerMap.get(register.getAddress());
if(null == list)
{
list = new ArrayList<>();
registerMap.put(register.getAddress(),list);
}
list.add(register);
}
}
}
public Cache<String, Object> getAll()
... ... @@ -66,15 +77,8 @@ public class ConfigurationParameterService {
public synchronized void setConfig(ConfigurationParameter configurationParameter,Object value)
{
if(configurationParameter !=configurationParameter.absValue_command && !configurationParameter.getValuType().isInstance(value) )
{
throw new RuntimeException("配置参数类型不正确");
}
switch (configurationParameter)
{
case gear_command:
setGearCommandMap((Map<String, String>) value);
break;
case absValue_command:
if(value instanceof ArrayList)
{
... ... @@ -129,20 +133,6 @@ public class ConfigurationParameterService {
sqliteService.updateConfigurationParameter(configurationParameter,value);
}
private void setGearCommandMap(Map<String,String> gearCommandMap)
{
Map<String,String> old = (Map<String, String>) ehCacheService.readFromCache(ConfigurationParameter.gear_command);
if(null == old)
{
old = gearCommandMap;
}
for (String key:gearCommandMap.keySet())
{
sqliteService.updateGearCommand(Integer.parseInt(key),gearCommandMap.get(key));
old.put(key,gearCommandMap.get(key));
}
ehCacheService.writeToCache(ConfigurationParameter.gear_command,old);
}
private void setabsValueCommandList(List<FishCurveControlCondition> absValueCommandList)
{
... ... @@ -172,4 +162,16 @@ public class ConfigurationParameterService {
sqliteService.updateabsValueCommand(absValueCommand.getGear(),absValueCommand.getSartAbsValue());
}
public Map<Integer, List<Register>> getRegisterMap() {
return registerMap;
}
public StateData getStateData() {
return stateData;
}
public void setStateData(StateData stateData) {
this.stateData = stateData;
}
}
... ...
package com.zhonglai.luhui.smart.feeder.service;
import cn.hutool.core.bean.BeanUtil;
import com.alibaba.fastjson.JSONObject;
import com.google.gson.JsonObject;
import com.ruoyi.common.utils.GsonConstructor;
import com.zhonglai.luhui.smart.feeder.Main;
import com.zhonglai.luhui.smart.feeder.dto.ConfigurationParameter;
import com.zhonglai.luhui.smart.feeder.dto.ModbusDto;
import com.zhonglai.luhui.smart.feeder.dto.StateData;
import com.zhonglai.luhui.smart.feeder.dto.commd.FeederCommd03Response;
import com.zhonglai.luhui.smart.feeder.dto.commd.FeederCommdDto;
import com.zhonglai.luhui.smart.feeder.util.FeederCommdUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
... ... @@ -8,6 +18,7 @@ import org.springframework.stereotype.Service;
import javax.annotation.PostConstruct;
import java.io.IOException;
import java.util.Map;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
... ... @@ -23,10 +34,23 @@ public class DateListenService {
@Autowired
private DeviceService deviceService;
@PostConstruct
@Autowired
private AnalysisDataService analysisDataService;
@Autowired
private TerminalService terminalService;
@Autowired
private ConfigurationParameterService configurationParameterService;
public void run()
{
scheduledExecutorService.scheduleAtFixedRate(() -> {
if(!(Boolean) configurationParameterService.getConfig(ConfigurationParameter.ifUpLoadData))
{
return;
}
try {
deviceService.openDefaultSerialPort();
} catch (Exception e) {
... ... @@ -34,11 +58,21 @@ public class DateListenService {
return;
}
try {
deviceService.sendData("01 03 00 00 00 47 05 F8".replace(" ","").trim());
ModbusDto modbusDto = deviceService.sendData(FeederCommdUtil.readAll());
Map<String,Object> data = analysisDataService.analysis(modbusDto);
if(null != data && data.size() != 0)
{
StateData stateData = BeanUtil.mapToBean(data, StateData.class,false,null);
configurationParameterService.setStateData(stateData);
JSONObject jsonObject = new JSONObject();
jsonObject.put("1",data);
terminalService.scheduledSubmissionData(jsonObject.toJSONString());
}
} catch (Exception e) {
logger.error("数据采集失败",e);
}
},1,60, TimeUnit.SECONDS);
}
... ...
... ... @@ -4,6 +4,8 @@ import com.ruoyi.common.utils.GsonConstructor;
import com.ruoyi.common.utils.StringUtils;
import com.zhonglai.luhui.smart.feeder.dto.*;
import com.zhonglai.luhui.smart.feeder.dto.commd.FeederCommdDto;
import com.zhonglai.luhui.smart.feeder.util.FeederCommd06ResponseType;
import com.zhonglai.luhui.smart.feeder.util.FeederCommdUtil;
import com.zhonglai.luhui.smart.feeder.util.serial.SerialTool;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
... ... @@ -13,6 +15,7 @@ import purejavacomm.SerialPort;
import javax.annotation.PostConstruct;
import java.io.IOException;
import java.io.OutputStream;
import java.util.*;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;
... ... @@ -26,8 +29,6 @@ import java.util.concurrent.TimeUnit;
public class DeviceService {
private static Logger logger = LoggerFactory.getLogger(DeviceService.class);
private SerialPort serialPort; //串口
// 锁对象
private final Object lock = new Object();
// 用于存储串口返回的数据,使用线程安全的队列
... ... @@ -43,6 +44,10 @@ public class DeviceService {
private Integer nowGear; //当前档位
private Integer oldGear; //老的档位
private Double area; //面积
@Autowired
private ConfigurationParameterService configurationParameterService;
... ... @@ -52,16 +57,41 @@ public class DeviceService {
@Autowired
private EhCacheService ehCacheService;
@PostConstruct
private SerialPort serialPort;
public void run()
{
//投料控制
scheduledExecutorService.scheduleWithFixedDelay(() -> {
if (((Boolean)ehCacheService.readFromCache(ConfigurationParameter.FeedingControl))) {
Map<Integer,String> map = (Map<Integer, String>) ehCacheService.readFromCache(ConfigurationParameter.gear_command);
if(null != map && StringUtils.isNotEmpty( map.get(nowGear)))
logger.info("当前档位{},以前的档位{},斜率{},斜率差值{},面积{},开关是否打开{}",nowGear,oldGear,slope,absValue,area,null == configurationParameterService.getStateData()?"未知":configurationParameterService.getStateData().getSwitch_status());
if(null != nowGear && oldGear != nowGear)
{
send485SerialData(map.get(nowGear));
if(nowGear>0 ) //如果档位有值
{
if(null !=configurationParameterService.getStateData() && 1==configurationParameterService.getStateData().getRunmode())
{
send485SerialData(FeederCommdUtil.controlData(FeederCommd06ResponseType.runmode,0)); //,运行模式改成手动
}
if(null !=configurationParameterService.getStateData() && 0==configurationParameterService.getStateData().getSwitch_status())
{
send485SerialData(FeederCommdUtil.controlData(FeederCommd06ResponseType.OnOroff,1)); //,开关是关的就先打开开关
}
send485SerialData(FeederCommdUtil.controlData(FeederCommd06ResponseType.runspeed,nowGear));
oldGear = nowGear;
}else{
if(null !=configurationParameterService.getStateData() && 0==configurationParameterService.getStateData().getRunmode())
{
send485SerialData(FeederCommdUtil.controlData(FeederCommd06ResponseType.runmode,1)); //,运行模式改成自动
}
if(null !=configurationParameterService.getStateData() && 1==configurationParameterService.getStateData().getSwitch_status())
{
send485SerialData(FeederCommdUtil.controlData(FeederCommd06ResponseType.OnOroff,0)); //,开关是关的就先打开开关
}
}
}
}
},1,1, TimeUnit.SECONDS);
... ... @@ -86,6 +116,7 @@ public class DeviceService {
*/
public double controlDevice(double area)
{
this.area = area;
if(null == backArea )
{
backArea = area;
... ... @@ -182,12 +213,33 @@ public class DeviceService {
SerialTool.addListener(serialPortEvent -> {
try {
Thread.sleep(500);
FeederCommdDto commdDto = FeederCommdDto.initRead (SerialTool.readFromPort(serialPort));
FeederCommdDto commdDto = new FeederCommdDto (SerialTool.readFromPort(serialPort));
dataQueue.offer(commdDto); // 将数据添加到队列中// 处理串口返回的数据
} catch (Exception e) {
logger.error("返回数据处理异常",e);
}
}, serialPort);
logger.info("打开串口成功");
}
public void nowOpenSerial(String portName, Integer baudrate, Integer dataBits, Integer stopBits,
Integer parity) throws Exception {
if(null != serialPort)
{
serialPort.removeEventListener();
serialPort.close();
}
serialPort = SerialTool.openPort(portName,baudrate,dataBits,stopBits,parity);
SerialTool.addListener(serialPortEvent -> {
try {
Thread.sleep(500);
FeederCommdDto commdDto = new FeederCommdDto (SerialTool.readFromPort(serialPort));
dataQueue.offer(commdDto); // 将数据添加到队列中// 处理串口返回的数据
} catch (Exception e) {
logger.error("返回数据处理异常",e);
}
}, serialPort);
}
public void openDefaultSerialPort() throws Exception {
... ... @@ -215,5 +267,14 @@ public class DeviceService {
}
public void close()
{
dataQueue.clear();
if(null != serialPort)
{
serialPort.removeEventListener();
serialPort.close();
}
}
}
... ...
... ... @@ -33,7 +33,6 @@ public class EhCacheService {
@Value("${sys.cacheFilePath}")
private String cacheFilePath;
@PostConstruct
public void instance()
{
cacheManager = CacheManagerBuilder.newCacheManagerBuilder()
... ...
... ... @@ -51,7 +51,6 @@ public class FishGroupImageRecognitionService {
private static Boolean isRun = false;
@PostConstruct
public void run()
{
scheduledExecutorService.scheduleWithFixedDelay(() -> {
... ...
package com.zhonglai.luhui.smart.feeder.service;
import org.eclipse.paho.client.mqttv3.MqttException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import javax.annotation.PostConstruct;
import java.util.concurrent.ScheduledExecutorService;
@Configuration
public class InitService {
@Autowired
private CameraService cameraService;
@Autowired
private ConfigurationParameterService configurationParameterService;
@Autowired
private DateListenService dateListenService;
@Autowired
private DeviceService deviceService;
@Autowired
private EhCacheService ehCacheService;
@Autowired
private FishGroupImageRecognitionService fishGroupImageRecognitionService;
@Autowired
private SqliteService sqliteService;
@Autowired
private TerminalService terminalService;
/**
* 守护摄像头
*/
@PostConstruct
private void run() throws MqttException {
//加载缓存
ehCacheService.instance();
//持久化初始
sqliteService.init();
//配置参数
configurationParameterService.initConfigurationParameter();
//摄像头监听
cameraService.start();
//鱼群识别
fishGroupImageRecognitionService.run();
//鱼群图像识别控制投料控制
deviceService.run();
//连接上报终端
terminalService.init();
//串口数据上报
dateListenService.run();
}
}
... ...
... ... @@ -25,7 +25,7 @@ public class MqttCallback implements MqttCallbackExtended {
@Override
public void messageArrived(String topic, MqttMessage message) throws Exception {
log.info("收到消息 {}",message);
}
@Override
... ...
... ... @@ -3,6 +3,7 @@ package com.zhonglai.luhui.smart.feeder.service;
import com.alibaba.fastjson.JSONObject;
import com.ruoyi.common.utils.GsonConstructor;
import com.zhonglai.luhui.dao.service.PublicService;
import com.zhonglai.luhui.smart.feeder.domain.Register;
import com.zhonglai.luhui.smart.feeder.dto.ConfigurationParameter;
import com.zhonglai.luhui.smart.feeder.dto.FishCurveControlCondition;
import com.zhonglai.luhui.smart.feeder.dto.SerialPortConfig;
... ... @@ -34,13 +35,11 @@ public class SqliteService {
@Value("${spring.datasource.druid.master.url}")
private String masterUrl;
@PostConstruct
private void init()
public void init()
{
initDb();
initSysConfig();
initAbsValueCommand();
initGearCommand();
}
/**
... ... @@ -121,20 +120,6 @@ public class SqliteService {
}
}
private void initGearCommand() {
logger.info("检查档位对应的指令表");
Long ct = publicService.selectCountBySql("SELECT count(*) ct FROM sqlite_master WHERE type='table' AND name='gear_command'");
if (0 == ct)
{
logger.info("档位对应的指令不存在自动创建");
publicService.updateBySql("CREATE TABLE \"gear_command\" (\n" +
" \"gear\" integer NOT NULL,\n" +
" \"command\" TEXT NOT NULL,\n" +
" PRIMARY KEY (\"gear\")\n" +
")");
}
}
public List<Map<String,Object>> getAllSysConfig()
{
return publicService.getObjectListBySQL("SELECT * FROM sys_config");
... ... @@ -145,22 +130,15 @@ public class SqliteService {
return absValueCommandMapper.getFishCurveControlConditionList("SELECT * FROM absValue_command");
}
public List<Map<String,Object>> getAllGearCommand()
public List<Map<String,Object>> getAllRegister()
{
return publicService.getObjectListBySQL("SELECT * FROM gear_command");
return publicService.getObjectListBySQL("SELECT * FROM register");
}
public void updateConfigurationParameter(ConfigurationParameter key,Object value)
{
switch (key)
{
case gear_command:
Map<String,String> map = (Map<String, String>) value;
for(String gear:map.keySet())
{
updateGearCommand(Integer.parseInt(gear),map.get(gear));
}
break;
case absValue_command:
List<FishCurveControlCondition> list = (List<FishCurveControlCondition>) value;
for(FishCurveControlCondition fishCurveControlCondition:list)
... ... @@ -180,12 +158,6 @@ public class SqliteService {
publicService.updateBySql("insert into sys_config(`parameter_name`,`parameter_value`,`describe`) values ('"+key.name()+"','"+value+"','"+key.getDescribe()+"')");
}
public void updateGearCommand(Integer gear,String command)
{
publicService.updateBySql("delete from gear_command where gear="+gear+"");
publicService.updateBySql("insert into gear_command(`gear`,`command`) values ("+gear+",'"+command+"')");
}
public void updateabsValueCommand(Integer gear,Integer sartAbsValue)
{
publicService.updateBySql("delete from absValue_command where sartAbsValue="+sartAbsValue+"");
... ... @@ -196,4 +168,6 @@ public class SqliteService {
{
publicService.updateBySql("delete from absValue_command ");
}
}
... ...
package com.zhonglai.luhui.smart.feeder.service;
import com.alibaba.fastjson.JSONObject;
import com.ruoyi.common.utils.ip.IpUtils;
import org.eclipse.paho.client.mqttv3.MqttClient;
import org.eclipse.paho.client.mqttv3.MqttConnectOptions;
import org.eclipse.paho.client.mqttv3.MqttException;
... ... @@ -13,7 +15,9 @@ import org.springframework.stereotype.Service;
import javax.annotation.PostConstruct;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* 终端服务
... ... @@ -36,15 +40,10 @@ public class TerminalService {
@Value("#{'${mqtt.topics}'.split(',')}")
private List<String> topics;
@Value("${mqtt.sub_clientid}")
private String sub_clientid;
@Value("#{'${mqtt.mqtt_usernames}'.split(',')}")
private List<String> mqtt_usernames;
@Value("${mqtt.roleid}")
private String roleid;
@Value("${mqtt.username}")
private String username;
@Value("${mqtt.password}")
... ... @@ -56,10 +55,19 @@ public class TerminalService {
init();
connect();
subscribe();
Map<String,Object> dmap = new HashMap<>();
Map<String,Object> map = new HashMap<>();
dmap.put("summary",map);
map.put("localhostIp",IpUtils.getHostIp());
JSONObject jsonObject = new JSONObject();
jsonObject.put("0",dmap);
String topic = "ADD_POST";
publish(topic,jsonObject.toJSONString());
}
private void init() throws MqttException {
public void init() throws MqttException {
if(null == mqttclient)
{
mqttclient = new MqttClient(broker, clientId, new MemoryPersistence());
... ... @@ -79,34 +87,7 @@ public class TerminalService {
}
public void subscribe() throws MqttException {
List<String> ts = getCompletionTopics();
mqttclient.subscribe(ts.toArray(new String[ts.size()]));
}
public List<String> getCompletionTopics()
{
List<String> ts = new ArrayList<>();
for(String mqtt_username:mqtt_usernames)
{
StringBuffer topic = new StringBuffer();
topic.append("/");
topic.append(roleid);
topic.append("/");
topic.append(mqtt_username);
topic.append("/");
topic.append(sub_clientid);
topic.append("/");
topic.append("+");
for(String tc:topics)
{
StringBuffer t = new StringBuffer(topic);
t.append("/");
t.append(tc);
ts.add(t.toString());
}
}
return ts;
mqttclient.subscribe(topics.toArray(new String[topics.size()]));
}
public void publish(String topic, MqttMessage message) throws MqttException {
... ... @@ -118,4 +99,18 @@ public class TerminalService {
message.setPayload(messageStr.getBytes());
mqttclient.publish(topic,message);
}
public void scheduledSubmissionData(String messageStr) throws MqttException {
String topic = "ALL_POST";
publish(topic,messageStr);
}
public void close()
{
try {
mqttclient.close();
} catch (MqttException e) {
log.error("关闭失败",e);
}
}
}
... ...
package com.zhonglai.luhui.smart.feeder.util;
public enum FeederCommd06ResponseType {
/**
* 运行模式
*/
runmode(13),
/**
*投料量
*/
runspeed(14),
/**
*投料时间
*/
worktime(15),
/**
*间隔时间
*/
interval(16),
/**
* 开/关
*/
OnOroff(17),
/**
*停投料倒计时
*/
stopfeedcnt(18);
private Integer number;
FeederCommd06ResponseType(Integer number) {
this.number = number;
}
public Integer getNumber() {
return number;
}
}
... ...
package com.zhonglai.luhui.smart.feeder.util;
import cn.hutool.core.util.ArrayUtil;
import com.ruoyi.common.utils.ByteUtil;
import com.zhonglai.luhui.smart.feeder.dto.commd.*;
public class FeederCommdUtil {
/**
* 读取所有数据
* @return
*/
public static String readAll()
{
FeederCommdDto feederCommdDto = new FeederCommdDto(new FeederCommd03Response(0,71));
return feederCommdDto.getHstr();
}
/**
* 写运行模式
* @return
*/
public static String controlData(FeederCommd06ResponseType feederCommd06ResponseType,int value)
{
FeederCommdDto feederCommdDto = new FeederCommdDto(new FeederCommd06Response(feederCommd06ResponseType.getNumber(),value));
return feederCommdDto.getHstr();
}
/**
* 写定时器
* @param timerNumber
* @param feederTimer
* @return
*/
public static String controlTimer(Integer timerNumber,FeederTimer feederTimer)
{
int i23 = 0;
if(null != feederTimer.getTimer_close_m())
{
i23 = ByteUtil.assignBits(i23,feederTimer.getTimer_close_m(),0,7);
}
if(null != feederTimer.getTimer_close_h())
{
i23 = ByteUtil.assignBits(i23,feederTimer.getTimer_close_h(),8,13);
}
if(null != feederTimer.getTimer_if_start())
{
i23 = ByteUtil.assignBits(i23,feederTimer.getTimer_if_start(),14,14);
}
if(null != feederTimer.getTimer_is_start())
{
i23 = ByteUtil.assignBits(i23,feederTimer.getTimer_is_start(),15,15);
}
int i24 = 0;
if(null != feederTimer.getTimer_close_m())
{
i24 = ByteUtil.assignBits(i24,feederTimer.getTimer_close_m(),0,7);
}
if(null != feederTimer.getTimer_close_h())
{
i24 = ByteUtil.assignBits(i24,feederTimer.getTimer_close_h(),8,13);
}
if(null != feederTimer.getTimer_if_close())
{
i24 = ByteUtil.assignBits(i24,feederTimer.getTimer_close_h(),14,14);
}
if(null != feederTimer.getTimer_is_close())
{
i24 = ByteUtil.assignBits(i24,feederTimer.getTimer_is_close(),15,15);
}
byte[] data = ArrayUtil.addAll( ByteUtil.intToBytesDESC(i23,2),ByteUtil.intToBytesDESC(i24,2));
FeederCommdDto feederCommdDto = new FeederCommdDto(new FeederCommd10Response(23+timerNumber-1,4,8,data));
return feederCommdDto.getHstr();
}
}
... ...
... ... @@ -58,7 +58,10 @@ public class SerialTool {
// 通过端口名识别端口
CommPortIdentifier portIdentifier = CommPortIdentifier.getPortIdentifier(portName);
if(portIdentifier.isCurrentlyOwned())
{
throw new RuntimeException("串口已被占用");
}
// 打开端口,并给端口名字和一个timeout(打开操作的超时时间)
CommPort commPort = portIdentifier.open(portName, 2000);
... ... @@ -68,7 +71,6 @@ public class SerialTool {
try {
// 设置一下串口的波特率等参数
serialPort.setSerialPortParams(baudrate, dataBits, stopBits, parity);
logger.info("串口" + portName + "打开成功");
} catch (UnsupportedCommOperationException e) {
logger.error("设置串口" + portName + "参数失败:" + e.getMessage());
throw e;
... ... @@ -144,6 +146,15 @@ public class SerialTool {
}
}
public static OutputStream getSerialPortStream( SerialPort serialPort) throws IOException {
return serialPort.getOutputStream();
}
public static void sendToPort(byte[] order, OutputStream out) throws IOException {
out.write(order);
out.flush();
}
/**
* 往串口发送数据
*
... ... @@ -161,6 +172,10 @@ public class SerialTool {
try {
out = serialPort.getOutputStream();
if(null == out)
{
logger.error("窗口未打开" );
}
out.write(order);
out.flush();
logger.info("发送数据成功" + serialPort.getName());
... ... @@ -171,7 +186,6 @@ public class SerialTool {
try {
if (out != null) {
out.close();
out = null;
}
} catch (IOException e) {
logger.error("关闭串口对象的输出流出错");
... ... @@ -240,7 +254,10 @@ public class SerialTool {
public static void addListener(SerialPortEventListener listener, SerialPort serialPort) throws TooManyListenersException {
try {
if(null == serialPort)
{
throw new RuntimeException("端口未初始化");
}
// 给串口添加监听器
serialPort.addEventListener(listener);
// 设置当有数据到达时唤醒监听接收线程
... ...
# 开发环境配置 server: # 服务器的HTTP端口,默认为8080 port: 8064 servlet: # 应用的访问路径 context-path: / tomcat: # tomcat的URI编码 uri-encoding: UTF-8 # 连接数满后的排队数,默认为100 accept-count: 1000 threads: # tomcat最大线程数,默认为200 max: 800 # Tomcat启动初始化的线程数,默认值10 min-spare: 100 # 日志配置 logging: level: com.ruoyi: debug org.springframework: warn # Swagger配置 swagger: # 是否开启swagger enabled: true # 请求前缀 pathMapping: /dev-api # 防止XSS攻击 xss: # 过滤开关 enabled: true # 排除链接(多个用逗号分隔) excludes: /system/notice # 匹配链接 urlPatterns: /system/*,/monitor/*,/tool/* sys: staticPath: "file:E:/work/idea/Luhui/lh-modules/lh-smart-feeder/src/main/resources/static/" cacheFilePath: "E:/work/idea/Luhui/lh-modules/lh-smart-feeder/cache/" # MyBatis配置 mybatis: # 搜索指定包别名 typeAliasesPackage: com.ruoyi.**.domain,com.zhonglai.**.domain # 配置mapper的扫描,找到所有的mapper.xml映射文件 mapperLocations: classpath*:mapper/**/*Mapper.xml # 加载全局的配置文件 configLocation: classpath:mybatis/mybatis-config.xml # 数据源配置 spring: autoconfigure: exclude: org.springframework.boot.autoconfigure.jackson.JacksonAutoConfiguration datasource: type: com.alibaba.druid.pool.DruidDataSource driverClassName: org.sqlite.JDBC druid: # 主库数据源 master: url: jdbc:sqlite:db/my.db username: password: # 从库数据源 slave: # 从数据源开关/默认关闭 enabled: false url: username: password: # 初始连接数 initialSize: 5 # 最小连接池数量 minIdle: 10 # 最大连接池数量 maxActive: 20 # 配置获取连接等待超时的时间 maxWait: 60000 # 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒 timeBetweenEvictionRunsMillis: 60000 # 配置一个连接在池中最小生存的时间,单位是毫秒 minEvictableIdleTimeMillis: 300000 # 配置一个连接在池中最大生存的时间,单位是毫秒 maxEvictableIdleTimeMillis: 900000 # 配置检测连接是否有效 validationQuery: SELECT 1 testWhileIdle: true testOnBorrow: false testOnReturn: false webStatFilter: enabled: true statViewServlet: enabled: true # 设置白名单,不填则允许所有访问 allow: url-pattern: /druid/* # 控制台管理用户名和密码 login-username: ruoyi login-password: 123456 filter: stat: enabled: true # 慢SQL记录 log-slow-sql: true slow-sql-millis: 1000 merge-sql: true wall: config: multi-statement-allow: true ## 数据源配置 #spring: # datasource: # type: com.alibaba.druid.pool.DruidDataSource # driverClassName: com.mysql.cj.jdbc.Driver # druid: # # 主库数据源 # master: # url: jdbc:mysql://rm-wz9740un21f09iokuao.mysql.rds.aliyuncs.com:3306/mqtt_broker?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8 # username: luhui # password: Luhui586 # # 从库数据源 # slave: # # 从数据源开关/默认关闭 # enabled: true # url: jdbc:mysql://119.23.218.181:3306/lh-server-ops?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8 # username: luhui # password: Luhui586 # # 初始连接数 # initialSize: 5 # # 最小连接池数量 # minIdle: 10 # # 最大连接池数量 # maxActive: 20 # # 配置获取连接等待超时的时间 # maxWait: 60000 # # 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒 # timeBetweenEvictionRunsMillis: 60000 # # 配置一个连接在池中最小生存的时间,单位是毫秒 # minEvictableIdleTimeMillis: 300000 # # 配置一个连接在池中最大生存的时间,单位是毫秒 # maxEvictableIdleTimeMillis: 900000 # # 配置检测连接是否有效 # validationQuery: SELECT 1 FROM DUAL # testWhileIdle: true # testOnBorrow: false # testOnReturn: false # webStatFilter: # enabled: true # statViewServlet: # enabled: true # # 设置白名单,不填则允许所有访问 # allow: # url-pattern: /druid/* # # 控制台管理用户名和密码 # login-username: ruoyi # login-password: 123456 # filter: # stat: # enabled: true # # 慢SQL记录 # log-slow-sql: true # slow-sql-millis: 1000 # merge-sql: true # wall: # config: # multi-statement-allow: true mqtt: #链接地址 broker: tcp://175.24.61.68:1883 #唯一标识 clientId: 70094a59d1d991d #公司id roleid: 2 mqtt_usernames: NWDB_2023 #订阅的topic topics: ADD_POST,ALL_POST,DB_TOPIC_DISTRIBUTE,GET/+,online,PUT_REQ/+,READ_REQ/+ sub_clientid: '70094a59d1d991d' topicconfig: "/{{roleid}}/{{username}}/{{clientid}}/{{payloadtype}}/{{topicType}}/{{messageid}}" top_return_map: '{"PUT":"PUT_REQ","READ":"READ_REQ"}' username: sysuser password: "!@#1qaz" client: #客户端操作时间 operationTime: 10
\ No newline at end of file
# 开发环境配置 server: # 服务器的HTTP端口,默认为8080 port: 8064 servlet: # 应用的访问路径 context-path: / tomcat: # tomcat的URI编码 uri-encoding: UTF-8 # 连接数满后的排队数,默认为100 accept-count: 1000 threads: # tomcat最大线程数,默认为200 max: 800 # Tomcat启动初始化的线程数,默认值10 min-spare: 100 # 日志配置 logging: level: com.ruoyi: debug org.springframework: warn # Swagger配置 swagger: # 是否开启swagger enabled: true # 请求前缀 pathMapping: /dev-api # 防止XSS攻击 xss: # 过滤开关 enabled: true # 排除链接(多个用逗号分隔) excludes: /system/notice # 匹配链接 urlPatterns: /system/*,/monitor/*,/tool/* sys: staticPath: "file:/opt/lh-smart-feeder/lh-smart-feeder/html/" cacheFilePath: "E:/opt/lh-smart-feeder/lh-smart-feeder/cache/" # MyBatis配置 mybatis: # 搜索指定包别名 typeAliasesPackage: com.ruoyi.**.domain,com.zhonglai.**.domain # 配置mapper的扫描,找到所有的mapper.xml映射文件 mapperLocations: classpath*:mapper/**/*Mapper.xml # 加载全局的配置文件 configLocation: classpath:mybatis/mybatis-config.xml # 数据源配置 spring: # autoconfigure: # exclude: org.springframework.boot.autoconfigure.jackson.JacksonAutoConfiguration datasource: type: com.alibaba.druid.pool.DruidDataSource driverClassName: org.sqlite.JDBC druid: # 主库数据源 master: url: jdbc:sqlite:db/my.db username: password: # 从库数据源 slave: # 从数据源开关/默认关闭 enabled: false url: username: password: # 初始连接数 initialSize: 5 # 最小连接池数量 minIdle: 10 # 最大连接池数量 maxActive: 20 # 配置获取连接等待超时的时间 maxWait: 60000 # 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒 timeBetweenEvictionRunsMillis: 60000 # 配置一个连接在池中最小生存的时间,单位是毫秒 minEvictableIdleTimeMillis: 300000 # 配置一个连接在池中最大生存的时间,单位是毫秒 maxEvictableIdleTimeMillis: 900000 # 配置检测连接是否有效 validationQuery: SELECT 1 testWhileIdle: true testOnBorrow: false testOnReturn: false webStatFilter: enabled: true statViewServlet: enabled: true # 设置白名单,不填则允许所有访问 allow: url-pattern: /druid/* # 控制台管理用户名和密码 login-username: ruoyi login-password: 123456 filter: stat: enabled: true # 慢SQL记录 log-slow-sql: true slow-sql-millis: 1000 merge-sql: true wall: config: multi-statement-allow: true ## 数据源配置 #spring: # datasource: # type: com.alibaba.druid.pool.DruidDataSource # driverClassName: com.mysql.cj.jdbc.Driver # druid: # # 主库数据源 # master: # url: jdbc:mysql://rm-wz9740un21f09iokuao.mysql.rds.aliyuncs.com:3306/mqtt_broker?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8 # username: luhui # password: Luhui586 # # 从库数据源 # slave: # # 从数据源开关/默认关闭 # enabled: true # url: jdbc:mysql://119.23.218.181:3306/lh-server-ops?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8 # username: luhui # password: Luhui586 # # 初始连接数 # initialSize: 5 # # 最小连接池数量 # minIdle: 10 # # 最大连接池数量 # maxActive: 20 # # 配置获取连接等待超时的时间 # maxWait: 60000 # # 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒 # timeBetweenEvictionRunsMillis: 60000 # # 配置一个连接在池中最小生存的时间,单位是毫秒 # minEvictableIdleTimeMillis: 300000 # # 配置一个连接在池中最大生存的时间,单位是毫秒 # maxEvictableIdleTimeMillis: 900000 # # 配置检测连接是否有效 # validationQuery: SELECT 1 FROM DUAL # testWhileIdle: true # testOnBorrow: false # testOnReturn: false # webStatFilter: # enabled: true # statViewServlet: # enabled: true # # 设置白名单,不填则允许所有访问 # allow: # url-pattern: /druid/* # # 控制台管理用户名和密码 # login-username: ruoyi # login-password: 123456 # filter: # stat: # enabled: true # # 慢SQL记录 # log-slow-sql: true # slow-sql-millis: 1000 # merge-sql: true # wall: # config: # multi-statement-allow: true mqtt: #链接地址 broker: tcp://175.24.61.68:1883 #唯一标识 clientId: 70094a59d1d991d #公司id roleid: 2 mqtt_usernames: 12_ZNZY #订阅的topic topics: PUT/+,GET_REQ/+, READ/+,POST_REQ/+ sub_clientid: '70094a59d1d991d' username: 12_ZNZY password: Luhui586 client: #客户端操作时间 operationTime: 10
\ No newline at end of file
... ...
... ... @@ -20,7 +20,6 @@ import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.enums.BusinessType;
import com.zhonglai.zl.email.forwarding.domain.RelayDomains;
import com.zhonglai.zl.email.forwarding.service.IRelayDomainsService;
import com.zhonglai.luhui.sys.utils.ExcelUtil;
import com.ruoyi.common.core.page.TableDataInfo;
/**
... ... @@ -50,19 +49,6 @@ public class RelayDomainsController extends BaseController
}
/**
* 导出转发地址管理列表
*/
@ApiOperation("导出转发地址管理列表")
@Log(title = "转发地址管理", businessType = BusinessType.EXPORT)
@PostMapping("/export")
public void export(HttpServletResponse response, RelayDomains relayDomains)
{
List<RelayDomains> list = relayDomainsService.selectRelayDomainsList(relayDomains);
ExcelUtil<RelayDomains> util = new ExcelUtil<RelayDomains>(RelayDomains.class);
util.exportExcel(response, list, "转发地址管理数据");
}
/**
* 获取转发地址管理详细信息
*/
@ApiOperation("获取转发地址管理详细信息")
... ...