Tesla Model 3 VIN status met Azure Logic Apps

Als je je droomauto mag bestellen moet je vaak wachten tot je deze daadwerkelijk in ontvangst mag nemen. Bij Tesla is dat wachten een “beetje” een black box, dus wat doe je dan om de tijd te verdrijven? Inderdaad.. kijken hoe je Microsoft Azure kan toepassen op dat wachtproces šŸ˜‰

Voor wie niet bekend is met het bestellen van een Tesla zal ik eerst kort opsommen hoe dat proces ongeveer gaat (in het geval van een leasemaatschappij):

  1. Je regelt intern de order en deze gaat naar de leasemaatschappij
  2. De leasemaatschappij bestelt daadwerkelijk de auto bij Tesla en doet de aanbetaling
  3. Je ontvangt een mailtje “Welkom bij de Tesla familie” en mag een account aanmaken
  4. Je krijgt een RN nummer en als je geluk hebt een leverindicatie
  5. Vervolgens is eerst alleen in de broncode het serienummer (VIN) van je auto zichtbaar
  6. Het serienummer is zichtbaar op je profiel pagina
  7. Je krijgt een leverdatum aangeboden
  8. Je mag je auto ophalen
Tesla bestelling overzicht. (goed irritant dat de kleur van het interieur op het plaatje niet klopt :()
Beetje jammer dat de interieurkleur niet overeen komt met de kleur in de bestelling šŸ™

Stap 1 tot 4 gaan redelijk vanzelf, en dan begint het kijken naar sheets zoals deze om te zien wanneer er weer een schip/shit-load aan Tesla Model 3’s deze kant op komen, in de hoop dat die van jou daar ook bij staat en je dus een serienummer toegekend krijgt.

Het vervelende is echter dat je dus iedere keer (als je een beetje ongeduldig bent, zoals de gemiddelde Tesla besteller) met de hand in de source moet zoeken of er een VIN beschikbaar is (of je gebruikt een Chrome plugin)

Automatiseren die hap

Alles wat of vervelend is om te doen, of je meer dan eens moet doen moet je proberen te automatiseren, en gelukkig zijn er dan oplossingen als Azure Logic Apps om dat te realiseren.

Tesla heeft een API beschikbaar waar je met je account gebruik van kan maken, er is niet echt officiele documentatie van, maar zoals vaker heeft dat het internet er niet van weerhouden er toch gebruik van te maken.

De stappen die we gaan doorlopen:

  1. Een autorisatie token genereren met je Tesla account
  2. Een Azure Logic App bouwen die ieder uur:
    1. Een webrequest doet bij Tesla
    2. Het webrequest interpreteert en een als dan functie uitvoert
    3. Je een mailtje stuurt bij goed nieuws

Ik heb eigenlijk alleen Postman gebruikt voor het maken van de initiele requests, maar met de code voorbeelden hier onder kan je als het goed is zelf wel uit de voeten zonder het gebruik van Postman.

Door wat tijdgebrek ben ik er niet aan toe gekomen om een generator te maken voor je autorisatie token, dus dat moet voor nu nog met de hand middels postman. Je kan eventueel ook een externe website gebruiken voor het genereren van je token, zoals bijvoorbeeld deze.

Autorisatie token genereren

Je kan je (Oauth) autorisatie token ophalen door de onderstaande stappen te volgen. Samengevat gaan we een API call doen om met je inloggegevens een token te genereren.

Als je Postman geopend hebt kies je voor “New request”:

Postman "Create New" menu
Postman – New Request

Je moet het request een naam geven en toevoegen aan een “Collection”, je kan hier een bestaande kiezen of een nieuwe aanmaken.

Postman save request menu
Postman – New request details

Als je een nieuw request aangemaakt hebt krijg je onderstaand scherm te zien (alleen dan nog leeg):

Postman request editor
Postman request
  1. Pas het type request aan naar een “POST”
  2. Voer de volgende URL in: https://owner-api.teslamotors.com/oauth/token
  3. Maak de volgende parameters aan en vul de value’s
    1. grant_type – password
    2. client_id – De waarde voor dit veld vind je hier: https://pastebin.com/pS7Z6yyP en de toelichting hier: https://tesla-api.timdorr.com/api-basics/authentication
    3. client_secret – De waarde voor dit veld vind je hier: https://pastebin.com/pS7Z6yyP en de toelichting hier: https://tesla-api.timdorr.com/api-basics/authentication
    4. email – het email adres van je Tesla account
    5. password – het wachtwoord van je Tesla account
  4. Druk vervolgens op Send

Je krijgt nu een response te zien die er grofweg zo uit ziet:

{
    "access_token": "****",
    "token_type": "bearer",
    "expires_in": 3888000,
    "refresh_token": "****",
    "created_at": 1568872567
}

Het access_token heb je in de volgende stappen nodig.

LET OP: Het token dat je hier aanmaakt (en je login gegevens sowieso) geven controle over veel meer dan alleen de data die we nu ophalen, ook zodra je je auto eenmaal hebt kan dit token gebruikt worden voor bijvoorbeeld het openen van de deuren.. Zorg er dus voor dat je zorgvuldig om gaat met het token. Tokens zijn momenteel 30 dagen houdbaar en moeten dan vervangen worden (zie daarvoor de documentatie)

Azure Logic App aanmaken

Logic apps kosten (zoals veel services op Azure als je ze goed gebruikt) zo ongeveer niks, en zeker niet als je het voor dit doel gebruikt. Als het wachten een beetje mee zit zou je zelfs in je trial account genoeg dagen gratis gebruik moeten hebben zitten om daarmee de wachttijd uit te zitten.

Als je nog geen account hebt kan je deze aanmaken via portal.azure.com, als je wel al een account hebt kan je daar inloggen en in de zoekbalk zoeken naar “Logic Apps”

Azure overzicht
Azure Logic Apps

Op de volgende pagina kan je vervolgens middels “Add” een nieuwe logic app aanmaken:

Azure logic apps
Logic app overzicht

Het aanmaken van de lege Logic App is in tegenstelling tot sommige andere Microsoft Azure onderdelen relatief eenvoudig:

Logic App aanmaken interface
Logic App Aanmaken

Je voert een naam in, kiest een subscription en een bestaande of nieuwe resource group (een bundel gerelateerde services en onderdelen) en kiest tot slot een locatie, waarbij het zinnig is een locatie zo dicht mogelijk bij je eigen locatie te kiezen.

Het aanmaken zelf duurt vervolgens even (1-2 minuten, verwaarloosbaar in Tesla-tijd), maar na een tijdje zie je je gloednieuwe Logic App in de lijst staan:

Azure Logic App overzicht
Logic App overzicht na aanmaken App

Je kan hier vervolgens op klikken en zal dan naar de design view gestuurd worden waar we de logic app kunnen gaan inrichten.

Azure Logic App configureren

In het eerste overzicht dat je krijgt zie je allerlei templates staan. Deze zijn leuk om eens mee te experimenteren, maar voor deze app kiezen we voor een “Blank Logic App”

Lege logic app template
Een leeg template

De eerste stap die je vervolgens zet is het bepalen van een trigger. De trigger bepaalt wanneer het proces in de Logic App moet starten. Je hebt hier een grote hoeveelheid opties die interessant zijn om te bekijken. In dit geval kiezen we voor de “Schedule” optie, en vervolgens voor recurring (oftewel, starten op basis van een timer):

Logic app recurrence
Logic App trigger

De vervolgstap is het invoegen van de daadwerkelijke actie waar het proces mee moet beginnen. In ons geval gaan we een “GET” actie uitvoeren tegen de Tesla API. We geven hierbij een autorisatie header mee met het Autorisatie token dat we eerder in deze post aangemaakt hebben met ons account.

Voor het toevoegen van deze stap zoeken we naar HTTP, en kiezen voor de HTTP actie, je krijgt dan een veld zoals hier onder:

Logic app http request
HTTP Request opbouwen

De waardes die je hier invult:

  • Method: GET
  • URI: https://owner-api.teslamotors.com/api/1/vehicles
  • Headers: Authorization | Bearer “token zoals eerder gegenereerd”

Wat deze stap doet is het webrequest opbouwen dat volgens het schema dat we eerder samengesteld hebben aangeroepen wordt.

De volgens stap is het oppakken van het resultaat van het webrequest dat we hiervoor aangemaakt hebben. We gaan het resultaat omzetten naar een JSON object, dat is niet per definitie nodig voor de werking zoals de app nu is, maar bied wel meer mogelijkheden voor de toekomst en is een kleine moeite.

Voeg een action toe en zoek naar “Parse JSON”. Je krijgt een blok te zien zoals hier onder:

Logic app JSON parser
Parse JSON configuratie

Klik hier eerst in het “Content” vak (1) en vervolgens in het Dynamic Content veld onder HTTP (eventueel even op klikken als je geen opties ziet) op “Body” (2). Tot slot klik je dan op ” Use Sample Payload to generate schema ” (3) en voer deze code in:

{
    "response": [],
    "count": 0
}

Er zal een schema gegenereerd worden waar we later naar refereren.

De volgende stap is een stukje “Als, dan” logicia om te zorgen dat je alleen een bericht ontvangt als er een VIN gekoppeld is aan je account. Je zoekt hiervoor naar de actie “Control” en kiest vervolgens voor “Condition”:

Logic app controller / condition
Condition Operators

De eerste stap die we hier zetten is de werkelijke vergelijking bepalen. In her eerste veld klikken we en kiezen we in de “Dynamic” content voor de waarde “Count”. Deze stap is iets makkelijker geworden door het schema dat we hier voor toegevoegd hebben, anders had je dat veld hier handmatig moeten specificeren.

Als de “Count” waarde niet gelijk is aan 0 is er dus blijkbaar een auto toegevoegd aan je account, dus dan gaan we in de volgende stap een “If true” actie instellen. Klik hiervoor op “Add an action” in het “If true” blok. Vervolgens zoek je naar “Send email”, in mijn geval kies ik hier voor Office 365 en vervolgens opnieuw voor “Send Email”, je mag vervolgens inloggen:

Logic app mailer connector
O365 Sign In

Na het inloggen kan je de mail opmaken, je kan hierbij elementen gebruiken uit alle eerdere stappen, deze zijn beschikbaar als dynamic content. Ik heb het niet al te moeilijk gemaakt en gewoon de hele HTTP response gepakt, als de auto eenmaal gekoppeld is maakt het me niet zo veel meer uit dat het mailtje niet zo mooi is ;). Als het menu bij Dynamic Content leeg blijft moet je even op “See more” klikken.

