修改:1、修改commManage,采用状态机模式

This commit is contained in:
pengwang 2021-09-10 17:21:42 +08:00
parent a1419aab30
commit b04d758dac
5 changed files with 224 additions and 8 deletions

View File

@ -212,7 +212,6 @@ func NewCollectInterface(collInterfaceName, commInterfaceName string,
}
}
setting.Logger.Debugf("CommunicationInterfaceMap %v index %v", commInterface.CommunicationInterfaceMap, index)
nodeManage := &CollectInterfaceTemplate{
CollInterfaceName: collInterfaceName,
CommInterfaceName: commInterfaceName,

View File

@ -31,6 +31,16 @@ const (
CommunicationManageMessageMaxCnt = 1024
)
const (
CommunicationState_Start int = iota
CommunicationState_Generate
CommunicationState_Send
CommunicationState_Wait
CommunicationState_WaitSucess
CommunicationState_WaitFail
CommunicationState_Stop
)
var CommunicationManage = make([]*CommunicationManageTemplate, 0)
func NewCommunicationManageTemplate(coll *CollectInterfaceTemplate) *CommunicationManageTemplate {
@ -102,6 +112,205 @@ func (c *CommunicationManageTemplate) ProcessReceiveData() {
}
func (c *CommunicationManageTemplate) CommunicationStateMachine(cmd CommunicationCmdTemplate) CommunicationRxTemplate {
rxResult := CommunicationRxTemplate{
Status: false,
}
commState := CommunicationState_Start
nodeIndex := -1
commStep := 0
txBuf := make([]byte, 0)
continues := false
func() {
for {
switch commState {
case CommunicationState_Start:
{
for k, v := range c.CollInterface.DeviceNodeMap {
if v.Name == cmd.DeviceName {
nodeIndex = k
}
}
if nodeIndex == -1 {
commState = CommunicationState_Stop
} else {
commState = CommunicationState_Generate
}
}
case CommunicationState_Generate:
{
//--------------组包---------------------------
result := false
if cmd.FunName == "GetDeviceRealVariables" {
txBuf, result, continues = c.CollInterface.DeviceNodeMap[nodeIndex].GenerateGetRealVariables(
c.CollInterface.DeviceNodeMap[nodeIndex].Addr,
commStep)
if result == false {
setting.Logger.Errorf("%v:GetRealVariables fail", c.CollInterface.CollInterfaceName)
commState = CommunicationState_Stop
} else {
commState = CommunicationState_Send
commStep++
}
} else {
txBuf, result, continues = c.CollInterface.DeviceNodeMap[nodeIndex].DeviceCustomCmd(
c.CollInterface.DeviceNodeMap[nodeIndex].Addr,
cmd.FunName,
cmd.FunPara,
commStep)
if result == false {
setting.Logger.Errorf("%v:DeviceCustomCmd fail", c.CollInterface.CollInterfaceName)
commState = CommunicationState_Stop
} else {
commState = CommunicationState_Send
commStep++
}
}
}
case CommunicationState_Send:
{
//---------------发送-------------------------
c.CollInterface.CommInterface.WriteData(txBuf)
c.CollInterface.DeviceNodeMap[nodeIndex].CommTotalCnt++
setting.Logger.Debugf("%v:txbuf %X", c.CollInterface.CollInterfaceName, txBuf)
c.CommunicationManageMessageAdd("send", txBuf)
commState = CommunicationState_Wait
}
case CommunicationState_Wait:
{
//阻塞读
rxBuf := make([]byte, 256)
rxTotalBuf := make([]byte, 0)
rxBufCnt := 0
rxTotalBufCnt := 0
var timeout int
timeout, _ = strconv.Atoi(c.CollInterface.CommInterface.GetTimeOut())
timerOut := time.NewTimer(time.Duration(timeout) * time.Millisecond)
func() {
for {
select {
//继续接收数据
case rxBuf = <-c.PacketChan:
{
rxBufCnt = len(rxBuf)
if rxBufCnt > 0 {
rxTotalBufCnt += rxBufCnt
//追加接收的数据到接收缓冲区
rxTotalBuf = append(rxTotalBuf, rxBuf[:rxBufCnt]...)
//清除本次接收数据
rxBufCnt = 0
rxBuf = rxBuf[0:0]
}
}
//是否接收超时
case <-timerOut.C:
{
timerOut.Stop()
c.CommunicationManageMessageAdd("receive", rxTotalBuf)
setting.Logger.Debugf("%v:rx timeout rxbuf:%X", c.CollInterface.CollInterfaceName, rxTotalBuf)
c.CollInterface.DeviceNodeMap[nodeIndex].CurCommFailCnt++
if c.CollInterface.DeviceNodeMap[nodeIndex].CurCommFailCnt >= c.CollInterface.OfflinePeriod {
c.CollInterface.DeviceNodeMap[nodeIndex].CurCommFailCnt = 0
//设备从上线变成离线
if c.CollInterface.DeviceNodeMap[nodeIndex].CommStatus == "onLine" {
content := CollectInterfaceEventTemplate{
Topic: "offLine",
CollName: c.CollInterface.CollInterfaceName,
NodeName: c.CollInterface.DeviceNodeMap[nodeIndex].Name,
Content: c.CollInterface.DeviceNodeMap[nodeIndex].Name,
}
err := c.CollInterface.CollEventBus.Publish("offLine", content)
if err != nil {
setting.Logger.Debugf("%v:publish offLine", c.CollInterface.CollInterfaceName)
}
}
c.CollInterface.DeviceNodeMap[nodeIndex].CommStatus = "offLine"
}
rxTotalBufCnt = 0
rxTotalBuf = rxTotalBuf[0:0]
commState = CommunicationState_WaitFail
return
}
//是否正确收到数据包
case rxStatus := <-c.CollInterface.DeviceNodeMap[nodeIndex].AnalysisRx(c.CollInterface.DeviceNodeMap[nodeIndex].Addr,
c.CollInterface.DeviceNodeMap[nodeIndex].Properties, rxTotalBuf, rxTotalBufCnt):
{
timerOut.Stop()
setting.Logger.Debugf("%v:rx ok rxbuf %X", c.CollInterface.CollInterfaceName, rxTotalBuf)
rxResult.Status = rxStatus
rxResult.RxBuf = rxTotalBuf
c.CommunicationManageMessageAdd("receive", rxTotalBuf)
//设备从离线变成上线
if c.CollInterface.DeviceNodeMap[nodeIndex].CommStatus == "offLine" {
content := CollectInterfaceEventTemplate{
Topic: "onLine",
CollName: c.CollInterface.CollInterfaceName,
NodeName: c.CollInterface.DeviceNodeMap[nodeIndex].Name,
Content: c.CollInterface.DeviceNodeMap[nodeIndex].Name,
}
err := c.CollInterface.CollEventBus.Publish("onLine", content)
if err != nil {
setting.Logger.Debugf("%v: publish onLine", c.CollInterface.CollInterfaceName)
}
}
if continues == false {
content := CollectInterfaceEventTemplate{
Topic: "update",
CollName: c.CollInterface.CollInterfaceName,
NodeName: c.CollInterface.DeviceNodeMap[nodeIndex].Name,
Content: c.CollInterface.DeviceNodeMap[nodeIndex].Name,
}
err := c.CollInterface.CollEventBus.Publish("update", content)
if err != nil {
setting.Logger.Debugf("%v: publish update", c.CollInterface.CollInterfaceName)
}
}
c.CollInterface.DeviceNodeMap[nodeIndex].CommSuccessCnt++
c.CollInterface.DeviceNodeMap[nodeIndex].CurCommFailCnt = 0
c.CollInterface.DeviceNodeMap[nodeIndex].CommStatus = "onLine"
c.CollInterface.DeviceNodeMap[nodeIndex].LastCommRTC = time.Now().Format("2006-01-02 15:04:05")
rxTotalBufCnt = 0
rxTotalBuf = rxTotalBuf[0:0]
commState = CommunicationState_WaitSucess
return
}
}
}
}()
}
case CommunicationState_WaitSucess:
{
//通信帧延时
var interval int
interval, _ = strconv.Atoi(c.CollInterface.CommInterface.GetInterval())
time.Sleep(time.Duration(interval) * time.Millisecond)
commState = CommunicationState_Stop
}
case CommunicationState_WaitFail:
{
commState = CommunicationState_Stop
}
case CommunicationState_Stop:
{
return
}
}
}
}()
return rxResult
}
func (c *CommunicationManageTemplate) CommunicationStateMachineOld(cmd CommunicationCmdTemplate) CommunicationRxTemplate {
rxData := CommunicationRxTemplate{
Status: false,

View File

@ -106,7 +106,7 @@ func ReadDeviceNodeTypeMap() bool {
}
}
setting.Logger.Debugf("DeviceNodeType %v", DeviceNodeTypeMap.DeviceNodeType)
//setting.Logger.Debugf("DeviceNodeType %v", DeviceNodeTypeMap.DeviceNodeType)
index := -1
for _, f := range fileMap {
@ -118,7 +118,7 @@ func ReadDeviceNodeTypeMap() bool {
if err != nil {
setting.Logger.Errorf("openPlug %s err %v", v.Name(), err)
} else {
setting.Logger.Debugf("openPlug %s ok", f.Name())
//setting.Logger.Debugf("openPlug %s ok", f.Name())
}
for k, d := range DeviceNodeTypeMap.DeviceNodeType {
if d.TemplateType == v.Name() {
@ -146,7 +146,7 @@ func ReadDeviceNodeTypeMap() bool {
setting.Logger.Errorf("%s Lua DoFile err, %v", fileFullName, err)
return false
} else {
setting.Logger.Debugf("%s Lua DoFile ok", f.Name())
//setting.Logger.Debugf("%s Lua DoFile ok", f.Name())
}
}
}

View File

@ -1648,9 +1648,13 @@ func apiDeleteDeviceTSLProperties(context *gin.Context) {
n, _ := context.Request.Body.Read(bodyBuf)
fmt.Println(string(bodyBuf[:n]))
type PropertyNameTemplate struct {
Name string
}
tslInfo := &struct {
TSLName string `json:"TSLName"` // 名称
PropertyNames []string `json:"PropertyNames"` //
TSLName string `json:"TSLName"` // 名称
Properties []PropertyNameTemplate `json:"Properties"` //
}{}
err := json.Unmarshal(bodyBuf[:n], tslInfo)
@ -1681,7 +1685,11 @@ func apiDeleteDeviceTSLProperties(context *gin.Context) {
return
}
_, err = device.DeviceTSLMap[index].DeviceTSLPropertiesDelete(tslInfo.PropertyNames)
propertyNames := make([]string, 0)
for _, v := range tslInfo.Properties {
propertyNames = append(propertyNames, v.Name)
}
_, err = device.DeviceTSLMap[index].DeviceTSLPropertiesDelete(propertyNames)
if err != nil {
aParam.Code = "1"
aParam.Message = err.Error()

View File

@ -1 +1 @@
{"NetworkParam":[{"Name":"en0","DHCP":"1","IP":"","Netmask":"1","Broadcast":"","Gateway":"","MAC":""},{"Name":"en1","DHCP":"1","IP":"","Netmask":"1","Broadcast":"","Gateway":"","MAC":""}]}
{"NetworkParam":[{"Name":"en0","DHCP":"1","IP":"192.168.1.103","Netmask":"255.255.255.0","Broadcast":"","Gateway":"","MAC":"34363BCA1A10"},{"Name":"en1","DHCP":"1","IP":"","Netmask":"","Broadcast":"","Gateway":"","MAC":"820F20971EC0"}]}