コード例 #1
0
ファイル: milecastles.py プロジェクト: heeed/avatap
 def validate(self):
     # construct an easy dot lookup mechanism from within templates
     self.nodes = Holder(**self._get_table(Node))
     self.boxes = Holder(**self._get_table(Box))
     agnostic.collect()
     # delegate validation to nodes
     for nodeUid, node in self._get_table(Node).items():
         node.validate(self)
         agnostic.collect()
コード例 #2
0
ファイル: integration_test.py プロジェクト: heeed/avatap
def run():
    show(b"Hello world")
    while True:
        agnostic.collect()
        (stat, tag_type) = rdr.request(rdr.REQIDL)
        if stat == rdr.OK:
            (stat, raw_uid) = rdr.anticoll()
            if stat == rdr.OK:
                para = b"ID is\n0x%02x%02x%02x%02x" % (raw_uid[0], raw_uid[1],
                                                       raw_uid[2], raw_uid[3])
                show(para)
コード例 #3
0
ファイル: milecastles.py プロジェクト: heeed/avatap
def ThroughSequence(uid, nextNodeUid, goalBoxUid, sequence, **k):
    pos = len(sequence) - 1
    while pos >= 0:
        page = sequence[pos]
        if pos == 0:  # first node
            pageUid = uid  # has uid of sequence
            kwargs = k  # inherits all operators etc
        else:  # later nodes
            pageUid = uid + str(
                pos - 1)  # have uids based on first node uid + position
            kwargs = {}  # don't inherit operators etc
        ThroughPage(uid=pageUid,
                    page=page,
                    goalBoxUid=goalBoxUid,
                    nextNodeUid=nextNodeUid,
                    **kwargs)
        nextNodeUid = pageUid
        pos -= 1
        agnostic.collect()
コード例 #4
0
ファイル: avatap.py プロジェクト: heeed/avatap
def runBox(boxUid):

    host = ConsoleHost()

    agnostic.collect()
    #TODO CH remove these test lines
    screen.clear()
    font.draw_generator(generatorFactory(), plotter)
    screen.redraw()

    agnostic.collect()

    boxUid = str(boxUid) # handle case of passing a number

    boxEngine = Engine(box=story.lookupBox(boxUid))
    boxEngine.registerStory(story)
    agnostic.collect()

    while True:
        agnostic.report_collect()
        try:
            tagUid = vault.awaitPresence()
            try:
                cardDict = vault.readJson(tagUid=tagUid)
                if "storyUid" not in cardDict or cardDict["storyUid"] is not loader.storyUid:
                    cardDict = None # existing card data incompatible
            except Exception as e:
                if type(e) is KeyboardInterrupt:
                    raise e
                else:
                    print(e)
                    cardDict = None # couldn't read card for some reason

            if cardDict is not None:
                print("JSON Good")
                card = dictToCard(tagUid, cardDict)
            else:
                print("JSON Bad")
                card = story.createBlankCard(tagUid)

            agnostic.collect()

            boxEngine.handleCard(card, host)
            print("Handled Card")
            vault.writeJson(cardToDict(card), tagUid=tagUid, unselect=True)
            print("Written JSON")
            vault.awaitAbsence()
            print("Card removed")
        except AssertionError as ae:
            print(type(ae).__name__ + str(ae))
        except KeyboardInterrupt:
            break