Logic app mail
Logic App mail

Uiteindelijk heb je dan iets zoals hier onder:

Logic app totaaloverzicht
Logic App overzicht

Als je hier eerst nog op “Save” (1) en vervolgens op “Run” (2) klikt zal de app eerst een keer zichtbaar draaien en vervolgens ieder uur op de achtergrond (volgens het eerder ingestelde schema). Je kan op deze pagina meteen zien wat er in iedere stap gebeurt is en wat het resultaat is geweest. Als het “goed” is zal je geen mail krijgen omdat er nog geen gekoppelde auto is. Als je zeker wil weten dat alles naar behoren werkt zou je ook een bericht kunnen koppelen aan de “If false” branch, maar dat is normaal gezien eigenlijk niet nodig.

Wachten

Als de logic app eenmaal draait merk je daar doorgaans niets van (tot je goed nieuws krijgt). Als je dan toch de status wil zien kan je de logic app op de Azure Portal opzoeken en open klikken. Je ziet dan altijd een overzicht van de keren dat de app gelopen heeft en de resultaten van iedere run:

Logic app history
Azure logic app history

Verder rest er nu dan niets meer dan wachten tot de mail komt.

Tot slot

Echt heel erg zinnig is deze logic app natuurlijk niet, maar het is wel een (erg simpele) introductie tot een zeer krachtig Microsoft Azure onderdeel wat eindeloos veel toepassingen kent en eigenlijk voor iedereen relatief goedkoop beschikbaar is.

