package ng.devices;
|
|
import java.sql.CallableStatement;
|
import java.sql.Connection;
|
import java.sql.SQLException;
|
import java.util.List;
|
|
import builder.S7control;
|
import com.github.xingshuangs.iot.protocol.s7.enums.EPlcType;
|
import ng.db.DBHelper;
|
import ng.db.DBSession;
|
import ng.db.DBSession.StdCallResult;
|
|
|
public abstract class ModbusService implements Runnable {
|
|
|
//modbus客户端
|
protected ModbusClient client;
|
//自动读数据地址(字节为单位,目前是0)
|
protected int readOffset;
|
//自动读取数据长度(字节为单位,可超长,目前用50,最大250)
|
protected int readSize;
|
//设备ID
|
protected int machineID;
|
//连接类型
|
protected byte functionType;
|
//线程运行状态
|
protected boolean running;
|
|
//设备IP
|
protected String ip;
|
//设备端口
|
protected int port;
|
protected String remarks;
|
//线程
|
java.lang.Thread thread;
|
//缓冲区(服务允许发送超过协议要求的数据,所以缓冲区更大)
|
byte[] buff=new byte[10000];
|
|
|
|
public String LastReturn;
|
|
//关闭线程
|
public void close(){
|
this.running=false;
|
}
|
|
//运行
|
public void Run(int MachineID,String ip,int port,byte state,int ReadOffset,int ReadSize,int timeout,byte FunctionType,String remarks){
|
//设置参数
|
this.machineID=MachineID;
|
this.ip=ip;
|
this.port=port;
|
this.readOffset=ReadOffset;
|
this.readSize=ReadSize;
|
this.functionType= FunctionType;
|
this.remarks= remarks;
|
|
//启动线程
|
if(this.port==102){
|
thread=new java.lang.Thread(this);
|
thread.start();
|
}else{
|
this.client=new ModbusClient();
|
this.client.setConnectionParam(MachineID,ip,port,(byte)state,timeout);
|
thread=new java.lang.Thread(this);
|
thread.start();
|
}
|
|
|
}
|
|
//一次读取行为
|
String once(){
|
//按照配置读数据
|
String msg= client.read(this.readOffset,this.readSize,buff,0,this.functionType);
|
this.LastReturn=msg;
|
if(msg=="ok"){
|
try {
|
//请求打包
|
ModbusDataPackage pack=new ModbusDataPackage();
|
pack.ByteSize=this.readSize;
|
pack.Address=this.readOffset;
|
pack.Content=buff;
|
ModbusDataPackage rsp=new ModbusDataPackage();
|
//调用服务
|
if(this.Service(pack,rsp)){
|
//服务要求会数据,则会
|
if(rsp.Content!=null){
|
return client.write(rsp.Address,rsp.ByteSize,rsp.Content,0);
|
}
|
}
|
} catch (Exception e) {
|
// TODO Auto-generated catch block
|
e.printStackTrace();
|
}
|
finally{
|
}
|
|
|
}
|
return msg;
|
}
|
//一次s7读取行为
|
String onceS7(){
|
try {
|
DBSession sn=null;
|
String result=null;
|
String flag=null;
|
String messsage="000000000000000000";
|
EPlcType ePlcType=null;
|
if(this.functionType==10){
|
ePlcType=EPlcType.S200_SMART;
|
}else if(this.functionType==11){
|
ePlcType=EPlcType.S1500;
|
}else if(this.functionType==12){
|
ePlcType=EPlcType.S1200;
|
}else{
|
return "";
|
}
|
S7control s7=new S7control(ePlcType, ip, port, 0, 0);
|
List<Integer> listWord=s7.readWord(this.remarks,(this.readSize/2));
|
if(listWord==null){
|
System.out.println("notread");
|
return "";
|
}
|
for(int i=0;i<listWord.size();i++){
|
messsage+=HexUtil.intTo2ByteHex(listWord.get(i));
|
}
|
//数据库
|
DBHelper db=DBHelper.getDBHelper("mes");
|
try{
|
//创建连接
|
sn=db.createSession(false);
|
Connection con= sn.getConnection();
|
//调用那个存储过程
|
CallableStatement sql=con.prepareCall("{call Total_method(?,?,?,?)}");
|
sql.registerOutParameter(3, java.sql.Types.VARCHAR);
|
sql.registerOutParameter(4, java.sql.Types.VARCHAR);
|
sql.setString(1, messsage);
|
sql.setLong(2, machineID);
|
sql.execute();
|
//读取返回参数
|
result= sql.getString(3);
|
flag= sql.getString(4);
|
if (result!=null&&result.length()>0){
|
String []results=result.split(",");
|
//得到存储过程返回的值,数组第一个为地址,第二个为值
|
int resultsLength=results.length;
|
int resultsSize=resultsLength/2;
|
for(int i=1;i<resultsSize+1;i++){
|
int addressIndex=(i-1)*2;
|
int valueIndex=i*2-1;
|
s7.writeWord(results[addressIndex],Integer.valueOf(results[valueIndex]));//参数组写入
|
}
|
}
|
}
|
catch(Exception e){
|
e.printStackTrace();
|
}
|
finally{
|
sn.close();
|
|
}
|
|
} catch (Exception e) {
|
// TODO Auto-generated catch block
|
e.printStackTrace();
|
}
|
finally{
|
|
}
|
|
return "";
|
}
|
|
public void SendPLC(int Address, int count, byte[] buffer, int offset) {
|
this.client.write(Address, count, buffer, offset);
|
}
|
public boolean isRunning(){
|
return this.running;
|
}
|
|
public boolean isOnLine(){
|
ModbusClient c=this.client;
|
if(this.client!=null)
|
return this.client.IsEnable();
|
return false;
|
}
|
|
protected int UpadateInterval=200;
|
|
//线程运行函数
|
void proc(){
|
running=true;
|
while(running){
|
if(this.port==102||client.IsEnable()){
|
try {
|
java.lang.Thread.sleep(UpadateInterval);
|
if(this.port==102){
|
String back=onceS7();
|
}else{
|
String back=once();
|
}
|
|
} catch (InterruptedException e) {
|
// TODO Auto-generated catch block
|
}
|
}
|
else{
|
client.connect();
|
if(client.IsEnable()==false){
|
try {
|
java.lang.Thread.sleep(4000);
|
} catch (InterruptedException e) {
|
// TODO Auto-generated catch block
|
}
|
}
|
// else{
|
// System.out.print("IO链接成功");
|
// }
|
}
|
}
|
this.running=false;
|
client.close();
|
|
}
|
|
//线程入口
|
@Override
|
public void run() {
|
// TODO Auto-generated method stub
|
|
proc();
|
}
|
public class ModbusDataPackage{
|
public int Address;
|
public int ByteSize;
|
public byte[] Content;
|
}
|
protected abstract boolean Service(ModbusDataPackage request,ModbusDataPackage response);
|
|
|
}
|