修改:1、解决lua解析器无法被多个采集任务同时调用的问题,采用加锁的方式解决

This commit is contained in:
pengwang 2020-12-31 13:20:10 +08:00
parent d40e65f1ec
commit b1f43d7baf
9 changed files with 329 additions and 292 deletions

View File

@ -2,7 +2,6 @@ package device
import ( import (
"encoding/json" "encoding/json"
lua "github.com/yuin/gopher-lua"
"log" "log"
"os" "os"
"path/filepath" "path/filepath"
@ -22,29 +21,28 @@ const (
) )
type CommunicationMessageTemplate struct { type CommunicationMessageTemplate struct {
CollName string `json:"CollInterfaceName"` //接口名称 CollName string `json:"CollInterfaceName"` //接口名称
TimeStamp string `json:"TimeStamp"` //时间戳 TimeStamp string `json:"TimeStamp"` //时间戳
Direction string `json:"DataDirection"` //数据方向 Direction string `json:"DataDirection"` //数据方向
Content string `json:"DataContent"` //数据内容 Content string `json:"DataContent"` //数据内容
} }
//采集接口模板 //采集接口模板
type CollectInterfaceTemplate struct { type CollectInterfaceTemplate struct {
CollInterfaceName string `json:"CollInterfaceName"` //采集接口 CollInterfaceName string `json:"CollInterfaceName"` //采集接口
CommInterfaceName string `json:"CommInterfaceName"` //通信接口 CommInterfaceName string `json:"CommInterfaceName"` //通信接口
CommMessage []CommunicationMessageTemplate `json:"-"` CommMessage []CommunicationMessageTemplate `json:"-"`
PollPeriod int `json:"PollPeriod"` //采集周期 PollPeriod int `json:"PollPeriod"` //采集周期
OfflinePeriod int `json:"OfflinePeriod"` //离线超时周期 OfflinePeriod int `json:"OfflinePeriod"` //离线超时周期
DeviceNodeCnt int `json:"DeviceNodeCnt"` //设备数量 DeviceNodeCnt int `json:"DeviceNodeCnt"` //设备数量
DeviceNodeOnlineCnt int `json:"DeviceNodeOnlineCnt"` //设备在线数量 DeviceNodeOnlineCnt int `json:"DeviceNodeOnlineCnt"` //设备在线数量
DeviceNodeMap []*DeviceNodeTemplate `json:"DeviceNodeMap"` //节点表 DeviceNodeMap []*DeviceNodeTemplate `json:"DeviceNodeMap"` //节点表
OnlineReportChan chan string `json:"-"` OnlineReportChan chan string `json:"-"`
OfflineReportChan chan string `json:"-"` OfflineReportChan chan string `json:"-"`
PropertyReportChan chan string `json:"-"` PropertyReportChan chan string `json:"-"`
LuaState *lua.LState `json:"-"`
} }
var CollectInterfaceMap = make([]*CollectInterfaceTemplate,0) var CollectInterfaceMap = make([]*CollectInterfaceTemplate, 0)
func WriteCollectInterfaceManageToJson() { func WriteCollectInterfaceManageToJson() {
@ -61,36 +59,36 @@ func WriteCollectInterfaceManageToJson() {
//采集接口配置参数 //采集接口配置参数
type CollectInterfaceParamTemplate struct { type CollectInterfaceParamTemplate struct {
CollInterfaceName string `json:"CollInterfaceName"` //采集接口 CollInterfaceName string `json:"CollInterfaceName"` //采集接口
CommInterfaceName string `json:"CommInterfaceName"` //通信接口 CommInterfaceName string `json:"CommInterfaceName"` //通信接口
PollPeriod int `json:"PollPeriod"` //采集周期 PollPeriod int `json:"PollPeriod"` //采集周期
OfflinePeriod int `json:"OfflinePeriod"` //离线超时周期 OfflinePeriod int `json:"OfflinePeriod"` //离线超时周期
DeviceNodeCnt int `json:"DeviceNodeCnt"` //设备数量 DeviceNodeCnt int `json:"DeviceNodeCnt"` //设备数量
DeviceNodeNameMap []string `json:"DeviceNodeNameMap"` //节点名称 DeviceNodeNameMap []string `json:"DeviceNodeNameMap"` //节点名称
DeviceNodeAddrMap []string `json:"DeviceNodeAddrMap"` //节点地址 DeviceNodeAddrMap []string `json:"DeviceNodeAddrMap"` //节点地址
DeviceNodeTypeMap []string `json:"DeviceNodeTypeMap"` //节点类型 DeviceNodeTypeMap []string `json:"DeviceNodeTypeMap"` //节点类型
} }
//定义采集接口参数结构体 //定义采集接口参数结构体
CollectInterfaceParamMap := struct { CollectInterfaceParamMap := struct {
CollectInterfaceParam []CollectInterfaceParamTemplate CollectInterfaceParam []CollectInterfaceParamTemplate
}{ }{
CollectInterfaceParam: make([]CollectInterfaceParamTemplate, 0), CollectInterfaceParam: make([]CollectInterfaceParamTemplate, 0),
} }
for _, v := range CollectInterfaceMap { for _, v := range CollectInterfaceMap {
ParamTemplate := CollectInterfaceParamTemplate{ ParamTemplate := CollectInterfaceParamTemplate{
CollInterfaceName : v.CollInterfaceName, CollInterfaceName: v.CollInterfaceName,
CommInterfaceName : v.CommInterfaceName, CommInterfaceName: v.CommInterfaceName,
PollPeriod : v.PollPeriod, PollPeriod: v.PollPeriod,
OfflinePeriod : v.OfflinePeriod, OfflinePeriod: v.OfflinePeriod,
DeviceNodeCnt : v.DeviceNodeCnt, DeviceNodeCnt: v.DeviceNodeCnt,
} }
ParamTemplate.DeviceNodeNameMap = make([]string,0) ParamTemplate.DeviceNodeNameMap = make([]string, 0)
ParamTemplate.DeviceNodeAddrMap = make([]string,0) ParamTemplate.DeviceNodeAddrMap = make([]string, 0)
ParamTemplate.DeviceNodeTypeMap = make([]string,0) ParamTemplate.DeviceNodeTypeMap = make([]string, 0)
for i := 0; i < v.DeviceNodeCnt; i++ { for i := 0; i < v.DeviceNodeCnt; i++ {
ParamTemplate.DeviceNodeNameMap = append(ParamTemplate.DeviceNodeNameMap, v.DeviceNodeMap[i].Name) ParamTemplate.DeviceNodeNameMap = append(ParamTemplate.DeviceNodeNameMap, v.DeviceNodeMap[i].Name)
@ -133,14 +131,14 @@ func ReadCollectInterfaceManageFromJson() bool {
//采集接口配置参数 //采集接口配置参数
type CollectInterfaceParamTemplate struct { type CollectInterfaceParamTemplate struct {
CollInterfaceName string `json:"CollInterfaceName"` //采集接口 CollInterfaceName string `json:"CollInterfaceName"` //采集接口
CommInterfaceName string `json:"CommInterfaceName"` //通信接口 CommInterfaceName string `json:"CommInterfaceName"` //通信接口
PollPeriod int `json:"PollPeriod"` //采集周期 PollPeriod int `json:"PollPeriod"` //采集周期
OfflinePeriod int `json:"OfflinePeriod"` //离线超时周期 OfflinePeriod int `json:"OfflinePeriod"` //离线超时周期
DeviceNodeCnt int `json:"DeviceNodeCnt"` //设备数量 DeviceNodeCnt int `json:"DeviceNodeCnt"` //设备数量
DeviceNodeNameMap []string `json:"DeviceNodeNameMap"` //节点名称 DeviceNodeNameMap []string `json:"DeviceNodeNameMap"` //节点名称
DeviceNodeAddrMap []string `json:"DeviceNodeAddrMap"` //节点地址 DeviceNodeAddrMap []string `json:"DeviceNodeAddrMap"` //节点地址
DeviceNodeTypeMap []string `json:"DeviceNodeTypeMap"` //节点类型 DeviceNodeTypeMap []string `json:"DeviceNodeTypeMap"` //节点类型
} }
//定义采集接口参数结构体 //定义采集接口参数结构体
@ -157,11 +155,11 @@ func ReadCollectInterfaceManageFromJson() bool {
return false return false
} }
log.Printf("CollectInterfaceParamMap %+v\n",CollectInterfaceParamMap) log.Printf("CollectInterfaceParamMap %+v\n", CollectInterfaceParamMap)
for k, v := range CollectInterfaceParamMap.CollectInterfaceParam { for k, v := range CollectInterfaceParamMap.CollectInterfaceParam {
//创建接口实例 //创建接口实例
CollectInterfaceMap = append(CollectInterfaceMap,NewCollectInterface(v.CollInterfaceName, CollectInterfaceMap = append(CollectInterfaceMap, NewCollectInterface(v.CollInterfaceName,
v.CommInterfaceName, v.CommInterfaceName,
v.PollPeriod, v.PollPeriod,
v.OfflinePeriod, v.OfflinePeriod,
@ -185,6 +183,9 @@ func ReadCollectInterfaceManageFromJson() bool {
} }
func DeviceNodeManageInit() { func DeviceNodeManageInit() {
//设备模版
ReadDeviceNodeTypeMap()
//通信接口 //通信接口
CommInterfaceInit() CommInterfaceInit()
//采集接口 //采集接口
@ -193,16 +194,7 @@ func DeviceNodeManageInit() {
//log.Printf("collectMInterfaceMap %+v\n",CollectInterfaceMap) //log.Printf("collectMInterfaceMap %+v\n",CollectInterfaceMap)
} else { } else {
//for i := 0; i < MaxCollectInterfaceManage; i++ {
// //创建接口实例
// CollectInterfaceMap[i] = NewCollectInterface(i,
// 60,
// 180,
// 0)
//}
} }
//设备模版
ReadDeviceNodeTypeMapFromJson()
} }
/******************************************************** /********************************************************
@ -216,24 +208,21 @@ func DeviceNodeManageInit() {
日期 日期
********************************************************/ ********************************************************/
func NewCollectInterface(collInterfaceName, commInterfaceName string, func NewCollectInterface(collInterfaceName, commInterfaceName string,
pollPeriod, offlinePeriod int, deviceNodeCnt int) *CollectInterfaceTemplate { pollPeriod, offlinePeriod int, deviceNodeCnt int) *CollectInterfaceTemplate {
nodeManage := &CollectInterfaceTemplate{ nodeManage := &CollectInterfaceTemplate{
CollInterfaceName: collInterfaceName, CollInterfaceName: collInterfaceName,
CommInterfaceName: commInterfaceName, CommInterfaceName: commInterfaceName,
CommMessage: make([]CommunicationMessageTemplate,0), CommMessage: make([]CommunicationMessageTemplate, 0),
PollPeriod: pollPeriod, PollPeriod: pollPeriod,
OfflinePeriod: offlinePeriod, OfflinePeriod: offlinePeriod,
DeviceNodeCnt: deviceNodeCnt, DeviceNodeCnt: deviceNodeCnt,
DeviceNodeMap: make([]*DeviceNodeTemplate, 0), DeviceNodeMap: make([]*DeviceNodeTemplate, 0),
OfflineReportChan: make(chan string, 100), OfflineReportChan: make(chan string, 100),
OnlineReportChan: make(chan string, 100), OnlineReportChan: make(chan string, 100),
PropertyReportChan: make(chan string, 100), PropertyReportChan: make(chan string, 100),
} }
//打开串口
//setting.SerialOpen(nodeManage.InterfaceID)
return nodeManage return nodeManage
} }
@ -263,7 +252,7 @@ func (d *CollectInterfaceTemplate) ModifyCollectInterface(pollPeriod, offlinePer
注意事项 注意事项
日期 日期
********************************************************/ ********************************************************/
func (d *CollectInterfaceTemplate) NewDeviceNode(dName string,dType string, dAddr string) { func (d *CollectInterfaceTemplate) NewDeviceNode(dName string, dType string, dAddr string) {
node := &DeviceNodeTemplate{} node := &DeviceNodeTemplate{}
node.Index = len(d.DeviceNodeMap) node.Index = len(d.DeviceNodeMap)
@ -282,7 +271,7 @@ func (d *CollectInterfaceTemplate) NewDeviceNode(dName string,dType string, dAdd
d.DeviceNodeMap = append(d.DeviceNodeMap, node) d.DeviceNodeMap = append(d.DeviceNodeMap, node)
} }
func (d *CollectInterfaceTemplate) AddDeviceNode(dName string,dType string, dAddr string) (bool, string) { func (d *CollectInterfaceTemplate) AddDeviceNode(dName string, dType string, dAddr string) (bool, string) {
node := &DeviceNodeTemplate{} node := &DeviceNodeTemplate{}
node.Index = len(d.DeviceNodeMap) node.Index = len(d.DeviceNodeMap)

View File

@ -3,15 +3,15 @@ package device
import ( import (
"fmt" "fmt"
"github.com/sirupsen/logrus" "github.com/sirupsen/logrus"
"goAdapter/setting"
"log" "log"
"strconv" "strconv"
"time" "time"
"goAdapter/setting"
) )
type CommunicationCmdTemplate struct { type CommunicationCmdTemplate struct {
CollInterfaceName string //采集接口名称 CollInterfaceName string //采集接口名称
DeviceAddr string //采集接口下设备地址 DeviceName string //采集接口下设备名称
FunName string FunName string
FunPara string FunPara string
} }
@ -71,7 +71,7 @@ func (c *CommunicationManageTemplate) AnalysisRx() {
//阻塞读 //阻塞读
rxBufCnt = serialPort.ReadData(rxBuf) rxBufCnt = serialPort.ReadData(rxBuf)
if rxBufCnt > 0 { if rxBufCnt > 0 {
//log.Printf("curRxBufCnt %v\n",rxBufCnt) //log.Printf("curRxBufCnt %v,", rxBufCnt)
//log.Printf("CurRxBuf %X\n", rxBuf[:rxBufCnt]) //log.Printf("CurRxBuf %X\n", rxBuf[:rxBufCnt])
//rxTotalBufCnt += rxBufCnt //rxTotalBufCnt += rxBufCnt
@ -92,8 +92,8 @@ func (c *CommunicationManageTemplate) CommunicationStateMachine(cmd Communicatio
startT := time.Now() //计算当前时间 startT := time.Now() //计算当前时间
for _, v := range c.CollInterface.DeviceNodeMap { for _, v := range c.CollInterface.DeviceNodeMap {
if v.Addr == cmd.DeviceAddr { if v.Name == cmd.DeviceName {
log.Printf("%v:addr %v\n", c.CollInterface.CollInterfaceName, v.Addr) log.Printf("%v:name %v\n", c.CollInterface.CollInterfaceName, v.Name)
step := 0 step := 0
for { for {
//--------------组包--------------------------- //--------------组包---------------------------
@ -103,7 +103,7 @@ func (c *CommunicationManageTemplate) CommunicationStateMachine(cmd Communicatio
if cmd.FunName == "GetDeviceRealVariables" { if cmd.FunName == "GetDeviceRealVariables" {
txBuf, ok, con = v.GenerateGetRealVariables(v.Addr, step) txBuf, ok, con = v.GenerateGetRealVariables(v.Addr, step)
} else { } else {
txBuf, ok, con = v.DeviceCustomCmd(cmd.DeviceAddr, cmd.FunName, cmd.FunPara, step) txBuf, ok, con = v.DeviceCustomCmd(cmd.DeviceName, cmd.FunName, cmd.FunPara, step)
if ok == false { if ok == false {
log.Printf("DeviceCustomCmd false\n") log.Printf("DeviceCustomCmd false\n")
goto LoopCommon goto LoopCommon
@ -279,7 +279,7 @@ func (c *CommunicationManageTemplate) CommunicationManageDel() {
setting.Logger.WithFields(logrus.Fields{ setting.Logger.WithFields(logrus.Fields{
"collName": c.CollInterface.CollInterfaceName, "collName": c.CollInterface.CollInterfaceName,
"deviceAddr": cmd.DeviceAddr, "deviceName": cmd.DeviceName,
"funName": cmd.FunName, "funName": cmd.FunName,
}).Info("emergency chan") }).Info("emergency chan")
status := false status := false
@ -357,7 +357,7 @@ func (c *CommunicationManageTemplate) CommunicationManagePoll() {
//对采集接口下设备进行遍历 //对采集接口下设备进行遍历
for _, v := range coll.DeviceNodeMap { for _, v := range coll.DeviceNodeMap {
cmd.CollInterfaceName = coll.CollInterfaceName cmd.CollInterfaceName = coll.CollInterfaceName
cmd.DeviceAddr = v.Addr cmd.DeviceName = v.Name
cmd.FunName = "GetDeviceRealVariables" cmd.FunName = "GetDeviceRealVariables"
c.CommunicationManageAddCommon(cmd) c.CommunicationManageAddCommon(cmd)
} }

View File

@ -1,14 +1,19 @@
package device package device
import ( import (
"bytes"
"github.com/yuin/gluamapper" "github.com/yuin/gluamapper"
lua "github.com/yuin/gopher-lua" lua "github.com/yuin/gopher-lua"
"layeh.com/gopher-luar"
"time"
"goAdapter/setting" "goAdapter/setting"
"layeh.com/gopher-luar"
"runtime"
"strconv"
"sync"
"time"
) )
var MaxDeviceNodeCnt int = 50 var MaxDeviceNodeCnt int = 50
var lock sync.Mutex
type ValueTemplate struct { type ValueTemplate struct {
Value interface{} //变量值,不可以是字符串 Value interface{} //变量值,不可以是字符串
@ -52,45 +57,48 @@ func (d *DeviceNodeTemplate) NewVariables() []VariableTemplate {
Variable []*LuaVariableTemplate Variable []*LuaVariableTemplate
} }
for _,c := range CollectInterfaceMap{ lock.Lock()
for _,n := range c.DeviceNodeMap{ //log.Printf("DeviceTypePluginMap %v\n",DeviceTypePluginMap)
if n.Name == d.Name{ for k, v := range DeviceNodeTypeMap.DeviceNodeType {
//调用NewVariables if d.Type == v.TemplateType {
err := c.LuaState.CallByParam(lua.P{ //调用NewVariables
Fn: c.LuaState.GetGlobal("NewVariables"), err := DeviceTypePluginMap[k].CallByParam(lua.P{
NRet: 1, Fn: DeviceTypePluginMap[k].GetGlobal("NewVariables"),
Protect: true, NRet: 1,
}) Protect: true,
if err != nil { })
setting.Logger.Warning("NewVariables err,", err) if err != nil {
} setting.Logger.Warning("NewVariables err,", err)
//获取返回结果
ret := c.LuaState.Get(-1)
c.LuaState.Pop(1)
LuaVariableMap := LuaVariableMapTemplate{}
if err := gluamapper.Map(ret.(*lua.LTable), &LuaVariableMap); err != nil {
setting.Logger.Warning("NewVariables gluamapper.Map err,", err)
}
variables := make([]VariableTemplate, 0)
for _, v := range LuaVariableMap.Variable {
variable := VariableTemplate{}
variable.Index = v.Index
variable.Name = v.Name
variable.Label = v.Label
variable.Type = v.Type
variable.Value = make([]ValueTemplate, 0)
variables = append(variables, variable)
}
return variables
} }
//获取返回结果
ret := DeviceTypePluginMap[k].Get(-1)
DeviceTypePluginMap[k].Pop(1)
LuaVariableMap := LuaVariableMapTemplate{}
if err := gluamapper.Map(ret.(*lua.LTable), &LuaVariableMap); err != nil {
setting.Logger.Warning("NewVariables gluamapper.Map err,", err)
}
variables := make([]VariableTemplate, 0)
for _, v := range LuaVariableMap.Variable {
variable := VariableTemplate{}
variable.Index = v.Index
variable.Name = v.Name
variable.Label = v.Label
variable.Type = v.Type
variable.Value = make([]ValueTemplate, 0)
variables = append(variables, variable)
}
lock.Unlock()
//log.Printf("variables %v\n",variables)
return variables
} }
} }
lock.Unlock()
return nil return nil
} }
@ -101,49 +109,49 @@ func (d *DeviceNodeTemplate) GenerateGetRealVariables(sAddr string, step int) ([
Variable []*byte Variable []*byte
} }
for _,c := range CollectInterfaceMap{ lock.Lock()
for _,n := range c.DeviceNodeMap { for k, v := range DeviceNodeTypeMap.DeviceNodeType {
if n.Name == d.Name { if d.Type == v.TemplateType {
//调用NewVariables //调用NewVariables
err := c.LuaState.CallByParam(lua.P{ err := DeviceTypePluginMap[k].CallByParam(lua.P{
Fn: c.LuaState.GetGlobal("GenerateGetRealVariables"), Fn: DeviceTypePluginMap[k].GetGlobal("GenerateGetRealVariables"),
NRet: 1, NRet: 1,
Protect: true, Protect: true,
}, lua.LString(sAddr), lua.LNumber(step)) }, lua.LString(sAddr), lua.LNumber(step))
if err != nil { if err != nil {
setting.Logger.Warning("GenerateGetRealVariables err,", err) setting.Logger.Warning("GenerateGetRealVariables err,", err)
}
//获取返回结果
ret := c.LuaState.Get(-1)
c.LuaState.Pop(1)
LuaVariableMap := LuaVariableMapTemplate{}
if err := gluamapper.Map(ret.(*lua.LTable), &LuaVariableMap); err != nil {
setting.Logger.Warning("GenerateGetRealVariables gluamapper.Map err,", err)
}
ok := false
con := false //后续是否有报文
if LuaVariableMap.Status == "0" {
con = false
} else {
con = true
}
nBytes := make([]byte, 0)
if len(LuaVariableMap.Variable) > 0 {
ok = true
for _, v := range LuaVariableMap.Variable {
nBytes = append(nBytes, *v)
}
} else {
ok = false
}
return nBytes, ok, con
} }
//获取返回结果
ret := DeviceTypePluginMap[k].Get(-1)
DeviceTypePluginMap[k].Pop(1)
LuaVariableMap := LuaVariableMapTemplate{}
if err := gluamapper.Map(ret.(*lua.LTable), &LuaVariableMap); err != nil {
setting.Logger.Warning("GenerateGetRealVariables gluamapper.Map err,", err)
}
ok := false
con := false //后续是否有报文
if LuaVariableMap.Status == "0" {
con = false
} else {
con = true
}
nBytes := make([]byte, 0)
if len(LuaVariableMap.Variable) > 0 {
ok = true
for _, v := range LuaVariableMap.Variable {
nBytes = append(nBytes, *v)
}
} else {
ok = false
}
lock.Unlock()
return nBytes, ok, con
} }
} }
lock.Unlock()
return nil, false, false return nil, false, false
} }
@ -154,62 +162,72 @@ func (d *DeviceNodeTemplate) DeviceCustomCmd(sAddr string, cmdName string, cmdPa
Variable []*byte `json:"Variable"` Variable []*byte `json:"Variable"`
} }
lock.Lock()
//log.Printf("cmdParam %+v\n", cmdParam) //log.Printf("cmdParam %+v\n", cmdParam)
for _,c := range CollectInterfaceMap{ for k, v := range DeviceNodeTypeMap.DeviceNodeType {
for _,n := range c.DeviceNodeMap { if d.Type == v.TemplateType {
if n.Name == d.Name { var err error
var err error var ret lua.LValue
var ret lua.LValue
//调用DeviceCustomCmd //调用DeviceCustomCmd
err = c.LuaState.CallByParam(lua.P{ err = DeviceTypePluginMap[k].CallByParam(lua.P{
Fn: c.LuaState.GetGlobal("DeviceCustomCmd"), Fn: DeviceTypePluginMap[k].GetGlobal("DeviceCustomCmd"),
NRet: 1, NRet: 1,
Protect: true, Protect: true,
}, lua.LString(sAddr), }, lua.LString(sAddr),
lua.LString(cmdName), lua.LString(cmdName),
lua.LString(cmdParam), lua.LString(cmdParam),
lua.LNumber(step)) lua.LNumber(step))
if err != nil { if err != nil {
setting.Logger.Warning("DeviceCustomCmd err,", err) setting.Logger.Warning("DeviceCustomCmd err,", err)
return nil, false, false lock.Unlock()
} return nil, false, false
//获取返回结果
ret = c.LuaState.Get(-1)
c.LuaState.Pop(1)
LuaVariableMap := LuaVariableMapTemplate{}
if err := gluamapper.Map(ret.(*lua.LTable), &LuaVariableMap); err != nil {
setting.Logger.Warning("DeviceCustomCmd gluamapper.Map err,", err)
return nil, false, false
}
ok := false
con := false //后续是否有报文
if LuaVariableMap.Status == "0" {
con = false
} else {
con = true
}
nBytes := make([]byte, 0)
if len(LuaVariableMap.Variable) > 0 {
ok = true
for _, v := range LuaVariableMap.Variable {
nBytes = append(nBytes, *v)
}
} else {
ok = false
}
return nBytes, ok, con
} }
//获取返回结果
ret = DeviceTypePluginMap[k].Get(-1)
DeviceTypePluginMap[k].Pop(1)
LuaVariableMap := LuaVariableMapTemplate{}
if err := gluamapper.Map(ret.(*lua.LTable), &LuaVariableMap); err != nil {
setting.Logger.Warning("DeviceCustomCmd gluamapper.Map err,", err)
lock.Unlock()
return nil, false, false
}
ok := false
con := false //后续是否有报文
if LuaVariableMap.Status == "0" {
con = false
} else {
con = true
}
nBytes := make([]byte, 0)
if len(LuaVariableMap.Variable) > 0 {
ok = true
for _, v := range LuaVariableMap.Variable {
nBytes = append(nBytes, *v)
}
} else {
ok = false
}
lock.Unlock()
return nBytes, ok, con
} }
} }
lock.Unlock()
return nil, false, false return nil, false, false
} }
func getGoroutineID() uint64 {
b := make([]byte, 64)
runtime.Stack(b, false)
b = bytes.TrimPrefix(b, []byte("goroutine "))
b = b[:bytes.IndexByte(b, ' ')]
n, _ := strconv.ParseUint(string(b), 10, 64)
return n
}
func (d *DeviceNodeTemplate) AnalysisRx(sAddr string, variables []VariableTemplate, rxBuf []byte, rxBufCnt int) chan bool { func (d *DeviceNodeTemplate) AnalysisRx(sAddr string, variables []VariableTemplate, rxBuf []byte, rxBufCnt int) chan bool {
status := make(chan bool, 1) status := make(chan bool, 1)
@ -228,67 +246,66 @@ func (d *DeviceNodeTemplate) AnalysisRx(sAddr string, variables []VariableTempla
Variable []*LuaVariableTemplate Variable []*LuaVariableTemplate
} }
for _,c := range CollectInterfaceMap{ lock.Lock()
for _,n := range c.DeviceNodeMap { for k, v := range DeviceNodeTypeMap.DeviceNodeType {
if n.Name == d.Name { if d.Type == v.TemplateType {
tbl := lua.LTable{} tbl := lua.LTable{}
for _, v := range rxBuf { for _, v := range rxBuf {
tbl.Append(lua.LNumber(v)) tbl.Append(lua.LNumber(v))
} }
DeviceTypePluginMap[k].SetGlobal("rxBuf", luar.New(DeviceTypePluginMap[k], &tbl))
c.LuaState.SetGlobal("rxBuf", luar.New(c.LuaState, &tbl)) //AnalysisRx
err := DeviceTypePluginMap[k].CallByParam(lua.P{
Fn: DeviceTypePluginMap[k].GetGlobal("AnalysisRx"),
NRet: 1,
Protect: true,
}, lua.LString(sAddr), lua.LNumber(rxBufCnt))
if err != nil {
setting.Logger.Warning("AnalysisRx err,", err)
}
//AnalysisRx //获取返回结果
err := c.LuaState.CallByParam(lua.P{ ret := DeviceTypePluginMap[k].Get(-1)
Fn: c.LuaState.GetGlobal("AnalysisRx"), DeviceTypePluginMap[k].Pop(1)
NRet: 1,
Protect: true,
}, lua.LString(sAddr), lua.LNumber(rxBufCnt))
if err != nil {
setting.Logger.Warning("AnalysisRx err,", err)
}
//获取返回结果 LuaVariableMap := LuaVariableMapTemplate{}
ret := c.LuaState.Get(-1)
c.LuaState.Pop(1)
LuaVariableMap := LuaVariableMapTemplate{} if err := gluamapper.Map(ret.(*lua.LTable), &LuaVariableMap); err != nil {
setting.Logger.Warning("AnalysisRx gluamapper.Map err,", err)
}
if err := gluamapper.Map(ret.(*lua.LTable), &LuaVariableMap); err != nil { timeNowStr := time.Now().Format("2006-01-02 15:04:05")
setting.Logger.Warning("AnalysisRx gluamapper.Map err,", err) value := ValueTemplate{}
} if LuaVariableMap.Status == "0" {
if len(LuaVariableMap.Variable) > 0 {
for _, lv := range LuaVariableMap.Variable {
for k, v := range variables {
if lv.Index == v.Index {
variables[k].Index = lv.Index
variables[k].Name = lv.Name
variables[k].Label = lv.Label
variables[k].Type = lv.Type
timeNowStr := time.Now().Format("2006-01-02 15:04:05") value.Value = lv.Value
value := ValueTemplate{} value.Explain = lv.Explain
//log.Printf("LuaVariableMap %+v\n", LuaVariableMap) value.TimeStamp = timeNowStr
if LuaVariableMap.Status == "0" {
if len(LuaVariableMap.Variable) > 0 {
for _, lv := range LuaVariableMap.Variable {
for k, v := range variables {
if lv.Index == v.Index {
variables[k].Index = lv.Index
variables[k].Name = lv.Name
variables[k].Label = lv.Label
variables[k].Type = lv.Type
value.Value = lv.Value if len(variables[k].Value) < 100 {
value.Explain = lv.Explain variables[k].Value = append(variables[k].Value, value)
value.TimeStamp = timeNowStr } else {
variables[k].Value = variables[k].Value[1:]
if len(variables[k].Value) < 100 { variables[k].Value = append(variables[k].Value, value)
variables[k].Value = append(variables[k].Value, value)
} else {
variables[k].Value = variables[k].Value[1:]
variables[k].Value = append(variables[k].Value, value)
}
} }
//log.Printf("LuaVariables %+v\n", variables[k])
} }
} }
} }
status <- true
} }
status <- true
} }
} }
} }
lock.Unlock()
return status return status
} }

View File

@ -3,6 +3,7 @@ package device
import ( import (
"encoding/json" "encoding/json"
lua "github.com/yuin/gopher-lua" lua "github.com/yuin/gopher-lua"
"goAdapter/setting"
"io/ioutil" "io/ioutil"
"log" "log"
"os" "os"
@ -25,12 +26,21 @@ type DeviceNodeTypeMapStruct struct {
DeviceNodeType []DeviceNodeTypeTemplate DeviceNodeType []DeviceNodeTypeTemplate
} }
type DeviceNodeTypeLuaState struct{
LuaState *lua.LState
TypeName string
CollName string
}
var DeviceNodeTypeMap = DeviceNodeTypeMapStruct{ var DeviceNodeTypeMap = DeviceNodeTypeMapStruct{
DeviceNodeType : make([]DeviceNodeTypeTemplate,0), DeviceNodeType : make([]DeviceNodeTypeTemplate,0),
} }
//var DeviceTypePluginMap = make(map[int]*plugin.Plugin) //var DeviceTypePluginMap = make(map[int]*plugin.Plugin)
//var DeviceTypePluginMap = make(map[int]*lua.LState) var DeviceTypePluginMap = make(map[int]*lua.LState)
//var DeviceTypePluginMap = make([]DeviceNodeTypeLuaState,0)
func init(){ func init(){
@ -85,7 +95,7 @@ func updataDeviceType(path string,fileName []string) ([]string,error){
return fileName,nil return fileName,nil
} }
func ReadDeviceNodeTypeMapFromJson() bool { func ReadDeviceNodeTypeMap() bool {
deviceTypeTemplate := struct { deviceTypeTemplate := struct {
TemplateName string `json:"TemplateName"` //模板名称 TemplateName string `json:"TemplateName"` //模板名称
@ -126,33 +136,19 @@ func ReadDeviceNodeTypeMapFromJson() bool {
DeviceNodeTypeMap.DeviceNodeType = append(DeviceNodeTypeMap.DeviceNodeType,nodeType) DeviceNodeTypeMap.DeviceNodeType = append(DeviceNodeTypeMap.DeviceNodeType,nodeType)
} }
} }
//打开lua文件
//for k,v := range DeviceNodeTypeMap.DeviceNodeType{
// for _,fileName := range fileNameMap{
// if strings.Contains(fileName,".lua") {
// if strings.Contains(fileName, v.TemplateType) {
// template, err := setting.LuaOpenFile(fileName)
// if err != nil {
// log.Printf("openPlug %s err,%s\n",fileName,err)
// }else{
// log.Printf("openPlug %s ok\n", fileName)
// }
//
// DeviceTypePluginMap[k] = template
// }
// }
// }
//}
for _,c := range CollectInterfaceMap{ //打开lua文件
for _,fileName := range fileNameMap{ for k, v := range DeviceNodeTypeMap.DeviceNodeType {
if strings.Contains(fileName,".lua") { for _, fileName := range fileNameMap {
c.LuaState = lua.NewState() if strings.Contains(fileName, ".lua") {
err := c.LuaState.DoFile(fileName) if strings.Contains(fileName, v.TemplateType) {
if err != nil { template, err := setting.LuaOpenFile(fileName)
log.Printf("openLua %s err,%s\n",fileName,err) if err != nil {
}else{ log.Printf("openPlug %s err,%s\n", fileName, err)
log.Printf("openLua %s ok\n", fileName) } else {
log.Printf("openPlug %s ok\n", fileName)
}
DeviceTypePluginMap[k] = template
} }
} }
} }
@ -161,5 +157,38 @@ func ReadDeviceNodeTypeMapFromJson() bool {
return true return true
} }
//func UpdateDeviceNodeType(collName string) {
//
// exeCurDir, _ := filepath.Abs(filepath.Dir(os.Args[0]))
//
// //遍历json和so文件
// pluginPath := exeCurDir + "/plugin"
// fileNameMap := make([]string,0)
// fileNameMap,_ = updataDeviceType(pluginPath,fileNameMap)
//
// var filenameWithSuffix string
// var fileSuffix string
// for _,fileName := range fileNameMap{
// if strings.Contains(fileName,".lua") {
// typeLuaState := DeviceNodeTypeLuaState{}
// typeLuaState.CollName = collName
// filenameWithSuffix = path.Base(fileName)
// fileSuffix = path.Ext(filenameWithSuffix)
// typeLuaState.TypeName = strings.TrimSuffix(filenameWithSuffix, fileSuffix)
// typeLuaState.LuaState = lua.NewState()
//
// typeLuaState.LuaState.SetGlobal("GetCRCModbus", typeLuaState.LuaState.NewFunction(setting.GetCRCModbus))
// typeLuaState.LuaState.SetGlobal("CheckCRCModbus", typeLuaState.LuaState.NewFunction(setting.CheckCRCModbus))
// err := typeLuaState.LuaState.DoFile(fileName)
// if err != nil {
// log.Printf("openLua %s err,%s\n",fileName,err)
// }else{
// log.Printf("openLua %s ok\n", fileName)
// DeviceTypePluginMap = append(DeviceTypePluginMap,typeLuaState)
// }
// }
// }
//}

View File

@ -162,5 +162,5 @@ func RouterWeb() {
} }
router.Run(":80") router.Run(":8080")
} }

20
main.go
View File

@ -9,23 +9,22 @@ import (
"goAdapter/setting" "goAdapter/setting"
) )
func main() { func main() {
/**************获取配置文件***********************/ /**************获取配置文件***********************/
setting.GetConf() setting.GetConf()
setting.LogerInit(setting.LogLevel,setting.LogSaveToFile,setting.LogFileMaxCnt) setting.LogerInit(setting.LogLevel, setting.LogSaveToFile, setting.LogFileMaxCnt)
//记录起始时间 //记录起始时间
setting.GetTimeStart() setting.GetTimeStart()
setting.Logger.Info("goteway V0.0.1") setting.Logger.Info("goteway V0.0.1")
setting.MemoryDataStream = setting.NewDataStreamTemplate("内存使用率") setting.MemoryDataStream = setting.NewDataStreamTemplate("内存使用率")
setting.DiskDataStream = setting.NewDataStreamTemplate("硬盘使用率") setting.DiskDataStream = setting.NewDataStreamTemplate("硬盘使用率")
setting.DeviceOnlineDataStream = setting.NewDataStreamTemplate("设备在线率") setting.DeviceOnlineDataStream = setting.NewDataStreamTemplate("设备在线率")
setting.DevicePacketLossDataStream = setting.NewDataStreamTemplate("通信丢包率") setting.DevicePacketLossDataStream = setting.NewDataStreamTemplate("通信丢包率")
/**************网口初始化***********************/ /**************网口初始化***********************/
setting.NetworkParaRead() setting.NetworkParaRead()
@ -59,7 +58,7 @@ func main() {
_ = cronProcess.AddFunc("*/60 * * * * *", setting.CollectSystemParam) _ = cronProcess.AddFunc("*/60 * * * * *", setting.CollectSystemParam)
// 每天0点,定时获取NTP服务器的时间并校时 // 每天0点,定时获取NTP服务器的时间并校时
_ = cronProcess.AddFunc("0 0 0 * * ?", func(){ _ = cronProcess.AddFunc("0 0 0 * * ?", func() {
setting.NTPGetTime() setting.NTPGetTime()
}) })
@ -69,10 +68,11 @@ func main() {
cronProcess.Start() cronProcess.Start()
defer cronProcess.Stop() defer cronProcess.Stop()
//setting.Logger.Info("wait 10s")
//time.Sleep(time.Second * 10)
report.ReportServiceInit() report.ReportServiceInit()
for _, v := range device.CommunicationManage {
v.CommunicationManagePoll()
}
httpServer.RouterWeb() httpServer.RouterWeb()
} }

View File

@ -399,6 +399,8 @@ func (r *ReportServiceParamAliyunTemplate) AllNodePropertyPost() {
if c.CollInterfaceName == n.CollInterfaceName { if c.CollInterfaceName == n.CollInterfaceName {
for _, d := range c.DeviceNodeMap { for _, d := range c.DeviceNodeMap {
if d.Addr == n.Addr { if d.Addr == n.Addr {
//log.Printf("nodeAddr %v\n",n.Addr)
//log.Printf("valueMap %v\n",d.VariableMap)
for _, v := range d.VariableMap { for _, v := range d.VariableMap {
if len(v.Value) > 1 { if len(v.Value) > 1 {
index := len(v.Value) - 1 index := len(v.Value) - 1
@ -614,7 +616,7 @@ func ReportServiceAliyunProcessRemoteCmd(r *ReportServiceParamAliyunTemplate, me
for _, v := range addrArray { for _, v := range addrArray {
cmd := device.CommunicationCmdTemplate{} cmd := device.CommunicationCmdTemplate{}
cmd.CollInterfaceName = "coll1" cmd.CollInterfaceName = "coll1"
cmd.DeviceAddr = v cmd.DeviceName = v
cmd.FunName = cmdName cmd.FunName = cmdName
paramStr, _ := json.Marshal(message.Params) paramStr, _ := json.Marshal(message.Params)
cmd.FunPara = string(paramStr) cmd.FunPara = string(paramStr)
@ -648,7 +650,7 @@ func ReportServiceAliyunProcessGetSubDeviceProperty(r *ReportServiceParamAliyunT
for _, v := range addrArray { for _, v := range addrArray {
cmd := device.CommunicationCmdTemplate{} cmd := device.CommunicationCmdTemplate{}
cmd.CollInterfaceName = "coll1" cmd.CollInterfaceName = "coll1"
cmd.DeviceAddr = v cmd.DeviceName = v
cmd.FunName = cmdName cmd.FunName = cmdName
paramStr, _ := json.Marshal(message.Params) paramStr, _ := json.Marshal(message.Params)
cmd.FunPara = string(paramStr) cmd.FunPara = string(paramStr)

View File

@ -4,6 +4,7 @@ import (
"fmt" "fmt"
rotatelogs "github.com/lestrrat-go/file-rotatelogs" rotatelogs "github.com/lestrrat-go/file-rotatelogs"
"github.com/sirupsen/logrus" "github.com/sirupsen/logrus"
"log"
"os" "os"
"path/filepath" "path/filepath"
"time" "time"
@ -18,7 +19,7 @@ func init() {
func LogerInit(level string, save bool, cnt uint) { func LogerInit(level string, save bool, cnt uint) {
//log输出行号和ms //log输出行号和ms
//log.SetFlags(log.Lshortfile | log.Ldate | log.Lmicroseconds) log.SetFlags(log.Lshortfile | log.Ldate | log.Lmicroseconds)
// 设置日志格式为json格式 自带的只有两种样式logrus.JSONFormatter{}和logrus.TextFormatter{} // 设置日志格式为json格式 自带的只有两种样式logrus.JSONFormatter{}和logrus.TextFormatter{}
Logger.Formatter = &logrus.JSONFormatter{} Logger.Formatter = &logrus.JSONFormatter{}

View File

@ -3,7 +3,6 @@ package setting
import ( import (
"github.com/yuin/gluamapper" "github.com/yuin/gluamapper"
lua "github.com/yuin/gopher-lua" lua "github.com/yuin/gopher-lua"
"log"
"os" "os"
"path/filepath" "path/filepath"
"sync" "sync"
@ -161,7 +160,7 @@ func GetCRCModbus(L *lua.LState) int {
} }
} }
log.Printf("crcBytes %x\n", nBytes) //log.Printf("crcBytes %x\n", nBytes)
//lenCRC := len(nBytes) //lenCRC := len(nBytes)
crc := crc16(nBytes) crc := crc16(nBytes)
//log.Printf("crcValue %v\n", crc) //log.Printf("crcValue %v\n", crc)