Azure function apps in combinatie met AFAS Profit

Als je wil proberen om zo min mogelijk eigen infrastructuur te gebruiken zonder dat dat meteen veel geld moet kosten zijn er talloze opties te bedenken. Een van die opties is Microsoft Azure. De eerste stap die je zal moeten zetten is gaan denken in de daadwerkelijke handelingen die er uitgevoerd moeten worden. Deze handelingen wil je vervolgens in logische blokken opdelen, met als voorwaarde dat deze blokken moeten onafhankelijk van elkaar kunnen functioneren. Vervolgens kan je per blok gaan kijken wat de beste manier is om de gewenste functionaliteit te realiseren.

Het “Probleem”

In dit voorbeeld gaan we voor nieuwe medewerkers in AFAS Profit een aantal velden vullen. Omwille van de eenvoud van het voorbeeld heb ik het gebruikte script even eenvoudig gehouden. Gezien het in Profit niet mogelijk is om logica toe te passen bij het automatisch vullen van velden hebben we een externe oplossing nodig om dit te doen. Het heeft mijn voorkeur om dit soort zaken met Powershell en de connectoren in Profit op te lossen. Voorheen gebruikte ik hiervoor altijd een van onze applicatieservers voor (om het script te draaien). We kunnen dit echter ook prima in Azure oplossen

