Cómo leer datos de forma asíncrona a través de modbus / TCP y enviarlos a la web

Necesito recibir datos del dispositivo conectado a través de Ethernet (modbus / TCP) y enviarlos a la página web (tal vez utilizando sockets web).

No puedo encontrar buenos ejemplos. Ahora puedo conectarme con el controlador e imprimir valores utilizando ModbusClientProtocol.read_input_registers() pero tuve que crear mi propia clase de protocolo y fábrica. Estoy usando autobahn, twisted, pymodbus.

No estoy familiarizado con modbus o pymodbus, así que estoy adivinando y dejando muchos espacios en blanco para que los llene.

Esto se ha eliminado de algo que recientemente reuní para recibir snmptraps y redistribuir la información a los websockets conectados.

Esperemos que esto sea suficiente para que te vayas:

 #!/usr/bin/python from twisted.internet import protocol, reactor, utils, defer from twisted.web.server import Site from twisted.web.static import File from autobahn.websocket import WebSocketServerFactory, WebSocketServerProtocol from autobahn.util import newid from autobahn.resource import WebSocketResource class ModbusThing(object): def __init__(self,clientAddress): self.clientAddress = clientAddress self.client = None def start(self): pass ## Create client connection to modbus server ## Start Looping Call of pollForData with suitable interval def pollForData(self): pass ## Call read methods on ModbusClient object, add call backs to process the results ## Add errorBacks to notify of errors def resultCallback(self,result): pass ## Process the data from a read request ## Assumes that your websocket clients expect json like {"event":"update","data":[0,1,2]} message = dict(event="update",data=processedResults) self.broadcast(json.dumps(message)) def broadcast(self,msg): """Override me""" pass class TrackingWebSocketProtocol(WebSocketServerProtocol): def onOpen(self): self.session_id = newid() self.factory._addSession(self,self.session_id) print "Socket Open %s" % (self.peerstr,) def onMessage(self,payload,isBinary): print "Message received from %s\n\t: %r" % (self.peerstr,payload) def onClose(self,wasClean,code,reason): self.factory._removeSession(self) print "Socket Closed %s" % (self.peerstr,) class TrackingWebSocketFactory(WebSocketServerFactory): def __init__(self,*args,**kwargs): WebSocketServerFactory.__init__(self,*args,**kwargs) self.proto2session = {} self.session2proto = {} def _addSession(self,proto,session_id): if not self.proto2session.has_key(proto): self.proto2session[proto] = session_id else: raise Exception("logic error - dublicate _addSession for protoToSessions") if not self.session2proto.has_key(session_id): self.session2proto[session_id] = proto else: raise Exception("logic error - dublicate _addSession for sessionsToProto") def _removeSession(self,proto): if proto in self.proto2session: session_id = self.proto2session[proto] del self.proto2session[proto] if session_id in self.session2proto: del self.session2proto[session_id] def sendToAll(self,message,binary=False): prepped = self.prepareMessage(message,binary) for proto in self.proto2session.keys(): proto.sendPreparedMessage(prepped) def run(): ## WebSocket Factory wsfactory = TrackingWebSocketFactory('ws://yourhostname:80') wsfactory.protocol = TrackingWebSocketProtocol wsresource = WebSocketResource(wsfactory) ## Modbus handler modbus_thing = ModbusThing((addressofserver,portofserver)) modbus_thing.broadcast = wsfactory.sendToAll modbus_thing.start() ## WebServer Site # "static" subdirectory, containing http served resources, eg index.html, javascript and css root = File("static") # Your websocket service as 'ws://yourhostname/ws' root.putChild("ws", wsresource) site = Site(root) reactor.listenTCP(80,site) def main(): reactor.callWhenRunning(run) reactor.run() if __name__=='__main__': main() 

En el lado del navegador de las cosas. Un pequeño módulo para interactuar con websockets es útil:

 var FancyWebSocket = function(url){ var conn = null; var fws = this; if ("WebSocket" in window) { conn = new WebSocket(url); } else if ("MozWebSocket" in window) { conn = new MozWebSocket(url); } else { console.log("Error Websockets not supported in browser"); return; } var callbacks = {}; var debug = true; this.bind = function(event_name, callback){ callbacks[event_name] = callbacks[event_name] || []; callbacks[event_name].push(callback); return this;// chainable }; this.send = function(event_name, event_data){ var payload = JSON.stringify({event:event_name, data: event_data}); conn.send( payload ); // <= send JSON data to socket server return this; }; this.close = function(){ conn.close(); return this;} // dispatch to the right handlers conn.onmessage = function(evt){ if (debug) console.log("Websocket(" + conn.URL + ") Message: " + evt.data) var json = JSON.parse(evt.data) dispatch(json.event, json.data) }; conn.onclose = function(){ if (debug) console.log("Websocket(" + conn.URL + ") Closed"); dispatch('close',fws); } conn.onopen = function(){ if (debug) console.log("Websocket(" + conn.URL + ") Open"); dispatch('open',fws); } conn.onerror = function(e){ if (debug) console.log("Websocket(" + conn.URL + ") Error: " + error); dispatch('error',fws,e); } this.setdebug = function(v) { debug=v; return this; } var dispatch = function(event_name, message){ var chain = callbacks[event_name]; if(typeof chain == 'undefined') return; // no callbacks for this event for(var i = 0; i < chain.length; i++){ chain[i]( message ) } } }; 

Luego en la consola de tu navegador:

 conn = new FancyWebSocket("ws://yourhostname/ws");