イーサネット (modbus/TCP) 経由で接続されたデバイスからデータを受信し、それを Web ページに送信する必要があります (おそらく Web ソケットを使用)。
良い例が見つかりません。これで、ドライバーに接続して値を出力ModbusClientProtocol.read_input_registers()
できますが、独自のファクトリとプロトコル クラスを作成する必要がありました。私はautobahn、twisted、pymodbusを使用しています。
イーサネット (modbus/TCP) 経由で接続されたデバイスからデータを受信し、それを Web ページに送信する必要があります (おそらく Web ソケットを使用)。
良い例が見つかりません。これで、ドライバーに接続して値を出力ModbusClientProtocol.read_input_registers()
できますが、独自のファクトリとプロトコル クラスを作成する必要がありました。私はautobahn、twisted、pymodbusを使用しています。
私は modbus や pymodbus に精通していないので、推測して多くの空白を残しておきます。
これは、snmptrap を受信し、接続された WebSocket に情報を再配布するために最近まとめたものからハッキングされたものです。
うまくいけば、これで十分です。
#!/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, e.g. 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()
物事のブラウザ側で。Websocket と対話するための小さなモジュールが便利です。
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 )
}
}
};
次に、ブラウザ コンソールで次の操作を行います。
conn = new FancyWebSocket("ws://yourhostname/ws");