A dirty hack to the first Head2Head challenge?

Okey, we do agree that solution that won is a bit better than this, but that’s why we think this is a dirty hack! Instead of doing what you should do with the challenge, we ended up creating a canvas app that could run offline and add that to the Power Page. It still solves the challenge, doesn’t it?

And, you might as how we got this brilliant idea.. What is more innovative use of AI if it’s not asking these questions you don’t have the answer for yourself? So we asked ChatGPT how we could solve this challenge, and this is the answer we got:

🤖 Automatically Priming our SPA cannons with React and .NET ⛵️

Sailing is though, so you need to rigg your ship to your advantage, preferably automating your sales and having people walk the plank for making bad code. We chose to created a project with ASP.NET Core application running with React.js. The application is running on .NET version 7 and uses several technologies, both hip and retro.

Screen capture of the .net SPA application setup

Mapbox for Charting the Seven Seas

Our application uses Mapbox – a provider of custom online maps for websites and applications. The company provides APIs and SDKs to create custom maps, add markers and other map controls, and to handle user interaction with maps. This ease of use and their clean and well-structured documentation (docs.mapbox.com) made Mapbox our top dog for create, edit and manipulate maps in our service.

Map created using Mapbox’s API

Protecting your Shared Booty form the Crew

Any pirate needs a secure lair, a pirate code and ability to help other pirates in need. For this reason we created a repository in GitHub and implemented best practices for collaborating as developers, like proper branching, build pipelines, linting and pre-deploy checks. Like blocking ourselves from bloat because we can’t have unused code in the repository.

Snipet showing lint error for unused variable

Branching Strategy for Division and Conquering

The master branch contains the production code. All development code is merged from develop into master. Cutting corners in true hacker style we opted to not use feature branches, since, to be frank, the entire thing is a feature at this point.

What we all said when discussing feature branches

All branches are protected with protection rules. Due to the limited size of the project we can automatically merge features and bug branches directly to develop, but we can’t push directly to develop. Even that is too risky for this group of mad lags and girl. If you want to merge code from develop into master you need approval from at leaste one other developer and no changes requested to your merge, if all flags are green Github forcefully collides the code together and see what sticks (it’s actually more sophisticated than this, but you Judges know a lot more about this than we ever will, so we humbly just call it “magic” – just like magnets).

Parchment showing the Law of Protection for our Master Branch

Feel free to have a gander at our code repository to appreciate all the shiny details: github.com/TommyBakkenMydland/CaptaIN-Hack-Sparrow

Smooth Rigging with CI/CD and Github Actions

Github Actions is a now a CI/CD platform that allows developers to automate their software development workflows. This, for us, is a huge win because we want to do as little configuration as possible!

CI/CD github actions

The actions reduce the time and effort required for manual processes and enables us to release new features and bug fixes quickly and confidently – Harr harr, got you matey, you thought we will fix bugs! … But … for the sake of argument … if we were to fix bugs, this powerful tool for streamlining development workflows, enables us to deliver high-quality software more efficiently and effectively at lower cost – Better use of time, reduce waste of time (WoT) and better business value for the client. We used yaml to tell what GitHub actions should create:

Yaml file describing what GitHub actions should create

Creating Overly Complex Gadgets to Avoid Simple Tasks
(aka How we used ChatGTP to give us documentation on Pulumi)

Nobody likes to know stuff. Everyone loves AI. What about AI that knows stuff?! Sold!! We used the AI service to provide us with documentation on how to deploy infrastructure in Azure with code.

Asking the oracle about stuff we probably already should know

From this we were able to write code that could be executed in our CI/CD

Pulumi snippet for creating our environment: Infrastructure as code #retro

Resulting in a beautiful environment and ample time for coffee ☕️

Screen grab showing the employed resources in Azure
Screen grab showing ChatGTP making a meme about making memes about using ChatGTP. Very meta.
Mame created from ChatGPD’s instructions

The dirty way

The idea of a map integration for our ships is pretty cool. We are already loading ships from Kystverkets api where we get the ship ids and store them in Dynamics. These ids can be used to lookup the specific ship and we have added an iframe to the lead form to generate the correct url. As it turns out, kystverket is not allowing us to show their website because… security 🙁

Nasty hacker to the rescue!

