Advertisement
Guest User

Untitled

a guest
Jan 25th, 2012
137
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
PHP 5.63 KB | None | 0 0
  1. #!/usr/bin/env python
  2.  
  3. # pfh 6/15/09
  4. # Starting from http://itamarst.org/writings/etech04/twisted_internet-22.html
  5. # Goal: Listen to arduino, save data in engineering units, to CSV, also present
  6. # in twisted.web or similar. Socket server?
  7. #
  8. # Design: For now, have arduino send raw ADC counts over and we'll do the
  9. # calibration - seems smarter. I can then use config file parser to move
  10. # all the constants into a config file.
  11. #
  12. # I really want something like rrdtool-based graphs with different timescales.
  13. # Maybe graphite?
  14. # http://somic.org/2009/05/21/graphite-rabbitmq-integration/
  15. # Or even AMQP for fun?
  16. # Serial code from http://twistedmatrix.com/projects/core/documentation/examples/gpsfix.py
  17.  
  18. from twisted.internet import win32eventreactor
  19. win32eventreactor.install()
  20.  
  21. from twisted.protocols.basic import LineReceiver
  22.  
  23. from twisted.internet import reactor
  24. from twisted.internet.serialport import SerialPort
  25. from twisted.web import server, resource, client
  26. from twisted.web.server import Site
  27. from twisted.web.static import File
  28.  
  29. from twisted.python import usage
  30. from twisted.python import log
  31. import sys
  32. import time
  33.  
  34. ## import stuff from Autobahn
  35. ##
  36. from autobahn.websocket import listenWS
  37. from autobahn.wamp import WampServerFactory, WampServerProtocol, exportRpc
  38.  
  39. print "using Twisted reactor", reactor.__class__
  40. print
  41.  
  42.  
  43. lastTemp = 0.0
  44. lastRH = 0.0
  45. lastTimestamp = 0
  46.  
  47. class THOptions(usage.Options):
  48.     optParameters = [
  49.         ['baudrate', 'b', 9600, 'Serial baudrate'],
  50.         ['port', 'p', 3, 'Serial port to use'],
  51.         ]
  52.  
  53. class indexPage(resource.Resource):
  54.     isLeaf = True
  55.  
  56.     def render_GET(self, request):
  57.         ccStr = ' Temp:%f Humidity:%f\n' % (lastTemp, lastRH)
  58.         return ccStr
  59.  
  60.  
  61. ## MCU protocol
  62. ##
  63. class McuProtocol(LineReceiver):
  64.  
  65.     ## need a reference to our WS-MCU gateway factory to dispatch PubSub events
  66.    ##
  67.    def __init__(self, wsMcuFactory):
  68.         self.wsMcuFactory = wsMcuFactory
  69.  
  70.     @exportRpc("control-led")
  71.     def controlLed(self, status):
  72.         ## use self.transport.write to send control to MCU via serial
  73.        ##
  74.        if status:
  75.             print "turn on LED"
  76.         else:
  77.             print "turn off LED"
  78.  
  79.     def processData(self, data):
  80.         """Convert raw ADC counts into SI units as per datasheets"""
  81.         # Skip bad reads
  82.        if len(data) != 2:
  83.             return
  84.  
  85.         global lastTemp, lastRH, lastTimestamp
  86.  
  87.         tempCts = int(data[0])
  88.         rhCts = int(data[1])
  89.  
  90.         rhVolts = rhCts * 0.0048828125
  91.         # 10mV/degree, 1024 count/5V
  92.        temp = tempCts * 0.48828125
  93.         # RH temp correction is -0.7% per deg C
  94.        rhcf = (-0.7 * (temp - 25.0)) / 100.0
  95.  
  96.         # Uncorrected humidity
  97.        humidity = (rhVolts * 45.25) - 42.76
  98.  
  99.         # Add correction factor
  100.        humidity = humidity + (rhcf * humidity)
  101.  
  102.  
  103.         lastTemp = tempCts
  104.         lastRH = rhCts
  105.         #lastTemp = temp
  106.        #lastRH = humidity
  107.        # Update screen now and then
  108.        if (time.time() - lastTimestamp) > 20.0:
  109.  
  110.             ## dispatch Temp/Humidity as a PubSub event to all clients subscribed to
  111.            ## topic http://example.com/mcu#measure1
  112.            ##
  113.            self.wsMcuFactory._dispatchEvent("http://example.com/mcu#measure1", (temp, humidity))
  114.  
  115.             log.msg('Temp: %f C Relative humidity: %f %%' % (temp, humidity))
  116.             log.msg('Temp: %f counts: %d RH: %f counts: %d volts: %f' % (temp, tempCts, humidity, rhCts, rhVolts))
  117.             lastTimestamp = time.time()
  118.  
  119.         return temp, humidity
  120.  
  121.     def connectionMade(self):
  122.         log.msg('Serial connection made!')
  123.  
  124.     def lineReceived(self, line):
  125.         try:
  126.             data = line.split()
  127.             log.msg(data)
  128.             self.processData(data)
  129.         except ValueError:
  130.             log.err('Unable to parse data %s' % line)
  131.             return
  132.  
  133.  
  134. ## WS-MCU protocol
  135. ##
  136. class WsMcuProtocol(WampServerProtocol):
  137.  
  138.     def onSessionOpen(self):
  139.         ## register topic under which we will publish MCU measurements
  140.        ##
  141.        self.registerForPubSub("http://example.com/mcu#", True)
  142.  
  143.         ## register methods for RPC
  144.        ##
  145.        self.registerForRpc(self.factory.mcuProtocol, "http://example.com/mcu-control#")
  146.  
  147.  
  148. ## WS-MCU factory
  149. ##
  150. class WsMcuFactory(WampServerFactory):
  151.  
  152.     protocol = WsMcuProtocol
  153.  
  154.     def __init__(self, url):
  155.         WampServerFactory.__init__(self, url)
  156.         self.mcuProtocol = McuProtocol(self)
  157.  
  158.     def pubKeepAlive(self):
  159.         self.keepAlive += 1
  160.         self._dispatchEvent("http://example.com/mcu#keepalive", self.keepAlive)
  161.         reactor.callLater(1, self.pubKeepAlive)
  162.  
  163.     def startFactory(self):
  164.         WampServerFactory.startFactory(self)
  165.         self.keepAlive = 0
  166.         self.pubKeepAlive()
  167.  
  168.  
  169. if __name__ == '__main__':
  170.  
  171.     log.startLogging(sys.stdout)
  172.  
  173.     ## create MCU-WS gateway factory/protocol
  174.    ##
  175.    wsMcuFactory = WsMcuFactory("ws://localhost:9000")
  176.     listenWS(wsMcuFactory)
  177.  
  178.     o = THOptions()
  179.     try:
  180.         o.parseOptions()
  181.     except usage.UsageError, errortext:
  182.         log.err('%s %s' % (sys.argv[0], errortext))
  183.         log.msg('Try %s --help for usage details' % sys.argv[0])
  184.         raise SystemExit, 1
  185.  
  186.     if o.opts['baudrate']:
  187.         baudrate = int(o.opts['baudrate'])
  188.  
  189.     port = o.opts['port']
  190.  
  191.     log.msg('About to open port %s' % port)
  192.     s = SerialPort(wsMcuFactory.mcuProtocol, port, reactor, baudrate=baudrate)
  193.  
  194.     ## embedded web server for static files
  195.    ##
  196.    webdir = File(".")
  197.     web = Site(webdir)
  198.     reactor.listenTCP(2000, web)
  199.  
  200.     reactor.run()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement