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.

Detron Open Script Night – Ronde 1

Als een van de Business Developers bij Detron IT Consultants mag ik samen met het als team altijd zoeken naar methoden om onze collega’s kennis te laten maken met nieuwe systemen en technieken. Maar soms moet je ook de aanpak van deze kennisdeling eens op de schop gooien om zo een andere groep mensen te bereiken of een hoger niveau te behalen. Zeker op het gebied van het schrijven van een script ten behoeve van automatisering zien we het niveau flink stijgen en moeten we de aanpak dus veranderen.

Zo gaan we na 2 jaar aan PowerShell bootcamps eens proberen om op een hele andere wijzen kennis te delen over niet alleen PowerShell, maar ook andere scripttalen waar we in onze dagelijkse werkzaamheden mee in aanraking komen. Het resultaat van wat berichten heen en weer tussen collega’s was dat we vanuit het Detron ICT Kenniscafé (communicatie middel en organisatie van een deel van onze kennissessies en trainingen en mijn hobby op het werk 😉 ) ook wel een Open Script Night konden houden. Hier kunnen collega’s of externe sprekers in 10-20 minuten een demo en toelichting geven van iets wat ze zelf gemaakt hebben en misschien handig is voor collega’s.

Als we deze korte sessies combineren met een introductie van een nieuwe of bestaande techniek die voor iedereen interessant kan zijn hopen we een leuke actieve avond te hebben. Het is niet de bedoeling dat bezoekers alleen maar gaan zitten luisteren, maar ook direct met de laptop aan de slag kunnen om ervaring op te doen met wat ze horen en zien.

Ondanks dat ik met al 6 jaar bezig houd met het organiseren van trainingen en sessies heb ik anders dan het welkomstwoord nog nooit zelf inhoudelijk gesproken op een sessie, gezien een van mijn hobby’s nogal wat met scripting te maken heeft (clickfarm.nluitleg) was dit een mooie gelegenheid om hier ook een keer verandering in te brengen. Tijdens de eerste Detron Open Script Night zal ik 30 minuten spreken over twee tools die mij enorm helpen en een stukje techniek waar ik dagelijks mee in aanraking kom. Een van de andere onderwerpen  waar we deze eerste avond naar gaan kijken is git, wat mij betreft ook een onmisbaar stuk gereedschap voor het onderhouden van je scripts.

Onderwerp 1: Visual Studio Code (script editor)

Visual Studio Code een erg mooi stukje gratis software van Microsoft voor het schrijven van je code. Voor de meeste talen is er een intellisense module beschikbaar. Daarnaast zorg de Emmet.io integratie voor een aanzienlijke versnelling van het schreven van de code. Ook een directe integratie met git draagt bij aan een goede workflow. Visual Studio Code - Script editor

Onderwerp 2: Postman

Eigenlijk al een stukje voorbereiding op het derde onderwerp, maar Postman is een tool voor het testen van allerlei web connectoren (om het maar eens heel simpel uit te leggen). De eerste keer dat ik er mee in aanraking kwam was voor het testen van de backend voor Clickfarm, maar inmiddels gebruik ik de tool ook zakelijk.

Postman API Test suite

Onderwerp 3: Web-connectoren (API’s)

Wanneer je meerdere (SaaS) systemen aan elkaar wil koppelen ontkom je niet meer aan allerlei verschillende API’s. Nou zijn er aardig wat standaarden, maar in hoofdlijnen werken ze technisch veelal hetzelfde. Reden genoeg om eens beter te kijken wat nu de kracht kan zijn van een goede API, maar ook wat de uitdaging kan zijn als je meerdere passieve systemen wil koppelen.

api grafische weergave

 

Microsoft Power BI Gateway (Deel 2)

In de vorige post hebben we gekeken naar hoe we data uit Profit via de webconnectoren naar JSON files kunnen halen. Om deze files ook beschikbaar te maken in de cloud voor Power Bi kunnen we het beste gebruik maken van de Power Bi gateway. Hier onder vind je een instructie van hoe deze te installeren en configureren. De instructie is op basis van de documentatie van Microsoft die je hier vind.

Stap 1: Download Enterprise Gateway

Om de Gateway te kunnen downloaden moet je inloggen op Office.com en dan doorklikken naar de PowerBI omgeving.

Office 365 Power BIRechts bovenaan heb je een “download” knop, kies daar voor “Data Gateway”

Power BI Gateway

Je wordt vervolgens doorverwezen naar de download pagina, klik daar op de “Download Gateway” optie.

Download Power BI gateway

Stap 2: Installeer Enterprise Gateway

Na de download kan je de installer starten, als er al andere applicaties draaien op de server is het zeer waarschijnlijk dat aan alle requirements voldaan wordt voor de installatie.

Power BI Gateway installatie