コード例 #5
0
ファイル: engines.py プロジェクト: heeed/avatap
    def displayNode(self, node, host):
        templateName = node.getRenderedTemplateName(self)
        templateId = getTemplateId(self.story, node, templateName)
        # TODO CH consider use of string hash of the template for lazy recompilation

        useCache = sys.implementation.name == "micropython"

        generatorFactory = None
        if useCache:
            # try to load from cache
            try:
                generatorFactory = boilerplate.loadTemplateGeneratorFactory(
                    templateId)
            except ImportError as e:
                pass  # generatorFactory is still None

        # lazy - create cache if forced or cache not found
        if not (useCache) or generatorFactory is None:
            cacheTemplate(self.story, node, templateName)
            generatorFactory = boilerplate.loadTemplateGeneratorFactory(
                templateId)
        agnostic.collect()

        generator = generatorFactory(**self.getEngineContext())
        agnostic.collect()

        host.displayGeneratedText(generator)
        agnostic.collect()

        # TODO CH Note remove this block, which is not intended for final deployment
        if sys.implementation.name is not "micropython":
            maxLineLen = 25
            maxLineCount = 8

            def generator_to_string(generator):
                s = ""
                for chunk in generator:
                    s += chunk
                return s

            def check_layout(nodeUid, generator):
                s = generator_to_string(generator)
                lines = s.split("\n")
                if len(lines) > maxLineCount:
                    print()
                    print(s)
                    raise AssertionError("> {} lines in {}".format(
                        maxLineCount, nodeUid))
                for line in lines:
                    if len(line) > maxLineLen:
                        print()
                        print(line)
                        raise AssertionError("> {} chars in {}".format(
                            maxLineLen, nodeUid))

            check_layout(node.uid, generatorFactory(**self.getEngineContext()))
コード例 #6
0
ファイル: avatap.py プロジェクト: heeed/avatap
# screen /dev/ttyUSB0 115200
# from regimes.avatap import runBox; runBox("1")
import loader
loader.loadAll()
import agnostic
from faces.font_5x7 import font
from st7920 import Screen
from mfrc522 import MFRC522
from machine import Pin,SPI
from engines import dictToCard, cardToDict
from engines import Engine
from regimes.console import ConsoleHost
from vault import BankVault
#TODO CH normalise this story module info into one place (e.g. loader, or via milecastles.loadStory)
from stories.corbridge import story
agnostic.collect()

spi = SPI(1, baudrate=1000000, polarity=0, phase=0)
spi.init()
agnostic.collect()

reader = MFRC522(spi=spi, gpioRst=0, gpioCs=2)
agnostic.collect()

vault = BankVault(reader)
agnostic.collect()

screen = Screen(spi=spi, slaveSelectPin=Pin(15))
agnostic.collect()

# TODO CH remove this test function (actual plotter is in avatap engine)
コード例 #7
0
ファイル: vault_test.py プロジェクト: heeed/avatap
def show(msg):
    screen.clear()
    font.draw_para(msg, plotter)
    screen.redraw()
    collect()
コード例 #8
0
ファイル: vault_test.py プロジェクト: heeed/avatap
report_import("faces.font_5x7")
from faces.font_5x7 import font

report_import("vault")

report_import("st7920")
from st7920 import Screen
report_import("machine")
from machine import Pin, SPI

report_import("mfrc522")
from mfrc522 import MFRC522

spi = SPI(1, baudrate=1800000, polarity=0, phase=0)
spi.init()
collect()

rdr = MFRC522(spi=spi, gpioRst=0, gpioCs=2)
collect()

screen = Screen(spi=spi, slaveSelectPin=Pin(15))
collect()


def plotter(x, y):
    screen.plot(x, y)


def show(msg):
    screen.clear()
    font.draw_para(msg, plotter)
コード例 #9
0
ファイル: engines.py プロジェクト: heeed/avatap
 def evaluateExpression(self, expression):
     result = eval(expression, self.getEngineContext())
     agnostic.collect()
     return result
コード例 #10
0
ファイル: milecastles.py プロジェクト: heeed/avatap
 def __init__(self, *a, **k):
     agnostic.collect()
     for key, val in k.items():
         setattr(self, key, val)
コード例 #11
0
ファイル: console.py プロジェクト: heeed/avatap
 def run(self):
     while True:
         agnostic.collect()
         self.handleInput()
         agnostic.collect()
