MBLogic for an open world in automation
The ERP protocol is a subset of the HMI protocol which is intended to allow access for ERP/MRP (Enterprise/Manufacturing Resource Planning) applications. This protocol uses the same configuration as the conventional HMI protocol, but limits the available features, and also allows the number of tags and the type of access (read or write).
Like the HMI server, the ERP server can automatically convert types, perform scaling, and enforce data ranges.
The ERP protocol is a type of "web service protocol". A web service protocol operates over HTTP like a web page, but transfers machine readable data rather than a simple web page.
The ERP Protocol uses a subset of the HMI protocol using JSON over HTTP. JSON is a standard encoding of data for web services based on "keys" and "values".
{"key1":123, "somekey":"value", "arrayexample":[1, 2, 3]}
The basic message format consists of the following:
{ "id":"ERP Client 123.", "msgid":456, }
The basic response format contains the following:
{ "id": "HMIServer demo server", "msgid": 456, "stat": "ok", }
The read command specifies which address tags should be read. It consists of a list of the address tag names which the client wishes to read. This command is optional and can be left out if it is not needed.
{ "id":"ERP Client 123.", "msgid":456, "read" : ["Tank1Level", "WidgetCount"], }
{ "id": "HMIServer demo server", "msgid": 0, "stat": "ok", "timestamp": 1238156675.0, "read": {"Tank1Level": 9875, "WidgetCount" : 87}, }
The write command is a group of address tags and values which are to be written to the server.
{ "id":"ERP Client 123.", "msgid":456, "write" : {"Pump1Speed" : 2250}, }
{ "id":"ERP Client 123.", "msgid":456, }
Reads and writes can be combined in a single transaction.
{ "id":"ERP Client 123.", "msgid":456, "read" : ["Tank1Level", "WidgetCount"], "write" : {"Pump1Speed" : 2250}, }
{ "id": "HMIServer demo server", "msgid": 0, "stat": "ok", "timestamp": 1238156675.0, "read": {"Tank1Level": 9875, "WidgetCount" : 87}, }
Read and write errors are reported in the "readerr" and "writeerr" fields in the response. The "readerr" and "writeerr" fields are only present in the response if there is a corresponding error to report.
{ "id": "HMIServer demo server", "msgid": 9875, "stat": "commanderror", "timestamp": 1238156675.0, "writeerr": {"PBBad": "tagnotfound"} }
The ERP server uses the same tag configuration as the HMI server. However, the ERP server has the following limits on it:
Configuration syntax can be found in the section on HMI configuration, and also in the section on using the status web interface for form based configuration.
To create a custom client interface to the ERP server, you need the following:
You then need to do the following:
The following is an example ERP client written in Python.
#!/usr/bin/python # This shows a basic demo for an ERP client. # This will work with the standard HMI demo. # 29-Dec-2010. import json import urllib2 # This is the data we are going to send to the server. # We need a client id, and a message id. In addition, if we want to # read data, we need to include a list of the tags we want to read. If we want to # write data, we need to include a dictionary with the tags and values that we # want to write. basicdemo = { 'id' : 'ErpDemo', 'msgid' : 0, 'read' : ['PL1', 'PL4', 'PumpSpeedActual', 'PumpSpeedCmd', 'Tank1Level', 'Tank2Number', 'hello', 'ButtonDisPB'], 'write' : {'PB1' : 1, 'PumpSpeedCmd' : -2, 'writebad' : 777, 'SSPPGrip' : 1} } # Encode the dictionary into JSON format using the standard Python library. JsonOut = json.dumps(basicdemo) # Send the data using POST. req = urllib2.Request(url = 'http://localhost:8084/', data = JsonOut) f = urllib2.urlopen(req) # Read the response. JsonIn = f.read() # Convert from JSON into a dictionary. respdata = json.loads(JsonIn) # We will iterate through the 'read' response and show the values that we read. # The dictionary will also contain other data (such as errors) which are not # showing here. print('Read response was') readdata = respdata.get('read', {}) for tag, value in readdata.items(): print('\tTag: %s Value: %s' % (tag, value)) # Read errors. readerr = respdata.get('readerr', {}) if readerr: print('\nRead errors') for tag, value in readerr.items(): print('\tTag: %s Value: %s' % (tag, value)) # Write errors. writeerr = respdata.get('writeerr', {}) if writeerr: print('\nWrite errors') for tag, value in writeerr.items(): print('\tTag: %s Value: %s' % (tag, value))
The output from the above is (when used with the standard HMI demo configuration):
Read response was Tag: PumpSpeedActual Value: 5 Tag: PL4 Value: 0 Tag: PumpSpeedCmd Value: -2 Tag: PL1 Value: 1 Tag: Tank2Number Value: 75.0 Tag: Tank1Level Value: 70 Read errors Tag: ButtonDisPB Value: accessdenied Tag: hello Value: tagnotfound Write errors Tag: SSPPGrip Value: accessdenied Tag: writebad Value: tagnotfound