De oplossing (Microsoft Azure)

Als je in MicrosoftĀ Azure scripts wil laten draaien die gebruik kunnen maken van web connectiviteit zijn de “Function Apps” een goede optie. Binnen dit systeem heb je bijvoorbeeld ook Web Proxies beschikbaar en die gaan we in een latere post gebruiken :). We gaan dus een Function App aanmaken waarbinnen we Ć©Ć©n of meerdere scripts op een tijdschema laten draaien. In dit voorbeeld gaan we een lijst ophalen van medewerkers die nog geen licenties toegekend gekregen hebben. Deze lijst met medewerkers krijgt vervolgens de juiste licenties toegekend op hun medewerkerkaart. Voor deze stappen heb je een actieve Azure Subscription nodig (je moet dus of in de trial zitten of een betaalmethode gekoppeld hebben). De kosten van het draaien van dit script (15 uur per dag) zijn 6 eurocent per maand (afhankelijk van de gebruikte opslag / data). Ik zou Azure altijd instellen op de Engelse taal gezien de vertalingen naar het Nederlands erg verwarrend kunnen zijn. Daarnaast zijn niet alle vertalingen correct.

Stappenplan (functie)

We starten op de AzureĀ portalĀ en kiezen daar voor het aanmaken van een nieuwe resource:
Azure portal "Create Resource"
In het volgende venster zoek je naar “Function app”:
Azure function app aanmaken
Je krijgt een nieuw menu te zien waar je een aantal instellingen in kan geven. De “App name” is voor dit stappenplan niet zo van belang. Mocht je later de Proxy functionaliteit wil gaan gebruiken wordt dit de URL waarop je de proxy kan benaderen. In ons geval moeten we een nieuwe resoursegroup aanmaken waar alle elementen voor deze functionaliteit gebundeld worden. als locatie kiezen we voor West Europe gezien die geografisch het dichtste bij onze AFAS Profit omgeving zal staan. De naam van de storagegroup is niet heel belangrijk in dit geval, als je het maar eenvoudig terug kan vinden. Uiteindelijk heb je dan grofweg het onderstaande. Als je nu op “Create” klikt wordt de Function App aangemaakt, dit kan ongeveer een minuut duren.
Na een minuutje wachten kan je de Function App openen en krijg je een overzicht zoals dit te zien:
Function app overzicht.
We kunnen nu daadwerkelijk de functie aan gaan maken die het script gaat draaien. We klikken hiervoor bij “Funtions” op het plusje om de wizzard te openen. Er zijn een groot aantal standaard functies beschikbaar, maar in ons geval willen we een custom function bouwen:
In het volgende venster zal je de beta talen aan moeten zetten. Powershell is nu nog in beta (al tijden), maar werkt prima. Om deze mogelijkheid te krijgen moet je deze switch even omzetten:
Vervolgens kan je de “Time Trigger” optie kiezen:
Azure function Time Trigger
In het volgende venster zal je de taal moeten kiezen (in ons geval PowerShell) en het schema moeten definiƫren. Dit schema maakt gebruik van dezelfde notatie als CRON en is niet heel erg gemakkelijk leesbaar als je er niet veel mee werkt. Je kan hiervoor eventueel een generator gebruiken. In het voorbeeld hier onder draaien we het script ieder uur vanaf 7.00 in de ochtend tot 20.00 in de avond. (let wel op dat je je tijdzone goed ingesteld hebt).
Na het aanmaken van de functie krijg je een leeg venster te zien waar het script geplaatst kan worden. Je kan dit allemaal integreren met bijvoorbeeld Github (of andere repositories), maar dat gaat voor dit voorbeeld even te ver.

