1 Star 0 Fork 0

sevpinna / ModbusTCP

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
克隆/下载
Comm.go 4.17 KB
一键复制 编辑 原始数据 按行查看 历史
package ModbusTCP
import (
"gitee.com/sevpinna/Aweto"
"github.com/pkg/errors"
"log"
"net"
"strconv"
"strings"
"time"
)
func send(conn net.Conn, data []byte) (v []byte, err error) {
err = conn.SetDeadline(time.Now().Add(1000 * time.Millisecond))
if err != nil {
log.Print(err)
return nil, err
}
_, err = conn.Write(data)
if err != nil {
log.Print(err)
return nil, err
}
var n int
v = make([]byte, 20)
err = conn.SetDeadline(time.Now().Add(2000 * time.Millisecond))
if err != nil {
log.Print(err)
return nil, err
}
n, err = conn.Read(v)
if err != nil {
log.Print(err)
return nil, err
}
return v[:n], nil
}
func (t *tag) read(conn net.Conn) (err error) {
var v []byte
v, err = send(conn, t.Read)
if err != nil {
return err
}
if len(v) < 9 {
log.Print("Rev bytes short")
return nil
}
if v[7] != t.Read[7] {
log.Print(string(v[8]))
return nil
}
_, _, l := getlen(t.Type)
var swap = 2
if t.Swap {
swap = 0
}
d, err := Aweto.ToValue(v[len(v)-int(l):], t.Type, true, swap)
if err != nil {
errString := err.Error()
if !strings.Contains(errString, "Data is not dword") {
log.Print(err)
return nil
}
log.Print(err)
err = nil
}
t.Value = d
dd, ok := d.(uint16)
if t.Bit > -1 && ok {
x := uint16(1) << t.Bit
if dd&x > 0 {
d = true
} else {
d = false
}
}
callback(t.TagID, d, time.Now().Unix())
return nil
}
func (t *tag) write(conn net.Conn, data interface{}) (err error) {
if t.Write == nil {
return nil
}
if t.Value == nil {
return nil
}
var swap = 2
if t.Swap {
swap = 0
}
d, ok := data.(uint16)
if t.Bit > -1 && ok {
x := uint16(1) << t.Bit
if d == 1 {
data = t.Value.(uint16) | x
} else {
x = ^x
data = t.Value.(uint16) & x
}
}
var db []byte
d2, ok2 := data.(bool)
if t.Type == "bool" && ok2 {
if d2 {
db, err = Aweto.ToBytes(uint16(65280), true, swap, 0)
} else {
db, err = Aweto.ToBytes(uint16(0), true, swap, 0)
}
} else {
db, err = Aweto.ToBytes(data, true, swap, 0)
}
if err != nil {
errString := err.Error()
if !strings.Contains(errString, "Data is not") {
log.Print(err)
return nil
}
log.Print(err)
}
b := Aweto.BytesCombine(t.Write, db)
var v []byte
v, err = send(conn, b)
if len(v) < 9 {
log.Print("Rev Data len is not")
return nil
}
if len(v) == 12 {
return nil
}
log.Print("Write fail")
return nil
}
func (p *protocol) getRead(Type string) []byte {
index, _ := Aweto.ToBytes(uint16(1), true, 0, 0)
mode := []byte{0, 0}
id := []byte{uint8(p.ID)}
f, _ := getfunc(p.Register, false)
addr, _ := Aweto.ToBytes(uint16(p.Addr), true, 0, 0)
wordlen, _, _ := getlen(Type)
data := Aweto.BytesCombine(id, f, addr, wordlen)
datalen, _ := Aweto.ToBytes(uint16(len(data)), true, 0, 0)
return Aweto.BytesCombine(index, mode, datalen, data)
}
func (p *protocol) getWrite(Type string) []byte {
index, _ := Aweto.ToBytes(uint16(2), true, 0, 0)
mode := []byte{0, 0}
id := []byte{uint8(p.ID)}
f, err := getfunc(p.Register, true)
if err != nil {
return nil
}
addr, _ := Aweto.ToBytes(uint16(p.Addr), true, 0, 0)
wordlen, byteslen, bytesnum := getlen(Type)
var data []byte
if f[0] == 5 {
data = Aweto.BytesCombine(id, f, addr)
} else {
data = Aweto.BytesCombine(id, f, addr, wordlen, byteslen)
}
datalen, _ := Aweto.ToBytes(uint16(len(data))+bytesnum, true, 0, 0)
return Aweto.BytesCombine(index, mode, datalen, data)
}
func getfunc(Reg string, rw bool) (f []byte, err error) {
reg, _ := strconv.ParseInt(Reg, 0, 0)
switch reg {
case 1:
if rw {
f = []byte{5}
} else {
f = []byte{1}
}
case 2:
if rw {
err = errors.New("Can not Write to Input status!")
} else {
f = []byte{2}
}
case 4:
if rw {
err = errors.New("Can not Write to Input register!")
} else {
f = []byte{4}
}
case 3:
if rw {
f = []byte{16}
} else {
f = []byte{3}
}
}
return
}
func getlen(t string) (wordlen, byteslen []byte, byteslennum uint16) {
switch t {
case "bool", "uint16", "int16":
wordlen = []byte{0, 1}
byteslen = []byte{2}
byteslennum = 2
case "uint32", "int32", "float32":
wordlen = []byte{0, 2}
byteslen = []byte{4}
byteslennum = 4
case "float64":
wordlen = []byte{0, 4}
byteslen = []byte{8}
byteslennum = 8
}
return
}
Go
1
https://gitee.com/sevpinna/ModbusTCP.git
git@gitee.com:sevpinna/ModbusTCP.git
sevpinna
ModbusTCP
ModbusTCP
4f27695a97cd

搜索帮助