We discovered that you can add a chrome extension to ignore x-frame headers. By adding the attribute is="x-frame-bypass" to the iframe html element, the iframe now bypasses the X-Frame-Options: deny/sameorigin response header from kystverket. The result:

By this we claim the Nasty Hacker badge! #rocksolidgeekness

Smack my JSON up – and why size matters

Power Automate loves talking to API’s. API’s love talking in JSON. Because why not, we’re in 2023 where curly braces are the equivalent of the human hug – just embrace it already, and grab what you need 3 levels deep. Dot, dot dot. Easy as a dot.

But what happens when you embrace too much? I mean, we’re in 2023 where size has grown (out of proportion) compared to the skinny 70’s. And we’re talking simplistic CSV files here in case your mind was wandering into the land of political correctness. Just saying.

Either way. If the body of JSON is too large, a tad over 0.5MB, Power Automate nullifies it, which prevents you from getting to the property you want. That’s quite the statement.

Fortunately JSON has a string body, and strings can be cut at the front and the back, scissor scissor, slice slice. Let’s strip the away the bloat, grab the good meat, and let JSON be JSON for the time being.

We’re willing to debate if string manipulation is a nasty hack, but this is what PirateGPT has to say about that: “Arrr, string manipulation be a nasty hack in 2023, as it be a shortcut that don’t stand the test of time. It be a quick fix, but be sure to find a more permanent solution before ye be walkin’ the plank!”

And there is no question it’s retro, or as PirateGPT says: “Arrr, ye scurvy dogs! String manipulation may be a tried and true technology, but it’s been outdone by more modern techniques like natural language processing and machine learning. So in 2023, it’s a bit of a retro technology.”

Kjøleskapet… Fridgitoid 9000.. Kjøkkenapparat eller din venn i hverdagen?

Ideen om verdens beste kjøleskap ble unnfanget få dager før ACDC gikk av stabelen, men vi hadde et kjempeproblem… Vi manglet jo et faktisk kjøleskap å «smartifisere». Heldigvis sitter teammedlemmene på enorme kunnskaper innen papp- og gaffateipkonstruksjon. Med en 3D-printer, semi-god kjennskap til 3D modellering en livlig fantasi klarte vi å lappe sammen en pappeske som absolutt minner om ekte vare.

Her er en video som viser vår fantastiske kjøleskapslogo som spinner rundt og indikerer at det er liv. Når døren åpnes trigges vår knappesensor som gjør at kamera tar bilde.
Dette oppsettet hadde ikke vært mulig uten den trofaste Arduinoen, som bygger på det eldgamle programmeringsspråket C som først brukt i 1972. Some things never change, og hvorfor bytte ut noe som fungerer?

Bildet sendes til Azure Cognitive services. Responsen kan du se på skjermen i videoen. Helt klart og tydelig en appelsin der altså. Deretter sendes dette til Power Automate for å oppdatere innholdet i ingredients-tabellen som beskriver hva som finnes i kjøleskapet. Orange = True!

Her har vi et flott B2C-produkt som forenkler hverdagen til alle mennesker og skillpadder med middagskvaler! Det beste av alt, latterlig lave produksjonskostnader! Hvis ikke det er Business Value så vet ikke jeg 😉

Dirty Hacker

Vi har gleder av å presentere vår Dirty hacker Kenny!

Vår kjære Kenny har laget en function app som trigger en logic app. I stedet for å skrive direkte til dataverse og sette opp kode som henter authentication tokens og håndterer dette, sender denne function appen dataen til en logic app. Denne logic appen håndterer da alt med autentisering. Dette legger til et ekstra ledd som forsinker hele prosessen, noe som IKKE er lurt når man vil jobbe med real time data. Spesielt når det er snakk om uvurdelige kunstverk.

Dette er for å skrive sensordata til dataverse sånn at vi kan bruke det i visualiseringen i Power BI

I og med at vi ikke har penger til å kjøpe mange (eller i det hele tatt èn) sensor, har Kenny enda en nasty hack. Dette går ut på å simulere sensordata.

Siden vi ikke har tilgang på noen IoT-enheter (😢) genererer vi målingene ved bruk av simuleringer fra en Raspberry Pi web simulator: https://azure-samples.github.io/raspberry-pi-web-simulator/ som vi har ti instanser av og skriver til ti forskjellige enhetregistreringer i IoT Hub i Azure.  

