Stap 6: imPrinter: wat zit er in de code?
Onze apparaat firmware begint met de klassendefinitie van een voor de "printer" klasse. Klassen zijn een beetje meer handig zijn in situaties waar u wilt meerdere exemplaren van iets maken, maar dit levert een leuke manier om de structuur van onze code. De meeste van de dingen die de firmware van het apparaat moet doen hier worden gemaakt als de methoden van de klasse van de printer. De printer ook houdt spoor van eigen huidige instellingen.
Binnen de constructor van de klasse van de printer zien we een koele one-liner de UART (Universal Asynchronous ontvangen en zenden) om hardware te configureren in het GMB:
hardware.uart57.configure(19200, 8, PARITY_NONE, 1, NO_CTSRTS);
Dit stelt de UART-hardware op pin 5 en 7, configureert de baud-rate 19200 (bits per seconde), 8 data bits per woord, geen pariteit bits, 1 stopbit en geen datatransportbesturing; zowat de eenvoudigste UART instellingen die u kunt gebruiken.
Onder de klassendefinitie voor de printer registreert het apparaat sommige retouraanroepen voor de agent. We kunnen denken van deze als haken, elkaar geven de agent een manier om te vertellen van het apparaat om iets te doen. Agent callbacks zijn geregistreerd met "agent.on()", waarin twee argumenten: een tekenreeks, die zal worden doorgegeven door de agent om te vertellen het apparaat welke terugbellen te gebruiken; en een functie die wordt aangeroepen wanneer de agent die string stuurt:
agent.on("print", function(buffer) {<br> server.log("Device: printing new buffer from agent: "+buffer);<br> myPrinter.print(buffer);<br>});
Kijkend naar de firmware, kunnen we zien dat we hebben geregistreerd callbacks voor allerlei dingen; gelijkwaardige vette of onderstreepte tekst, vertellen van het GMB om te beginnen met het downloaden van een afbeelding van de agent die met behulp van de "pull"-callback (die u vindt als een methode van de klasse van de printer), het voeden van een bepaald aantal lijnen, enz.
Wanneer de agent callbacks zijn al geregistreerd, en de klassen worden gedefinieerd, we instantiëren de klasse van de printer als een printerobject wilt maken en we zijn klaar om te gaan. De firmware van het apparaat is vooral gebeurtenisgestuurde; bits van het heten in actie wanneer de agent signalen is het tijd om iets te doen.
// instantiate the printer object at global scope myPrinter <- printer(hardware.uart57, 19200);<br>
De firmware van de agent is veel hetzelfde, maar zelfs korter, met een paar interessante stukjes gegooid in voor een HTTP-interacties. Laten we een kijkje nemen:
We het hele ding aftrap met een definitie van de printLogo functie - we zullen zien dat dit geregistreerd als een retouraanroep voor het evenement "logo" een beetje verder naar beneden. Een handig stukje hier is de illustratie van hoe te maken van een HTTP GET-aanvraag uit uw agent:
local reqURL = "http://electricimp.com/docs/attachments/images/examples/resources/ei_logo_tinyprinter.bmp";<br>local req = http.get(reqURL);<br>imageData = req.sendsync().body;
We maken een request-object met "http.get(reqURL), vervolgens verzenden, die een http response-object retourneert. Het lichaam van dat object response bevat de afbeeldingsgegevens - het is zo simpel als dat!
Na het doen van een beetje van het werk met de afbeeldingsgegevens, zien we de agent een gebeurtenis naar het apparaat sturen. Hier moeten we meerdere parameters naar het apparaat sturen, zodat wij hen in een array inpakken en verzend deze array met de gebeurtenis:
local imageParams = [imageSize, imageWidth, imageHeight]; device.send("downloadImage", imageParams);
Verder zien naar beneden we callbacks geregistreerd voor de gebeurtenissen van het "pull" en "imageDone" van het apparaat, dan een retouraanroep geregistreerd met "http.onrequest". Dit is een zeer nuttig stukje agent API: de functie hier geregistreerd zal worden aangeroepen wanneer een HTTP-aanvraag (van elke methode) is aangebracht in de agent URL in Apparaatinstellingen. Dit is hoe de agent omgaat met nieuwe gegevens uit de printer demo-website:
http.onrequest(function(request,res){
Een zeer belangrijk deel hier, voor het verzenden van berichten naar de agent: als uw browser een bericht verstuurt, stuurt deze een Preflight-controle eerst om te zien welke methodes de geadresseerde ondersteunt. De ontvanger biedt deze informatie met haar antwoordheaders. Als dit niet laten zien dat de agent POST ondersteunt, de pagina zal niet sturen de hoofdtekst van het bericht, en het verzoek om de agent leeg! Hier is waar we deze headers om onze pagina te werken:
res.header("Access-Control-Allow-Origin", "*");<br>res.header("Access-Control-Allow-Headers","Origin, X-Requested-With, Content-Type, Accept"); res.header("Access-Control-Allow-Methods", "POST, GET, OPTIONS");
De agent doet een ander handig ding nadat de headers zijn ingesteld, maar een leesbevestiging moet worden verzonden: het bepaalt of gebruik de tekst bericht of afbeelding message handler op basis van het URL-pad waarop het verzoek is ingediend:
if (request.path == "/text") {
Laatst in de code van de agent zien we de callback geregistreerd voor het evenement "logo" van het apparaat:
device.on("logo", function(value) {<br> printLogo();<br>});
Dat is de hele wedstrijd schieten! Het hele internet-verbonden printer, in minder dan 600 lijnen!