changeset 1235:d8aa414f21d9

py3, rfid-console rename Ignore-this: 1b28d912e8847685a87c0c9ccb703608 darcs-hash:1812ff3e65cffea158d10f03e565942a684b4bd4
author drewp <drewp@bigasterisk.com>
date Sun, 07 Apr 2019 03:58:51 -0700
parents c02ac623e593
children 7364c259de8a
files service/rfid_pn532_py/Dockerfile.pi service/rfid_pn532_py/Dockerfile.x86 service/rfid_pn532_py/index.html service/rfid_pn532_py/makefile service/rfid_pn532_py/requirements.txt service/rfid_pn532_py/rfid-console.html service/rfid_pn532_py/rfid.py service/rfid_pn532_py/tags.py
diffstat 8 files changed, 76 insertions(+), 37 deletions(-) [+]
line wrap: on
line diff
--- a/service/rfid_pn532_py/Dockerfile.pi	Sun Apr 07 03:58:05 2019 -0700
+++ b/service/rfid_pn532_py/Dockerfile.pi	Sun Apr 07 03:58:51 2019 -0700
@@ -1,13 +1,13 @@
 FROM bang6:5000/base_pi
 
 WORKDIR /opt
-RUN apt-get install -y libnfc5 libfreefare0 libnfc-dev libfreefare-dev 
-RUN apt-get install -y python3-nose2
+RUN apt-get install -y libnfc5 libfreefare0 libnfc-dev libfreefare-dev python3-nose2 libffi-dev
 COPY pyfreefare-build-pi ./pyfreefare-build
 
 COPY requirements.txt .
-RUN pip3 install -r requirements.txt
-RUN pip3 install -v -U 'https://github.com/drewp/cyclone/archive/python3.zip'
+RUN pip3 install -Ur requirements.txt
+# not sure why this doesn't work from inside requirements.txt
+RUN pip3 install -U 'https://github.com/drewp/cyclone/archive/python3.zip'
 
 COPY *.py *.html  ./
 
--- a/service/rfid_pn532_py/Dockerfile.x86	Sun Apr 07 03:58:05 2019 -0700
+++ b/service/rfid_pn532_py/Dockerfile.x86	Sun Apr 07 03:58:51 2019 -0700
@@ -7,6 +7,7 @@
 
 COPY requirements.txt .
 RUN pip3 install -r requirements.txt
+# not sure why this doesn't work from inside requirements.txt
 RUN pip3 install -U 'https://github.com/drewp/cyclone/archive/python3.zip'
 
 COPY *.py *.html  ./
--- a/service/rfid_pn532_py/index.html	Sun Apr 07 03:58:05 2019 -0700
+++ b/service/rfid_pn532_py/index.html	Sun Apr 07 03:58:51 2019 -0700
@@ -31,8 +31,26 @@
      };
     </script>
     <link rel="import" href="rfid-console.html">
+    <style>
+     .served-resources {
+         margin-top: 4em;
+         border-top: 1px solid gray;
+         padding-top: 1em;
+     }
+     .served-resources a {
+         padding-right: 2em;
+     }
+    </style>
   </head>
   <body>
-    <rfid-control></rfid-control>
+    <rfid-console></rfid-console>
+
+    <div class="served-resources">
+      <a href="stats/">/stats/</a>
+      <a href="graph">/graph</a>
+      <a href="graph/events">/graph/events</a>
+      <a href="output" >(post) /output</a>
+      <a href="rewrite">(post) /rewrite</a>
+    </div>
   </body>
 </html>
--- a/service/rfid_pn532_py/makefile	Sun Apr 07 03:58:05 2019 -0700
+++ b/service/rfid_pn532_py/makefile	Sun Apr 07 03:58:51 2019 -0700
@@ -37,12 +37,14 @@
 	docker push bang6:5000/$(SERVICE)_pi:latest
 
 run_local_x86: build_image_x86