Denne dataen blir så tilgjengeliggjort i endepunktet som er innebygd i IoT Hub som igjen trigger en Azure Function App som formaterer dataen og trigger Logic app som skriver til Dataverse.  

Dette gjør at vi kan vise temperatur og fuktighet i “vårt museum”. Selv om det i dag ikke er hooket opp noen sensorer. Dette er jo noe man ikke kunne sendt inn i prod, ettersom den ikke er koblet til noen sensorer og man dermed ikke ville fått beskjed selv om museet skulle brent ned og oversteget grensen for hva maleriene tåler av temperatur 🙂

Update after request from judges, and new badge claim!

Since we didn’t show enoug last time when trying to clam the Retro badge, here we go again! Here we will show how we used paint to create the sause for the Pizza in the Head 2 Head challenge. But, paint wasn’t enoug, so we had to use Power Point as well. Had to make the transparent background in Power Point, as it’s not possible in Paint. We think that all graphic designers would either shoot themself or turn around in their grave if they knew we did this to make a red round object with a transparent background. So, if this is not a dirty hack, then how would you explain why not to the graphic designer that’s about to …… Yeah, you know…

Kapaow! Real time data in Power Apps Portals!

In order to be sure all data in the Covert Operation Center is up to date, we have to make sure caching is disabled. This is not possible by design in portals. But no worries. We have a dirty hack in our sleeves.

In order to reset the cache, we must navigate to /_services/about within the solution and click the “Tøm hurtibuffer” for the page.

Then we can monitor the network when clicking the button and save the request as a fetch request. Then we create a setTimout function with location.location() at the end.

And kapow! We have real-time data as long as the page is open within and browser.

How to make Google Maps work in .NET MAUI!

MAUI is still in Preview. That means it has a relatively small feature set and some of it doesn’t work as you’d expect. The fun part is figuring out how to make it work.

We wanted to implement an interactive map in a portion of our app. Seems like MAUI doesn’t support a solution for it yet. Whoops. Xamarin.Forms, the predecessor of MAUI, does support it but it hasn’t been ported to MAUI yet. So what do you do?

Here’s what we did:

  • Create a React project
  • Implement a React Component that shows Google Maps
  • Pass in location data to create pins
  • Host the app as a separate web app on a website (https://sosmap.vercel.app)
  • Show that React app as a “WebView” inside the MAUI app
    • A webview is a webpage hosted inside your app

Suddenly you have an interactive map in your application.

This isn’t the way MAUI is supposed to work, but a hack while it is in preview!


Also, the React app is hosted with CI/CD for a proper agile workflow.

Bilde gjennkjenning

Vi i Munchmuseet er veldig glade for å kunne lansere en ny funkjsonalitet i Munch besøksappen: GiveMeMoreInfo!

Syns du at maleriene våre vekker interesse, men du skulle gjerne hatt enda mer informasjon om maleriet? Da har vi løsningen for deg!
GiveMeMoreInfo! gir deg mer informasjon om maleriet du ser på gjennom applikasjonen. Det eneste du trenger å gjøre er å ta et bilde av maleriet, og informasjonen hentes inn automatisk!

Link til video: https://youtu.be/DUkVdxUdlGI

Teknisk informasjon:

  • Vi bruker Ai Builder for å gjenkjenne ulike malerier. Denne har blitt trent ved bruk av ca. 15 bilder fra hvert maleri. (Litt Nasty??)
  • Vi bruker en Power Automate for å motta bilde fra Canvas Appen, sender bildet videre til AI modellen som returnerer hvilket bildet det kjenner igjen i fotografiet tatt fra Canvas Applikasjonen.

I fremtiden håper vi å kunne bruke appliasjonen for å:

  • Utvide til å gi tilpasset informasjon baser på alder f.eks
  • Gi informasjon om lignende mallerier du kunne ha likt som Museet også har inne eller i sin virtuelle samling
  • Gi forslag til besøk i andre museer basert på dine interesser.
  • Vise hvordan bildet faktisk så ut da den ble laget ( mallerier er ofte gule grunnet at coaten over har decomponert grunnet UV lys og ligende)