sige 1 year ago
parent
commit
02026f0fd1
  1. 12
      src/src/main/java/com/my/graphiteDigesterBg/diframe/actuator/DiActHeater.java
  2. 187
      src/src/main/java/com/my/graphiteDigesterBg/diframe/actuator/impl/DiActHeaterTokyGteModbusRtuOverTcp.java

12
src/src/main/java/com/my/graphiteDigesterBg/diframe/actuator/DiActHeater.java

@ -0,0 +1,12 @@
package com.my.graphiteDigesterBg.diframe.actuator;
public interface DiActHeater {
// set temperature
void setTemperature( Integer temperature );
// get temperature
Integer getTemperature();
void start();
void stop();
}

187
src/src/main/java/com/my/graphiteDigesterBg/diframe/actuator/impl/DiActHeaterTokyGteModbusRtuOverTcp.java

@ -0,0 +1,187 @@
package com.my.graphiteDigesterBg.diframe.actuator.impl;
import com.my.graphiteDigesterBg.diframe.DiActuatorBase;
import com.my.graphiteDigesterBg.diframe.actuator.DiActHeater;
import java.io.*;
import java.net.Socket;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.util.ArrayList;
import java.util.List;
public class DiActHeaterTokyGteModbusRtuOverTcp extends DiActuatorBase implements DiActHeater {
// host
private String host;
// port
private Integer port;
// slave id
private Integer slaveId;
// heater key
private String ioKey;
// connection
private Socket connection;
// writer
private DataOutputStream writer;
// reader
private InputStream reader;
@Override
public void setEnable( Boolean enable ) {
if ( enable ) {
this.onEnable();
} else {
this.onDisable();
}
}
@Override
protected void onEnable() {
if ( null != this.connection ) {
return ;
}
try {
this.connection = new Socket(this.host, this.port);
} catch (IOException e) {
throw new RuntimeException(e);
}
try {
this.writer = new DataOutputStream(this.connection.getOutputStream());
} catch (IOException e) {
throw new RuntimeException(e);
}
try {
this.reader = this.connection.getInputStream();
} catch (IOException e) {
throw new RuntimeException(e);
}
LOG.info("[Actuator {}({})] {} enable -- OK", this.key, this.type, this.name);
}
@Override
protected void onDisable() {
if ( null == this.connection ) {
return ;
}
try {
this.connection.close();
this.connection = null;
} catch (IOException e) {
throw new RuntimeException(e);
}
try {
this.writer.close();
} catch (IOException e) {
throw new RuntimeException(e);
}
LOG.info("[Actuator {}({})] {} disable -- OK", this.key, this.type, this.name);
}
@Override
public void start() {
this.device.getIO().setValue(this.ioKey, 1);
LOG.info("[Actuator {}({})] {} heating : start", this.key, this.type, this.name);
}
@Override
public void stop() {
this.device.getIO().setValue(this.ioKey, 0);
LOG.info("[Actuator {}({})] {} heating : stop", this.key, this.type, this.name);
this.setTemperature(10);
}
@Override
public void setTemperature(Integer temperature) {
byte[] cmd = new byte[8];
cmd[0] = (byte)(this.slaveId & 0xFF); // slave id
cmd[1] = 0x06; // function code
cmd[2] = 0x20; // address high
cmd[3] = 0x00; // address low
cmd[4] = (byte)(temperature >> 8); // value high
cmd[5] = (byte)(temperature & 0xFF); // value low
this.writeCmd(cmd);
this.readCmdResponse();
LOG.info("[Actuator {}({})] {} set temperature : {}", this.key, this.type, this.name, temperature);
}
// get temperature
public Integer getTemperature() {
byte[] cmd = new byte[8];
cmd[0] = (byte)(this.slaveId & 0xFF); // slave id
cmd[1] = 0x03; // function code
cmd[2] = 0x20; // address high
cmd[3] = 0x10; // address low
cmd[4] = 0x00; // length high
cmd[5] = 0x01; // length low
this.writeCmd(cmd);
var response = this.readCmdResponse();
Integer temperature = response.get(3) << 8 | response.get(4);
LOG.info("[Actuator {}({})] {} get temperature : {}", this.key, this.type, this.name, temperature);
return temperature;
}
/**
* 计算输入数据的CRC16 (Modbus)
* @param data 要计算CRC的字节数组
* @param length 数组中需要计算的长度
* @return 计算出的CRC16值
*/
public int calculateCRC(byte[] data, int length) {
int crc = 0xFFFF; // CRC的初始值
for (int pos = 0; pos < length; pos++) {
crc ^= data[pos] & 0xFF; // 将数据与CRC寄存器异或
for (int i = 8; i != 0; i--) { // 循环处理每个位
if ((crc & 0x0001) != 0) {
crc >>= 1;
crc ^= 0xA001; // 0xA001是预设的多项式
} else {
crc >>= 1;
}
}
}
// 高低位不交换直接返回
return crc & 0xFFFF;
}
// write command
private void writeCmd( byte[] cmd ) {
if ( null == this.connection ) {
throw new RuntimeException("加热器"+this.key+"未启用");
}
var size = cmd.length;
var crc = this.calculateCRC(cmd, size - 2);
cmd[size-2] = (byte)(crc & 0xFF);
cmd[size-1] = (byte)(crc >> 8);
try {
this.writer.write(cmd);
this.writer.flush();
} catch (IOException e) {
throw new RuntimeException(e);
}
}
// read command response
private List<Integer> readCmdResponse () {
if ( null == this.connection ) {
throw new RuntimeException("加热器"+this.key+"未启用");
}
try {
List<Integer> result = new ArrayList<>();
while ( 0 < this.reader.available() ) {
result.add(this.reader.read());
}
return result;
} catch (IOException e) {
throw new RuntimeException(e);
}
}
}
Loading…
Cancel
Save