-	docker run -it --rm --privileged --net=host --cap-add=SYS_PTRACE --name $(JOB)_run bang6:5000/$(SERVICE)_x86:latest python3 rfid.py -v 
+	docker run -it --rm --privileged --net=host --hostname=testhost --cap-add=SYS_PTRACE --name $(JOB)_run bang6:5000/$(SERVICE)_x86:latest python3 rfid.py -v
 
 
 # test on pi:
 # docker pull bang6:5000/rfid_pn532_py_pi:latest && docker run -it --rm --privileged --name rfid_shell bang6:5000/rfid_pn532_py_pi:latest nose2-3 tags_test
 
-redeploy: build_image_pi
+fresh_sudo:
+	sudo -v
+redeploy: fresh_sudo build_image_pi
 	sudo /my/proj/ansible/playbook -l $(RUNHOST) -t rfid
 	supervisorctl -s http://$(RUNHOST):9001/ restart $(JOB)_$(PORT)
--- a/service/rfid_pn532_py/requirements.txt	Sun Apr 07 03:58:05 2019 -0700
+++ b/service/rfid_pn532_py/requirements.txt	Sun Apr 07 03:58:51 2019 -0700
@@ -1,7 +1,7 @@
-cyclone
 docopt
 rdflib-jsonld==0.4.0
 rdflib==4.2.2
 https://projects.bigasterisk.com/rdfdb/rdfdb-0.7.0.tar.gz
 git+http://github.com/drewp/scales.git@448d59fb491b7631877528e7695a93553bfaaa93#egg=scales
-
+influxdb==3.0.0
+https://github.com/drewp/cyclone/archive/python3.zip
--- a/service/rfid_pn532_py/rfid-console.html	Sun Apr 07 03:58:05 2019 -0700
+++ b/service/rfid_pn532_py/rfid-console.html	Sun Apr 07 03:58:51 2019 -0700
@@ -4,7 +4,7 @@
 <link rel="import" href="/rdf/rdf-uri.html">
 <link rel="import" href="/rdf/streamed-graph.html">
 
-<dom-module id="rfid-control">
+<dom-module id="rfid-console">
   <style>
    button {
        min-width: 60px;
@@ -19,14 +19,10 @@
    }
   </style>
   <template>
-    <div>
-      <streamed-graph url="graph/events" graph="{{graph}}"></streamed-graph>
-      <!-- also get a graph of users so we can look up cards -->
-    </div>
     
     <iron-ajax id="rewrite" url="rewrite" method="POST"></iron-ajax>
     
-    Current reads: 
+    Current RFID reads: 
     <table>
       <tr><th>Card UID</th><th>Card text</th><th></th></tr>
       <template is="dom-repeat" items="{{currentReads}}">
@@ -41,11 +37,15 @@
         </tr>
       </template>
     </table>
