parent
0022e22f93
commit
7f43b90147
14 changed files with 428 additions and 9 deletions
@ -0,0 +1,18 @@ |
|||||||
|
<?xml version="1.0" encoding="UTF-8"?> |
||||||
|
<project xmlns="http://maven.apache.org/POM/4.0.0" |
||||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" |
||||||
|
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> |
||||||
|
<parent> |
||||||
|
<artifactId>lab-service-api</artifactId> |
||||||
|
<groupId>org.springblade</groupId> |
||||||
|
<version>2.8.1.RELEASE</version> |
||||||
|
</parent> |
||||||
|
<modelVersion>4.0.0</modelVersion> |
||||||
|
|
||||||
|
<artifactId>lab-iot-api</artifactId> |
||||||
|
<name>${project.artifactId}</name> |
||||||
|
<version>${bladex.project.version}</version> |
||||||
|
<packaging>jar</packaging> |
||||||
|
|
||||||
|
|
||||||
|
</project> |
||||||
@ -0,0 +1,63 @@ |
|||||||
|
/* |
||||||
|
* Copyright (c) 2018-2028, Chill Zhuang All rights reserved. |
||||||
|
* |
||||||
|
* Redistribution and use in source and binary forms, with or without |
||||||
|
* modification, are permitted provided that the following conditions are met: |
||||||
|
* |
||||||
|
* Redistributions of source code must retain the above copyright notice, |
||||||
|
* this list of conditions and the following disclaimer. |
||||||
|
* Redistributions in binary form must reproduce the above copyright |
||||||
|
* notice, this list of conditions and the following disclaimer in the |
||||||
|
* documentation and/or other materials provided with the distribution. |
||||||
|
* Neither the name of the dreamlu.net developer nor the names of its |
||||||
|
* contributors may be used to endorse or promote products derived from |
||||||
|
* this software without specific prior written permission. |
||||||
|
* Author: Chill 庄骞 (smallchill@163.com) |
||||||
|
*/ |
||||||
|
package org.springblade.iot.entry; |
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.annotation.TableField; |
||||||
|
import com.baomidou.mybatisplus.annotation.TableName; |
||||||
|
import com.fasterxml.jackson.annotation.JsonFormat; |
||||||
|
import io.swagger.annotations.ApiModel; |
||||||
|
import io.swagger.annotations.ApiModelProperty; |
||||||
|
import lombok.Data; |
||||||
|
import lombok.EqualsAndHashCode; |
||||||
|
import org.springblade.core.mp.base.BaseEntity; |
||||||
|
import org.springframework.format.annotation.DateTimeFormat; |
||||||
|
|
||||||
|
import java.time.LocalDateTime; |
||||||
|
|
||||||
|
/** |
||||||
|
* 数采配置实体类 |
||||||
|
* |
||||||
|
* @author swj |
||||||
|
* @since 2022年8月17日16:29:15 |
||||||
|
*/ |
||||||
|
@Data |
||||||
|
@TableName("t_sensor_base") |
||||||
|
@EqualsAndHashCode(callSuper = true) |
||||||
|
@ApiModel(value = "Sensor对象", description = "数采配置") |
||||||
|
public class Sensor extends BaseEntity { |
||||||
|
|
||||||
|
@ApiModelProperty(value = "传感器名称") |
||||||
|
private String name; |
||||||
|
|
||||||
|
@ApiModelProperty(value = "plc设备的ip") |
||||||
|
private String ip; |
||||||
|
|
||||||
|
@ApiModelProperty(value = "信息名称(如:302更衣室压差)") |
||||||
|
private String signalName; |
||||||
|
|
||||||
|
@ApiModelProperty(value = "数据类型(REAL->float)") |
||||||
|
private String dataType; |
||||||
|
|
||||||
|
@ApiModelProperty(value = "寄存器地址") |
||||||
|
private String registerAddress; |
||||||
|
|
||||||
|
@TableField(exist = false) |
||||||
|
@ApiModelProperty(value = "单前的实时数据") |
||||||
|
private String currData; |
||||||
|
|
||||||
|
private static final long serialVersionUID = 1L; |
||||||
|
} |
||||||
@ -0,0 +1,23 @@ |
|||||||
|
|
||||||
|
package org.springblade.iot; |
||||||
|
|
||||||
|
import org.springblade.common.constant.LauncherConstant; |
||||||
|
import org.springblade.core.cloud.feign.EnableBladeFeign; |
||||||
|
import org.springblade.core.launch.BladeApplication; |
||||||
|
import org.springframework.cloud.client.SpringCloudApplication; |
||||||
|
|
||||||
|
/** |
||||||
|
* Iot启动器 |
||||||
|
* @author swj |
||||||
|
* @date 2022年8月17日15:21:251 |
||||||
|
*/ |
||||||
|
@EnableBladeFeign |
||||||
|
@SpringCloudApplication |
||||||
|
public class IotApplication { |
||||||
|
|
||||||
|
public static void main(String[] args) { |
||||||
|
BladeApplication.run(LauncherConstant.APPLICATION_IOT_NAME, IotApplication.class, args); |
||||||
|
} |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
@ -0,0 +1,88 @@ |
|||||||
|
|
||||||
|
package org.springblade.iot.controller; |
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; |
||||||
|
import com.baomidou.mybatisplus.core.metadata.IPage; |
||||||
|
import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport; |
||||||
|
import io.swagger.annotations.Api; |
||||||
|
import io.swagger.annotations.ApiOperation; |
||||||
|
import io.swagger.annotations.ApiParam; |
||||||
|
import lombok.AllArgsConstructor; |
||||||
|
import org.springblade.core.boot.ctrl.BladeController; |
||||||
|
import org.springblade.core.mp.support.Condition; |
||||||
|
import org.springblade.core.mp.support.Query; |
||||||
|
import org.springblade.core.secure.utils.AuthUtil; |
||||||
|
import org.springblade.core.tool.api.R; |
||||||
|
import org.springblade.core.tool.utils.Func; |
||||||
|
import org.springblade.iot.entry.Sensor; |
||||||
|
import org.springblade.iot.service.ISensorService; |
||||||
|
import org.springframework.web.bind.annotation.*; |
||||||
|
|
||||||
|
import java.util.Date; |
||||||
|
|
||||||
|
/** |
||||||
|
* 物品申领表 控制器 |
||||||
|
* |
||||||
|
* @author swj |
||||||
|
* @since 2022年8月17日16:35:34 |
||||||
|
*/ |
||||||
|
@RestController |
||||||
|
@AllArgsConstructor |
||||||
|
@RequestMapping("/sensor") |
||||||
|
@Api(value = "", tags = "") |
||||||
|
public class SensorController extends BladeController { |
||||||
|
|
||||||
|
private final ISensorService service; |
||||||
|
|
||||||
|
/** |
||||||
|
* 分页 |
||||||
|
*/ |
||||||
|
@GetMapping("/list") |
||||||
|
@ApiOperationSupport(order = 2) |
||||||
|
public R<Object> list(Sensor entry, Query query) { |
||||||
|
LambdaQueryWrapper<Sensor> wrapper = new LambdaQueryWrapper<>(); |
||||||
|
wrapper.orderByDesc(Sensor::getCreateTime); |
||||||
|
IPage<Sensor> page = service.page(Condition.getPage(query), wrapper); |
||||||
|
return R.data(page); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 更改 |
||||||
|
*/ |
||||||
|
@PostMapping("/update") |
||||||
|
@ApiOperation(value = "更改", notes = "更改") |
||||||
|
public R update(@RequestBody Sensor entry) { |
||||||
|
return R.data(service.updateById(entry)); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 新增 |
||||||
|
*/ |
||||||
|
@PostMapping("/insert") |
||||||
|
@ApiOperation(value = "新增", notes = "新增") |
||||||
|
public R insert(@RequestBody Sensor entry) { |
||||||
|
entry.setCreateTime(new Date()); |
||||||
|
entry.setUpdateTime(new Date()); |
||||||
|
entry.setCreateUser(AuthUtil.getUserId()); |
||||||
|
entry.setUpdateUser(AuthUtil.getUserId()); |
||||||
|
return R.data(service.save(entry)); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 删除 |
||||||
|
*/ |
||||||
|
@PostMapping("/deleteByIds") |
||||||
|
@ApiOperation(value = "逻辑删除", notes = "传入ids") |
||||||
|
public R deleteByIds(@ApiParam(value = "主键集合", required = true) @RequestParam String ids) { |
||||||
|
return R.status(service.deleteLogic(Func.toLongList(ids))); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 根据id获取对应的Sensor |
||||||
|
*/ |
||||||
|
@GetMapping("/getSensor") |
||||||
|
public Sensor getReagent(String id) { |
||||||
|
Sensor sensor = service.getById(id); |
||||||
|
return sensor; |
||||||
|
} |
||||||
|
} |
||||||
@ -0,0 +1,15 @@ |
|||||||
|
|
||||||
|
package org.springblade.iot.mapper; |
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.core.mapper.BaseMapper; |
||||||
|
import org.springblade.iot.entry.Sensor; |
||||||
|
|
||||||
|
/** |
||||||
|
* |
||||||
|
* |
||||||
|
* @author swj |
||||||
|
* @since 2022年8月17日16:37:29 |
||||||
|
*/ |
||||||
|
public interface SensorMapper extends BaseMapper<Sensor> { |
||||||
|
|
||||||
|
} |
||||||
@ -0,0 +1,13 @@ |
|||||||
|
|
||||||
|
package org.springblade.iot.service; |
||||||
|
|
||||||
|
|
||||||
|
import org.springblade.core.mp.base.BaseService; |
||||||
|
import org.springblade.iot.entry.Sensor; |
||||||
|
|
||||||
|
/** |
||||||
|
* @author swj |
||||||
|
* @since 2022年8月17日16:39:35 |
||||||
|
*/ |
||||||
|
public interface ISensorService extends BaseService<Sensor> { |
||||||
|
} |
||||||
@ -0,0 +1,22 @@ |
|||||||
|
|
||||||
|
package org.springblade.iot.service.impl; |
||||||
|
|
||||||
|
|
||||||
|
import lombok.AllArgsConstructor; |
||||||
|
import org.springblade.core.mp.base.BaseServiceImpl; |
||||||
|
import org.springblade.iot.entry.Sensor; |
||||||
|
import org.springblade.iot.mapper.SensorMapper; |
||||||
|
import org.springblade.iot.service.ISensorService; |
||||||
|
import org.springframework.stereotype.Service; |
||||||
|
|
||||||
|
|
||||||
|
/** |
||||||
|
* @author swj |
||||||
|
* @since 2022年8月17日16:39:58 |
||||||
|
*/ |
||||||
|
@Service |
||||||
|
@AllArgsConstructor |
||||||
|
public class SensorServiceImpl extends BaseServiceImpl<SensorMapper, Sensor> implements ISensorService { |
||||||
|
|
||||||
|
private final SensorMapper sensorMapper; |
||||||
|
} |
||||||
@ -0,0 +1,120 @@ |
|||||||
|
package org.springblade.iot.utils; |
||||||
|
|
||||||
|
import com.serotonin.modbus4j.ModbusFactory; |
||||||
|
import com.serotonin.modbus4j.ModbusMaster; |
||||||
|
import com.serotonin.modbus4j.exception.ModbusInitException; |
||||||
|
import com.serotonin.modbus4j.exception.ModbusTransportException; |
||||||
|
import com.serotonin.modbus4j.ip.IpParameters; |
||||||
|
import com.serotonin.modbus4j.msg.ReadHoldingRegistersRequest; |
||||||
|
import com.serotonin.modbus4j.msg.ReadHoldingRegistersResponse; |
||||||
|
|
||||||
|
import java.util.ArrayList; |
||||||
|
import java.util.List; |
||||||
|
|
||||||
|
/** |
||||||
|
* @author swj |
||||||
|
*/ |
||||||
|
public class ReadModBusUtil { |
||||||
|
|
||||||
|
static ModbusFactory modbusFactory; |
||||||
|
|
||||||
|
static { |
||||||
|
if (modbusFactory == null) { |
||||||
|
modbusFactory = new ModbusFactory(); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
public static void main(String[] args) throws InterruptedException { |
||||||
|
// 1.获取tcp协议的主机(上位机)
|
||||||
|
ModbusMaster master = getTcpMaster("192.168.1.217", 502, 1); |
||||||
|
// 2.初始化
|
||||||
|
try { |
||||||
|
master.init(); |
||||||
|
while (0 == 0) { |
||||||
|
// 3.读取保持寄存器数据
|
||||||
|
readHoldingRegistersTest(master, 1, 0, 10); |
||||||
|
Thread.sleep(1000L); |
||||||
|
} |
||||||
|
} catch (ModbusInitException e) { |
||||||
|
e.printStackTrace(); |
||||||
|
} finally { |
||||||
|
// 销毁连接
|
||||||
|
master.destroy(); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 2 |
||||||
|
*/ |
||||||
|
public static ModbusMaster getTcpMaster(String ip, int port, int salveId) { |
||||||
|
IpParameters params = new IpParameters(); |
||||||
|
params.setHost(ip); |
||||||
|
if (port == 0) { |
||||||
|
params.setPort(502); |
||||||
|
} else { |
||||||
|
params.setPort(port); |
||||||
|
} |
||||||
|
ModbusMaster tcpMaster = modbusFactory.createTcpMaster(params, true); |
||||||
|
return tcpMaster; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 3.读取保持寄存器上的内容 |
||||||
|
* |
||||||
|
* @param master 主站 |
||||||
|
* @param slaveId 从站地址 |
||||||
|
* @param start 起始地址的偏移量 |
||||||
|
* @param len 待读寄存器的个数 |
||||||
|
*/ |
||||||
|
private static void readHoldingRegistersTest(ModbusMaster master, int slaveId, int start, int len) { |
||||||
|
try { |
||||||
|
ReadHoldingRegistersRequest request = new ReadHoldingRegistersRequest(slaveId, start, len); |
||||||
|
ReadHoldingRegistersResponse response = (ReadHoldingRegistersResponse) master.send(request); |
||||||
|
if (response.isException()) { |
||||||
|
System.out.println("Exception response: message=" + response.getExceptionMessage()); |
||||||
|
} else { |
||||||
|
byte[] data = response.getData(); |
||||||
|
List<Float> floats = byteArrayToFloatList(data); |
||||||
|
System.out.println("floats:" + floats); |
||||||
|
} |
||||||
|
} catch (ModbusTransportException e) { |
||||||
|
e.printStackTrace(); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 4.将byte类型的arr转换成float |
||||||
|
*/ |
||||||
|
public static List<Float> byteArrayToFloatList(byte[] bytes){ |
||||||
|
// index:0 1 2 3
|
||||||
|
// byte:1-2 3-4 5-6 7-8
|
||||||
|
// byte:2-1 4-3 6-5 8-7
|
||||||
|
// 高低位转换操作:同一
|
||||||
|
for (int i = 0; i < bytes.length; i++) { |
||||||
|
if (i + 1 < bytes.length && i % 2 == 0) { |
||||||
|
byte temp = bytes[i]; |
||||||
|
bytes[i] = bytes[i + 1]; |
||||||
|
bytes[i + 1] = temp; |
||||||
|
} |
||||||
|
} |
||||||
|
List<Float> d = new ArrayList<>(bytes.length / 8); |
||||||
|
byte[] doubleBuffer = new byte[4]; |
||||||
|
for(int j = 0; j < bytes.length; j += 4) { |
||||||
|
System.arraycopy(bytes, j, doubleBuffer, 0, doubleBuffer.length); |
||||||
|
d.add(bytes2Float(doubleBuffer)); |
||||||
|
} |
||||||
|
return d; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 5.将byte数组数据转换成float |
||||||
|
*/ |
||||||
|
public static float bytes2Float(byte[] arr) { |
||||||
|
int accum = 0; |
||||||
|
accum = accum|(arr[0] & 0xff) << 0; |
||||||
|
accum = accum|(arr[1] & 0xff) << 8; |
||||||
|
accum = accum|(arr[2] & 0xff) << 16; |
||||||
|
accum = accum|(arr[3] & 0xff) << 24; |
||||||
|
return Float.intBitsToFloat(accum); |
||||||
|
} |
||||||
|
} |
||||||
Loading…
Reference in new issue