コード例 #12
0
    def gameLoop(self, fuzz=False):
        agnostic.collect()

        cardUid = None
        card = None

        try:  # toast and label finaliser

            toastRect = None
            labelRect = None
            if self.expectStay:
                labelRect = self.label(
                    awaitReplace
                )  # draw quickly before clearing rest of screen
                self.screen.clear()
                labelRect = self.label(awaitReplace, redraw=False)
            else:
                self.screen.clear()
                if self.resetCard:
                    toastRect = self.toast(b"RESETTING TAG!", redraw=False)
                else:
                    toastRect = self.toast(b"PLACE TAG\nto read", redraw=False)
            self.redraw()

            if self.cardCache or self.resetCard:  # block for short period
                cardUid = self.rfid.awaitPresence(PRESENCE_TIMEOUT)
            else:
                cardUid = self.rfid.awaitPresence()  # block indefinitely
            if cardUid is None:  # presence timeout was hit
                if self.cardCache is not None:
                    self.cardCache = None  # abandon resume
                if self.resetCard:
                    self.resetCard = False  # abandon reset
                return None

            if cardUid in redTags:
                self.screen.clear()
                self.redraw()
                toastRect = self.toast(b"Reset requested")
                self.expectStay = False
                self.cardCache = None
                self.resetCard = True
                self.rfid.awaitAbsence()
                return cardUid
        finally:
            if toastRect:
                self.wipeRect(toastRect)
            if labelRect:
                self.wipeRect(labelRect)

        try:  # unselect finaliser
            self.rfid.selectTag(cardUid)

            if self.resetCard and not (cardUid in redTags):
                self.resetCard = False
                card = self.story.createBlankCard(cardUid)
                self.rfid.writeCard(card=card, unselect=True)
                toastRect = self.toast(b"Reset complete")
                self.rfid.awaitAbsence()
                self.wipeRect(toastRect)
                return cardUid
            elif self.cardCache is not None:
                if cardUid == self.cardCache.uid:
                    card = self.cardCache  # resume avoiding any read
                else:
                    pass  # do not load from cache - wrong card
                self.cardCache = None  # discard cached data from previous cycle (implicitly after resumeMs)

            if card is None:
                try:
                    labelRect = self.label(b"KEEP IN PLACE, loading..")
                    agnostic.collect()
                    card = self.rfid.readCard(cardUid=cardUid, unselect=False)
                    if card.storyUid != self.story.uid or card.storyVersion != self.story.version:
                        raise CardJsonIncompatibleError(
                            "Wrong story or version")
                except CardReadIncompleteError:
                    return None  # exit the loop altogether
                except (CardBankMissingError, CardJsonInvalidError,
                        CardJsonIncompatibleError, AssertionError):
                    card = self.story.createBlankCard(
                        cardUid
                    )  # overwrite the card, read was successful but content flawed

            try:  # label finaliser
                labelRect = self.label(
                    b"KEEP IN PLACE, saving..."
                )  # TODO CH calculate location to just wipe and draw 'saving.' over 'loading'

                origNodeUid = card.nodeUid
                agnostic.collect()
                nextNode = self.engine.handleCard(card, self)

                # will next page also be at this box?
                if issubclass(
                        type(nextNode),
                        GoalPage) and nextNode.goalBoxUid == self.box.uid:
                    self.expectStay = True  # goalpage at same box
                elif nextNode.uid != origNodeUid:
                    self.expectStay = True  # remote GoalPage or NodeFork unvisited
                else:
                    self.expectStay = False  # remote GoalPage or NodeFork now visited

                try:
                    agnostic.collect()
                    self.rfid.writeCard(card=card, unselect=False)
                    self.cardCache = card
                except:
                    print("Error; discarding write. One of...")
                    print("Card identity not the intended card to be written")
                    print("Card removed before write complete")
            finally:
                self.wipeRect(labelRect)

            # TODO try this to avoid error counting in awaitAbsence (meaning two presence cycles needed to detect)
            # cardVault.reader.reset()
        finally:
            try:
                labelRect = self.label(
                    awaitLift if self.expectStay else awaitLeave, redraw=False)
                self.redraw(
                )  # TODO redraw fully as workaround for draw alignment bug which seems only to affect this message
                self.rfid.unselectTag()
                if not fuzz:  # if fuzzing, don't wait for tag lift
                    self.rfid.awaitAbsence()
                print("CARD REMOVED")
            finally:
                self.wipeRect(labelRect)

        return cardUid