package service
|
|
import (
|
"apsClient/conf"
|
"apsClient/constvar"
|
"apsClient/model"
|
"apsClient/pkg/logx"
|
"apsClient/pkg/plc"
|
"apsClient/pkg/plc/modbusx"
|
"apsClient/pkg/plccom"
|
"encoding/binary"
|
"errors"
|
"fmt"
|
"github.com/spf13/cast"
|
)
|
|
func PlcRead(plcConfig *model.DevicePlc, fieldType constvar.PlcStartAddressType, position int) (val interface{}, err error) {
|
var (
|
startAddress int
|
valueType constvar.PlcStartAddressValueType
|
dataLength int
|
ipAddr string
|
)
|
|
for _, pc := range plcConfig.Details {
|
if pc.FieldName == fieldType && pc.Position == position {
|
startAddress = pc.StartAddress
|
valueType = pc.Type
|
dataLength = pc.Length
|
}
|
}
|
|
if plcConfig.Method == constvar.PlcMethodModbusTCP {
|
ipAddr = fmt.Sprintf("%s:%v", plcConfig.Address, plcConfig.Port)
|
|
conn, err := plc.GetModbusConnection(ipAddr)
|
if err != nil {
|
logx.Errorf("PlcRead 连接plc失败: %v", err.Error())
|
return nil, err
|
}
|
|
rawData, err := plc.ReadHoldingRegister(conn, startAddress, dataLength)
|
if err != nil {
|
logx.Errorf("PlcRead 获取plc数据失败: %v", err.Error())
|
return nil, err
|
}
|
switch valueType {
|
case constvar.PlcStartAddressValueTypeString:
|
return string(rawData), nil
|
case constvar.PlcStartAddressValueTypeInt:
|
if len(rawData) == 2 {
|
return int(binary.BigEndian.Uint16(rawData)), nil
|
} else {
|
logx.Errorf("plc read get an unknown int value: %v, address:%v", rawData, startAddress)
|
return nil, errors.New(fmt.Sprintf("unknown int value:%v", rawData))
|
}
|
}
|
return nil, errors.New("undefined value type")
|
} else if plcConfig.Method == constvar.PlcMethodSerial {
|
ipAddr = conf.Conf.Services.Serial
|
if ipAddr == "" {
|
return nil, errors.New("conf.Conf.Services.Serial config not set yet")
|
}
|
label := fmt.Sprintf("D%d", startAddress)
|
return plccom.ReadPLC(plccom.DeviceTypeMitsubishi, ipAddr, label)
|
}
|
return nil, errors.New("interface type not support")
|
}
|
|
func PlcWrite(plcConfig *model.DevicePlc, fieldType constvar.PlcStartAddressType, position int, value interface{}) (err error) {
|
var (
|
startAddress int
|
ipAddr string
|
)
|
|
if plcConfig.CurrentTryTimes > plcConfig.MaxTryTimes {
|
return plcConfig.CurrentErr
|
}
|
plcConfig.CurrentTryTimes++
|
|
for _, pc := range plcConfig.Details {
|
if pc.FieldName == fieldType && pc.Position == position {
|
startAddress = pc.StartAddress
|
}
|
}
|
|
if plcConfig.Method == constvar.PlcMethodModbusTCP {
|
ipAddr = fmt.Sprintf("%s:%v", plcConfig.Address, plcConfig.Port)
|
//conn, err := plc.GetModbusConnection(ipAddr)
|
//if err != nil {
|
// logx.Errorf("plc write failed, 连接plc失败: %v", err.Error())
|
// plcConfig.CurrentErr = err
|
// return PlcWrite(plcConfig, fieldType, position, value)
|
//}
|
//
|
//result, err := plc.WriteHoldingRegister(conn, startAddress, value)
|
err = modbusx.Write(ipAddr, uint16(startAddress), value)
|
if err != nil {
|
logx.Errorf("plc write failed, address: %v, value: %v, err: %v", startAddress, value, err.Error())
|
plcConfig.CurrentErr = err
|
return PlcWrite(plcConfig, fieldType, position, value)
|
}
|
logx.Infof("plc write ok, address: %v, value: %v", startAddress, value)
|
} else if plcConfig.Method == constvar.PlcMethodSerial {
|
ipAddr = conf.Conf.Services.Serial
|
if ipAddr == "" {
|
return errors.New("conf.Conf.Services.Serial config not set yet")
|
}
|
label := fmt.Sprintf("D%d", startAddress)
|
return plccom.WritePLC(plccom.DeviceTypeMitsubishi, ipAddr, label, cast.ToInt(value))
|
}
|
return
|
}
|
|
func PlcWriteDirect(plcConfig *model.DevicePlc, address int, value interface{}) (err error) {
|
var (
|
ipAddr string
|
)
|
|
if plcConfig.CurrentTryTimes > plcConfig.MaxTryTimes {
|
logx.Errorf("plc write try time beyond max try times, err: %v", plcConfig.CurrentErr)
|
return plcConfig.CurrentErr
|
}
|
plcConfig.CurrentTryTimes++
|
if plcConfig.Method == constvar.PlcMethodModbusTCP {
|
ipAddr = fmt.Sprintf("%s:%v", plcConfig.Address, plcConfig.Port)
|
//conn, err := plc.GetModbusConnection(ipAddr)
|
//if err != nil {
|
// logx.Errorf("plc write failed, 连接plc失败: %v", err.Error())
|
// plcConfig.CurrentErr = err
|
// return PlcWriteDirect(plcConfig, address, value)
|
//}
|
//result, err := plc.WriteHoldingRegister(conn, address, value)
|
|
err = modbusx.Write(ipAddr, uint16(address), value)
|
if err != nil {
|
logx.Errorf("plc write failed, address: %v, value: %v, err: %v", address, value, err.Error())
|
plcConfig.CurrentErr = err
|
return PlcWriteDirect(plcConfig, address, value)
|
}
|
logx.Infof("plc write ok, address: %v, value: %v", address, value)
|
} else if plcConfig.Method == constvar.PlcMethodSerial {
|
ipAddr = conf.Conf.Services.Serial
|
if ipAddr == "" {
|
return errors.New("conf.Conf.Services.Serial config not set yet")
|
}
|
label := fmt.Sprintf("D%d", address)
|
return plccom.WritePLC(plccom.DeviceTypeMitsubishi, ipAddr, label, cast.ToInt(value))
|
}
|
return
|
}
|
|
func PlcReadDirect(plcConfig *model.DevicePlc, address int, dataLength int, valueType constvar.PlcStartAddressValueType) (val interface{}, err error) {
|
var (
|
ipAddr string
|
)
|
|
if plcConfig.CurrentTryTimes > plcConfig.MaxTryTimes {
|
logx.Errorf("plc read try time beyond max try times, err: %v", plcConfig.CurrentErr)
|
return nil, plcConfig.CurrentErr
|
}
|
plcConfig.CurrentTryTimes++
|
if plcConfig.Method == constvar.PlcMethodModbusTCP {
|
ipAddr = fmt.Sprintf("%s:%v", plcConfig.Address, plcConfig.Port)
|
//conn, err := plc.GetModbusConnection(ipAddr)
|
//if err != nil {
|
// plcConfig.CurrentErr = err
|
// return PlcReadDirect(plcConfig, address, dataLength, valueType)
|
//}
|
//value, err := plc.ReadHoldingRegister(conn, address, dataLength)
|
value, err := modbusx.Read(ipAddr, uint16(address), uint16(dataLength))
|
if err != nil {
|
plcConfig.CurrentErr = err
|
return PlcReadDirect(plcConfig, address, dataLength, valueType)
|
}
|
switch valueType {
|
case constvar.PlcStartAddressValueTypeString:
|
return string(value), nil
|
case constvar.PlcStartAddressValueTypeInt:
|
if len(value) == 2 {
|
return int(binary.BigEndian.Uint16(value)), nil
|
} else {
|
logx.Errorf("plc read get an unknown int value: %v, address:%v", value, address)
|
return nil, errors.New(fmt.Sprintf("unknown int value:%v", value))
|
}
|
}
|
logx.Infof("plc read ok, address: %v, result: %v", address, value)
|
} else if plcConfig.Method == constvar.PlcMethodSerial {
|
ipAddr = conf.Conf.Services.Serial
|
if ipAddr == "" {
|
return nil, errors.New("conf.Conf.Services.Serial config not set yet")
|
}
|
label := fmt.Sprintf("D%d", address)
|
return plccom.ReadPLC(plccom.DeviceTypeMitsubishi, ipAddr, label)
|
}
|
return
|
}
|