-    
+
+    <div>
+      <streamed-graph url="graph/events" graph="{{graph}}"></streamed-graph>
+      <!-- also get a graph of users so we can look up cards -->
+    </div>
   </template>
   <script>
    Polymer({
-     is: 'rfid-control',
+     is: 'rfid-console',
      properties: {
        graph: { type: Object, notify: true, observer: "_onGraph" },
        currentReads: { type: Array, value: [] },
--- a/service/rfid_pn532_py/rfid.py	Sun Apr 07 03:58:05 2019 -0700
+++ b/service/rfid_pn532_py/rfid.py	Sun Apr 07 03:58:51 2019 -0700
@@ -6,7 +6,7 @@
 from patchablegraph import PatchableGraph, CycloneGraphHandler, CycloneGraphEventsHandler
 from rdflib import Namespace, URIRef, Literal, Graph
 from rdflib.parser import StringInputSource
-from twisted.internet import reactor, task
+from twisted.internet import reactor, task, defer
 import cyclone.web
 from cyclone.httpclient import fetch
 import cyclone
@@ -14,14 +14,16 @@
 from logsetup import log, enableTwistedLog
 from greplin import scales
 from greplin.scales.cyclonehandler import StatsHandler
+from export_to_influxdb import InfluxExporter
 from tags import NfcDevice, FakeNfc
 
 ROOM = Namespace('http://projects.bigasterisk.com/room/')
 
 ctx = ROOM['frontDoorWindowRfidCtx']
 
-STATS = scales.collection('/web',
+STATS = scales.collection('/root',
                           scales.PmfStat('cardReadPoll'),
+                          scales.IntStat('newCardReads'),
 )
 
 class OutputPage(cyclone.web.RequestHandler):
@@ -96,7 +98,7 @@
         self.overwrite_any_tag = overwrite_any_tag
         self.log = {} # cardIdUri : most recent seentime
 
-        self.pollPeriodSecs = 5.1
+        self.pollPeriodSecs = .1
         self.expireSecs = 5
         
         task.LoopingCall(self.poll).start(self.pollPeriodSecs)
@@ -107,25 +109,29 @@
 
         self.flushOldReads(now)
 
-        for tag in self.reader.getTags(): # blocks for a bit
-            uid = tag.uid()
-            log.debug('detected tag uid=%r', uid)
-            cardIdUri = uidUri(uid)
+        try:
+            for tag in self.reader.getTags(): # blocks for a bit
+                uid = tag.uid()
+                log.debug('detected tag uid=%r', uid)
+                cardIdUri = uidUri(uid)
 
-            is_new = cardIdUri not in self.log
-            self.log[cardIdUri] = now
-            if is_new:
-                tag.connect()
-                try:
-                    textLit = Literal(tag.readBlock(1).rstrip('\x00'))
-                    if self.overwrite_any_tag and not looksLikeBigasterisk(textLit):
-                        log.info("block 1 was %r; rewriting it", textLit)
-                        tag.writeBlock(1, randomBody())
+                is_new = cardIdUri not in self.log
+                self.log[cardIdUri] = now
+                if is_new:
+                    STATS.newCardReads += 1
+                    tag.connect()
+                    try:
                         textLit = Literal(tag.readBlock(1).rstrip('\x00'))
-                finally:
-                    tag.disconnect()
-                self.startCardRead(cardIdUri, textLit)
-        
+                        if self.overwrite_any_tag and not looksLikeBigasterisk(textLit):
+                            log.info("block 1 was %r; rewriting it", textLit)
+                            tag.writeBlock(1, randomBody())
+                            textLit = Literal(tag.readBlock(1).rstrip('\x00'))
+                    finally:
+                        tag.disconnect()
+                    self.startCardRead(cardIdUri, textLit)
+        except OSError as e:
+            log.error(e)
+            reactor.stop()
     def flushOldReads(self, now):
         for uri in list(self.log):
             if self.log[uri] < now - self.expireSecs:
@@ -186,6 +192,15 @@
     masterGraph = PatchableGraph()
     reader = NfcDevice() if not arg['-n'] else FakeNfc()
 
+    ie=InfluxExporter(Graph())
+    ie.exportStats(STATS, ['root.cardReadPoll.count',
+                           'root.cardReadPoll.95percentile',
+                           'root.newCardReads',
+                       ],
+                    period_secs=10,
+                    retain_days=7,
+    )
+
     loop = ReadLoop(reader, masterGraph, overwrite_any_tag=arg['--overwrite_any_tag'])
 
     port = 10012
--- a/service/rfid_pn532_py/tags.py	Sun Apr 07 03:58:05 2019 -0700
+++ b/service/rfid_pn532_py/tags.py	Sun Apr 07 03:58:51 2019 -0700
@@ -18,6 +18,7 @@
         conn_strings = (nfc.nfc_connstring * 10)()
         t0, _, t2 = nfc.nfc_list_devices.argtypes
         nfc.nfc_list_devices.argtypes = [t0, type(conn_strings), t2]
+        log.info("nfc_list_devices:")
         devices_found = nfc.nfc_list_devices(self.context, conn_strings, 10)
         log.info(f'{devices_found} connection strings')
         for i in range(devices_found):
@@ -38,6 +39,8 @@
     def getTags(self):
         log.debug("getting tags")
         t0 = time.time()
+        # see https://github.com/nfc-tools/libfreefare/blob/master/libfreefare/freefare.c
+        # for how this might waste time on felica tags
         ret = freefare.freefare_get_tags(self.dev)
         if not ret:
             raise IOError("freefare_get_tags returned null")