# HG changeset patch # User drewp@bigasterisk.com # Date 1555828419 25200 # Node ID cebc0134254ae97965bfc7687e0263eafa22b78d # Parent 7051b8b4766a1e6862db6fa238ceec8556712f79 last version of rc522 reader; i moved onto pn532 now Ignore-this: 37d50691ffec46f984a66c185cc27445 diff -r 7051b8b4766a -r cebc0134254a service/rfid/index.html --- a/service/rfid/index.html Sat Apr 20 23:32:36 2019 -0700 +++ b/service/rfid/index.html Sat Apr 20 23:33:39 2019 -0700 @@ -1,14 +1,128 @@ - + rfid + + + + + + + + + + + - - Current read: graph.sensor.card graph.sensor.card.text + + + + + + diff -r 7051b8b4766a -r cebc0134254a service/rfid/requirements.txt --- a/service/rfid/requirements.txt Sat Apr 20 23:32:36 2019 -0700 +++ b/service/rfid/requirements.txt Sat Apr 20 23:33:39 2019 -0700 @@ -1,6 +1,7 @@ cyclone +docopt rdflib-jsonld==0.4.0 rdflib==4.2.2 -https://projects.bigasterisk.com/rdfdb/rdfdb-0.6.0.tar.gz -https://github.com/drewp/MFRC522-python/archive/drewp/m4.zip - +https://projects.bigasterisk.com/rdfdb/rdfdb-0.7.0.tar.gz +https://github.com/drewp/MFRC522-python/archive/877f5568627b5e67d622c08191aae0f4ffd6dd32.zip +git+http://github.com/drewp/scales.git@448d59fb491b7631877528e7695a93553bfaaa93#egg=scales diff -r 7051b8b4766a -r cebc0134254a service/rfid/rfid.py --- a/service/rfid/rfid.py Sat Apr 20 23:32:36 2019 -0700 +++ b/service/rfid/rfid.py Sat Apr 20 23:33:39 2019 -0700 @@ -6,14 +6,25 @@ from twisted.internet import reactor, task import cyclone.web from cyclone.httpclient import fetch -import logging, time +import logging, time, json, random, string from MFRC522.SimpleMFRC522 import SimpleMFRC522 from logsetup import log, enableTwistedLog +import private +from greplin import scales +from greplin.scales.cyclonehandler import StatsHandler ROOM = Namespace('http://projects.bigasterisk.com/room/') ctx = ROOM['frontDoorWindowRfidCtx'] +cardOwner = { + URIRef('http://bigasterisk.com/rfidCard/93a7591a77'): + URIRef('http://bigasterisk.com/foaf.rdf#drewp'), +} + +STATS = scales.collection('/web', + scales.PmfStat('cardReadPoll'), +) def rdfGraphBody(body, headers): g = Graph() g.parse(StringInputSource(body), format='nt') @@ -41,6 +52,36 @@ return log.warn("ignoring %s", stmt) +def uidUri(card_id): + return URIRef('http://bigasterisk.com/rfidCard/%010x' % card_id) + +def uidArray(uri): + prefix, h = uri.rsplit('/', 1) + if prefix != 'http://bigasterisk.com/rfidCard': + raise ValueError(uri) + return [int(h[i * 2: i * 2 + 2], 16) for i in range(0, len(h), 2)] + +class Rewrite(cyclone.web.RequestHandler): + def post(self): + agent = URIRef(self.request.headers['x-foaf-agent']) + body = json.loads(self.request.body) + + _, uid = reader.read_id() + log.info('current card id: %r %r', _, uid) + if uid is None: + self.set_status(404, "no card present") + # maybe retry a few more times since the card might be nearby + return + + text = ''.join(random.choice(string.uppercase) for n in range(32)) + log.info('%s rewrites %s to %s, to be owned by %s', + agent, uid, text, body['user']) + + #reader.KEY = private.rfid_key + reader.write(uid, text) + log.info('done with write') + + sensor = ROOM['frontDoorWindowRfid'] class ReadLoop(object): @@ -49,22 +90,25 @@ self.masterGraph = masterGraph self.log = {} # cardIdUri : most recent seentime - self.pollPeriodSecs = .2 + self.pollPeriodSecs = .1 self.expireSecs = 2 task.LoopingCall(self.poll).start(self.pollPeriodSecs) - + + @STATS.cardReadPoll.time() def poll(self): now = time.time() self.flushOldReads(now) card_id, text = self.reader.read() - if card_id is None: + if card_id is None or text == '': + # text=='' could be legit, but it's probably a card that's + # still being read. return - cardIdUri = URIRef('http://bigasterisk.com/rfidCard/%s' % card_id) - textLit = Literal(text.rstrip()) + cardIdUri = uidUri(card_id) + textLit = Literal(text.rstrip().decode('ascii', 'replace')) is_new = cardIdUri not in self.log self.log[cardIdUri] = now @@ -79,16 +123,20 @@ def startCardRead(self, cardUri, text): p = Patch(addQuads=[(sensor, ROOM['reading'], cardUri, ctx), - (cardUri, ROOM['cardText'], text, ctx)], delQuads=[]) + (cardUri, ROOM['cardText'], text, ctx)], + delQuads=[]) self.masterGraph.patch(p) + log.info('read card: id=%s %r', cardUri, str(text)) self._sendOneshot([(sensor, ROOM['startReading'], cardUri), (cardUri, ROOM['cardText'], text)]) def endCardRead(self, cardUri): delQuads = [] - for spo in self.masterGraph._graph.triples((sensor, ROOM['reading'], cardUri)): + for spo in self.masterGraph._graph.triples( + (sensor, ROOM['reading'], cardUri)): delQuads.append(spo + (ctx,)) - for spo in self.masterGraph._graph.triples((cardUri, ROOM['cardText'], None)): + for spo in self.masterGraph._graph.triples( + (cardUri, ROOM['cardText'], None)): delQuads.append(spo + (ctx,)) self.masterGraph.patch(Patch(addQuads=[], delQuads=delQuads)) @@ -121,7 +169,7 @@ log.setLevel(logging.DEBUG) masterGraph = PatchableGraph() - reader = SimpleMFRC522() + reader = SimpleMFRC522(gain=0x07) loop = ReadLoop(reader, masterGraph) @@ -133,6 +181,8 @@ (r"/graph/events", CycloneGraphEventsHandler, {'masterGraph': masterGraph}), (r'/output', OutputPage), + (r'/rewrite', Rewrite), + (r'/stats/(.*)', StatsHandler, {'serverName': 'rfid'}), ], masterGraph=masterGraph, debug=arg['-v']), interface='::') log.warn('serving on %s', port)