Je krijgt de keuze voor twee types gateway, kies hier voor de aanbevolen optie en dus NIET voor de personal mode!

Power BI Gateway Installtie modusDruk op volgende tot de installatie daadwerkelijk start.

Stap 3: Koppel Gateway

Na de installatie moet deze gekoppeld worden. Het maakt in principe niet al te veel uit welke user hier gekoppeld wordt, maar:

Alleen deze user kan:

  • aanpassingen doen aan de configuratie van de gateway zelf
  • Logging exporteren

Verder:

  • Er wordt een recovery code aangemaakt waarmee we deze user kunnen omzeilen, bewaar deze goed
  • Je moet met deze user in kunnen loggen op Office.com en je hebt dus een volledige O365 licentie nodig!

Power BI Gateway user

Je zal vervolgens een pop-up krijgen voor je credentials.

Vervolgens moet je een keuze maken of je een oude gateway wil recoveren of dat je een nieuwe gaat installeren, in ons geval installeren we dus een nieuwe:

Power BI Gateway Nieuw of Recover

Geef de gateway een naam en voer de herstelsleutel in, bewaar deze goed, we hebben deze nodig als we de gateway ooit zouden willen migreren naar een nieuwe server.

Power BI Gateway Recovery Key en naam

Je krijgt vervolgens de instellingen te zien, deze staan goed, dus die kan je zo laten:

Power BI Gateway regio

Zet tot slot het vinkje voor het verzenden van de gebruikersgegevens nog even uit. Vervolgens is de installatie klaar.

Power BI Gateway installatie voltooid

Stap 4: Autoriseer Gateway

Tot slot moet de gateway nog geautoriseerd worden. Deze is op dit moment alleen beschikbaar voor de user die je bij de installatie hebt opgegeven.

Log als deze user in op Offic.com, ga naar de PowerBI pagina en kies deze keer voor de “Settings” knop en kies voor manage gateways

Power BI Gateway autorisatie

Klik vervolgens op administrators:

Power BI Gateway administrators

 

 

De rest van de configuratie vind plaats vanuit Power Bi zelf.

AFAS Profit – Microsoft Power BI (Deel 1)

Het was voor ons al langer een wens om data uit AFAS Profit eenvoudig in Power BI te kunnen gebruiken, en alhoewel het nog steeds geen helemaal directe link is kunnen we nu wel middels een klein stukje Powershell en de Power BI gateway gebruik maken van automatisch bijgewerkte Profit data in Power BI.

De voorbereidingen beginnen in Profit:

Zorg er voor dat je eerst in AFAS Profit een app connector aanmaakt, koppel hier vervolgens een gebruiker aan en zorg er voor dat je het autorisatie token genereert.

De volgende stap is het toevoegen van de “Getconnectoren” die je automatisch wil exporteren. Het Powershell script zal alle getconnectoren voor deze gebruiker exporteren, dus het is zaak om te zorgen dat je alleen de data die je naar PowerBI wil sturen beschikbaar stelt voor deze connector. In dit geval betreft het drie connectoren:

 

Tot slot hebben we voor het exporteren van de data een klein stukje Powershell nodig:

$token = ‘<token><version>1</version><data>***</data></token>’
$encodedToken = [System.Convert]::ToBase64String([System.Text.Encoding]::ASCII.GetBytes($token))
$authValue = “AfasToken $encodedToken”
$Headers = @{
Authorization = $authValue
}

$url = ‘https://**/Profitrestservices//metainfo’
$file = ‘C:\PBIData\todo.json’
Invoke-WebRequest -Uri $url -OutFile $file -Headers $Headers

$todo = Get-Content -Raw -Path $file | ConvertFrom-Json

foreach ($conn in $todo.getConnectors.id){
$url = ‘https://**/profitrestservices/connectors/’+$conn+’?skip=-1&take=-1′
$file = ‘C:\PBIData\’+$conn+’.json’
Invoke-WebRequest -Uri $url -OutFile $file -Headers $Headers
}

Het bovenstaande script haalt de beschikbare getconnectoren op en zal deze vervolgens zonder filtering volledig ophalen en als JSON op de gespecificeerde locatie neerzetten. Overigens kan dit natuurlijk ook mooi opgelost worden met een stukje storage en een function app in Azure, maar dat is iets voor later :).

We hebben de data nu klaar staan voor de integratie met PowerBI, hoe dat in zijn werk gaat wordt in de volgende post uitgewerkt.

IoT – ESP8266 gepruts

Een tijdje terug ben ik bezig geweest met het aansturen van mijn KlikAanKlikUit lampen via een Raspberry, rond die tijd kwam ook ineens Andries met een reeks blogposts  over het draadloos aansturen / dimmen van ledverlichting. Dat triggerde mij om me eens te verdiepen in dat soort systemen en de mogelijkheden die daarbij komen kijken.