Het script

De laatste stap is het toevoegen van het script zelf. Ik ga niet al te veel in op de werking van het script, maar kort samengevat gebeurt er het volgende:
  • Roep een getconnector aan die een gefilterde lijst met gebruikers zonder licenties ophaalt.
  • Loop door deze lijst en voer de gewenste licentiecodes in bij de diverse users.
Om het voorbeeld een beetje overzichtelijk te houden staat hier onder een versimpelde versie van ons script. We gebruiken zelf een complexer script met een aantal randvoorwaarden om te bepalen welke licentie nodig is voor welke gebruiker.
begin {

    # define the access token for the AFAS service
    $token = '<token><version>1</version><data>***</data></token>'
    $encodedToken = [System.Convert]::ToBase64String([System.Text.Encoding]::ASCII.GetBytes($token))
    $authValue = "AfasToken $encodedToken"
    $Headers = @{
        Authorization = $authValue
    }

    # Connect and retrieve the table
    $url = 'https://**/profitrestservices/connectors/***?skip=-1&take=-1'
    $records = ((Invoke-WebRequest -Uri $url -UseBasicParsing -Headers $Headers).content  | ConvertFrom-Json).Rows
}

process {
    # Specify update authorization
    $token = '<token><version>1</version><data>***</data></token>'
    $encodedToken = [System.Convert]::ToBase64String([System.Text.Encoding]::ASCII.GetBytes($token))
    $authValue = "AfasToken $encodedToken"
    $Headers = @{
        Authorization = $authValue
    }
    $connectorname = "KnEmployee"
    
    # Process records 
    foreach ($record in $records) {
        $url = "https://***/profitrestservices/connectors/KnEmployee"

        Write-Host $record.profituser
        $medewerker = $record.profituser

        $messagecontent = '{"AfasEmployee": {"Element": {"@EmId": "' + $medewerker + '", "Fields": { "***": "02", "***": "01"}}}}'

        $results = ((Invoke-WebRequest -Uri $url -UseBasicParsing -ContentType 'application/json;charset=utf-8' -Method PUT -Headers $Headers -Body $messagecontent).content | ConvertFrom-Json)
        Write-Host $results
    }
}
Na het invoeren van het script kan je op “save en run” klikken en daarna zal het script volgens het voorgestelde schema draaien. Je kan eventuele fouten opsporen door de logging na te kijken, deze is voor de losse run direct onder in het scherm beschikbaar:
En later via het monitor menu:

Tot slot

Dit is natuurlijk maar een eenvoudig voorbeeld, maar je kan je voorstellen dat je op deze manier veel zaken kan automatiseren zonder dat je hier eigen infrastructuur voor nodig hebt. Het script wat ik gebruikt heb in dit voorbeeld is gemaakt samen met Jaap de Koning, lees ook eens zijn blog als je geĆÆnteresseerd bent in automatisering. Laat even een berichtje achter als je meer wil weten over deze manier van automatiseren rondom AFAS Profit of het gebruik van Azure functions. De komende tijd zal ik meer in gaan op deze aanpak. Daarbij kijken we naar de veranderingen die nodig zijn in de manier van denken om goed gebruik te maken van cloud en hybride oplossingen.