github.com/simpleiot/simpleiot@v0.18.3/node/modbus-node.go (about)

     1  package node
     2  
     3  import (
     4  	"errors"
     5  	"fmt"
     6  	"strconv"
     7  
     8  	"github.com/simpleiot/simpleiot/data"
     9  )
    10  
    11  // ModbusNode is the node data from the database
    12  type ModbusNode struct {
    13  	nodeID             string
    14  	busType            string
    15  	protocol           string
    16  	uri                string
    17  	id                 int // only used for server
    18  	portName           string
    19  	debugLevel         int
    20  	baud               int
    21  	pollPeriod         int
    22  	disabled           bool
    23  	errorCount         int
    24  	errorCountCRC      int
    25  	errorCountEOF      int
    26  	errorCountReset    bool
    27  	errorCountCRCReset bool
    28  	errorCountEOFReset bool
    29  }
    30  
    31  // NewModbusNode converts a node to ModbusNode data structure
    32  func NewModbusNode(node data.NodeEdge) (*ModbusNode, error) {
    33  	ret := ModbusNode{
    34  		nodeID: node.ID,
    35  	}
    36  
    37  	var ok bool
    38  
    39  	ret.busType, ok = node.Points.Text(data.PointTypeClientServer, "")
    40  	if !ok {
    41  		return nil, errors.New("Must define modbus client/server")
    42  	}
    43  
    44  	ret.protocol, ok = node.Points.Text(data.PointTypeProtocol, "")
    45  	if !ok {
    46  		return nil, errors.New("Must define modbus protocol")
    47  	}
    48  
    49  	if ret.protocol == data.PointValueRTU {
    50  		ret.portName, ok = node.Points.Text(data.PointTypePort, "")
    51  		if !ok {
    52  			return nil, errors.New("Must define modbus port name")
    53  		}
    54  
    55  		baud, ok := node.Points.Text(data.PointTypeBaud, "")
    56  		if !ok {
    57  			return nil, errors.New("Must define modbus baud")
    58  		}
    59  
    60  		var err error
    61  		ret.baud, err = strconv.Atoi(baud)
    62  
    63  		if err != nil {
    64  			return nil, fmt.Errorf("Invalid baud: %v", baud)
    65  		}
    66  	}
    67  
    68  	if ret.protocol == data.PointValueTCP {
    69  		switch ret.busType {
    70  		case data.PointValueClient:
    71  			ret.uri, ok = node.Points.Text(data.PointTypeURI, "")
    72  			if !ok {
    73  				return nil, errors.New("Must define modbus URI")
    74  			}
    75  		case data.PointValueServer:
    76  			ret.portName, ok = node.Points.Text(data.PointTypePort, "")
    77  			if !ok {
    78  				return nil, errors.New("Must define modbus port name")
    79  			}
    80  		default:
    81  			return nil, fmt.Errorf("Invalid bus type: %v", ret.busType)
    82  		}
    83  	}
    84  
    85  	ret.pollPeriod, ok = node.Points.ValueInt(data.PointTypePollPeriod, "")
    86  	if ret.busType == data.PointValueClient && !ok {
    87  		return nil, errors.New("Must define modbus polling period for client devices")
    88  	}
    89  
    90  	ret.debugLevel, _ = node.Points.ValueInt(data.PointTypeDebug, "")
    91  	ret.disabled, _ = node.Points.ValueBool(data.PointTypeDisabled, "")
    92  	ret.errorCount, _ = node.Points.ValueInt(data.PointTypeErrorCount, "")
    93  	ret.errorCountCRC, _ = node.Points.ValueInt(data.PointTypeErrorCountCRC, "")
    94  	ret.errorCountEOF, _ = node.Points.ValueInt(data.PointTypeErrorCountEOF, "")
    95  	ret.errorCountReset, _ = node.Points.ValueBool(data.PointTypeErrorCountReset, "")
    96  	ret.errorCountCRCReset, _ = node.Points.ValueBool(data.PointTypeErrorCountCRCReset, "")
    97  	ret.errorCountEOFReset, _ = node.Points.ValueBool(data.PointTypeErrorCountEOFReset, "")
    98  
    99  	if ret.busType == data.PointValueServer {
   100  		var ok bool
   101  		ret.id, ok = node.Points.ValueInt(data.PointTypeID, "")
   102  		if !ok {
   103  			return nil, errors.New("Must define modbus ID for server bus")
   104  		}
   105  	}
   106  
   107  	return &ret, nil
   108  }