Als we bedrijven als Intel mogen geloven moet The Internet of Things (IoT) DE toekomst worden op technologisch vlak. Dat zou er op neer komen dat zo’n beetje alles om je heen is aangesloten op het internet, waardoor je altijd alles kan monitoren, je op afstand je lampen aan / uit kan zetten, je de wasmachine kan starten, thermostaat kan instellen enzovoorts. Er zijn meerdere mogelijkheden om dit te realiseren, maar WiFi is hiervoor het meest toegankelijk als je er zelf mee aan de slag wil.

Dit is waar de ESP8266 een rol gaat spelen, via de posts van Andries raakte ik bekend met het bestaan van dit platform (ESP8266)

esp8266 ESP-01

Door de chip te flashen met een NodeMCU firmware kan je de aansturing van het “systeem” in LUA schrijven. Mijn Lua kennis is ongeveer net zo groot als mijn kennis over curling, dus daar ligt nog wel een kleine uitdaging. Maar juist dat uitzoekwerk maakt het wel leuk om hier tijd aan te spenderen.

Als eerste project ben ik maar eens begonnen met het nabouwen van het project van Andries (met wat kleine aanpassingen), een mooie oefening om ook het solderen weer eens onder de knie te krijgen. Ondertussen heb ik gewoon om te proberen ook een printje gemaakt waarmee ik via WiFi en mijn Raspberry (als webserver) mijn lampen aan en uit kan zetten, het programma en de print zijn erg basic, maar het is wel bijzonder bevredigend om zoiets zelf te maken.

Heel kort samengevat wordt er een web request gestuurd naar de Raspberry op het moment dat een van de twee GPIO poorten op de ESP8266 naar High gaat (er dus spanning op komt te staan), dit gebeurt wanneer de drukknop ingedrukt is.

Je kan diverse sensors aan het systeem knopen waarvan je de output relatief eenvoudig naar een webserver kan versturen, deze informatie kan je dan vervolgens weer voor uiteenlopende zaken gebruiken.

Al met al leuk speelgoed, mocht ik ergens nog een keer een toepassing bedenken waarvan ik denk dat deze ook nuttig kan zijn voor anderen zal ik eens een uitgebreid verslag / instructie schrijven.

Nuttige toepassing RFID tags en Android telefoon

Een hele tijd terug heb ik al eens geschreven over het gebruik van RFID tags in combinatie met de NFC functie van mijn Samsung Galaxy S3.  De app die ik toen gebruikte heeft inmiddels een nieuwe naam gekregen, maar het idee is hetzelfde.

Inmiddels heb ik een echt zinnige toepassing gevonden voor deze mogelijkheid. Eigenlijk is de onderliggende reden wel goed waardeloos, maar dat maakt het plezier aan de oplossing niet minder :).

Sinds iets meer dan een half jaar rij ik in een Audi A3 met onder andere het Audi Connect systeem. Hierin kan je een simkaart stoppen zodat de auto zelf toegang heeft tot internet voor allerlei uiteenlopende zaken zoals bijvoorbeeld verkeersinformatie. Het is dan alleen niet meer mogelijk om je telefoon te koppelen aan de carkit functie… Je kan dus alleen maar bellen via de sim in de de auto. Dan kan je voor een duosim gaan maar dan moet je telefoon eigenlijk uit, of in ieder geval het mobiele deel, wat weer niet handig is voor zaken als Spotify, en bovendien een handmatige actie is. Gelukkig kan de auto het internet van de sim delen via wifi zodat je via die weg wel nog wifi kan krijgen op je telefoon. Maar een hoop gedoe dus.

Nu kan je met de Android app Trigger NFC tags gebruiken voor het uitvoeren van een serie handelingen. Voor deze oplossing is het noodzakelijk dat de app root toegang krijgt gezien het voor apps sinds een paar Android versies terug niet meer standaard mogelijk is om bijvoorbeeld de airplane mode te activeren. Als dat eenmaal geregeld is kan je de volgende stappen instellen:

1. Enable airplane mode
2. Enable wifi

En dan als de tag nog een keer gescand wordt:

3. Disable airplane mode
4. Enable wifi (waarschijnlijk overbodig)

trigger screenshot

Op deze manier kan je de duosim in de auto gebruiken terwijl de telefoon via wifi alsnog normaal internet heeft. Een groot nadeel hiervan is dat je telefoon op Wifi aanzienlijk meer data zal verstoken dan normaal via 3/4G, dus dat is wel iets om rekening mee te houden. Optimaal is het nog niet, maar ik hoef nu alleen maar bij het in en uitstappen de telefoon even bij de tag te houden om de modus van mijn telefoon aan te passen om dit werkend te maken. Bijkomend voordeel is wel ook dat bellen direct via de auto zonder tussenkomst van de telefoon een stuk beter werkt.