Geschaatst

Laat me beginnen met de mensen van de Stichting IJsbaan Zeist te bedanken. Door hun harde werk van afgelopen dagen, maandagmiddag: zeister-ijsmakers-werken-hard-aan-gladde-ijsvloer, maandagavond: zeister-ijsbaan-gaat-naar-verwachting-dinsdag-om-8-00-uur-open. En dan uiteindelijk vanochtend kom-schaatsen-op-natuurijs-in-zeist. Ik heb vanochtend een paar heel lekkere rondjes kunnen schaatsen op een prachtige strakke ijsbaan.

Dit is toch genieten in optima forma

mastodon

With love from POJO/DTO – JAVA

It’s now few months ago I found the POJO/DTO way of serializing and deserializing of JSON and AVRO messages. Now using it everywhere. It’s just as easy as ‘describe’ your json message in a Java Class. Initize it. Fill it with your data and Map it to the Jackson ObjectMapper and ready to go.

Create 3 classes:

class NameDTO{
	String Name;
}
class EmailDTO{
	String email;
}
class TopdeskDTO{
	EmailDTO callerLookup;
	String status;
	String briefDescription;
	String request;
	NameDTO callType;
	NameDTO category;
	NameDTO subcategory;
}

Generate the needed getters and setters, for a new Topdesk ticket payload. Actually generating a json string is now no more than:

  TopdeskDTO dto = new TopdeskDTO();
  dto.setCallerLookup(new EmailDTO("mymail@mydomain.com"));
  dto.setStatus("open");
  dto.setBriefDescription("some brief description");
  dto.setRequest("Information about the issue, can even be something in base html");
  dto.setCallType(new NameDTO("Incident")); //fixed value
  dto.setCategory(new NameDTO("Valid Category from Topdesk"));
  dto.setSubcategory(new NameDTO("Valid Subcategory from Topdesk"));

  ObjectMapper mapper = new ObjectMapper();
  String json = mapper.writerWithDefaultPrettyPrinter().writeValueAsString(dto);

This results in this json string:

{
  "callerLookup" : {
    "email" : "mymail@mydomain.com"
  },
  "status" : "open",
  "briefDescription" : "some brief description",
  "request" : "Information about the issue, can even be something in base html",
  "callType" : {
    "name" : "Incident"
  },
  "category" : {
    "name" : "Valid Category from Topdesk"
  },
  "subcategory" : {
    "name" : "Valid Subcategory from Topdesk"
  }
}

Fun thing with such a POJO is, that you can also use it in a reversed way. Map your (matching) json on the POJO and and the data is available in java.

String json = {[...]};

ObjectMapper mapper = new ObjectMapper();
TopdeskDTO dto = mapper.readValue(json, TopdeskDTO.class);

Now the dto contains the data from the json string. Input can be anything. In this case it’s a string, but in most of the solutions, the input is of type inputStream (a file reader).

https://social.oarsnet.nl/@johannes/111600087614823900

Git en Github

Created a Github account today:

https://github.com/JohannesKalma

Linked the Github to my local Git repository. Now when I do a commit with a push to my local repository, I have to do another push to sync with Github. The local commit is for the bleeding edge (daily commits). When I want to make things available for the world, I’ll do the github push.

Plee kalender, dure kinderen

Vraag: “Op welke leeftijd is een kind het duurst?”

Antwoord: Zestien en zeventienjarigen.

Redenatie: Jonge kinderen hebben luiers, opvang en fruithapjes nodig. Volgens onderzoek is dat 17% van de gezinsbestedingen op een leeftijd van 0 tot 5 jaar. Maar zodra het puberstadium op zijn top is, slokken ze meer dan 20% van het gezinsbudget op. En als je er twee of meer van hebt, kan dat oplopen tot 33%, ja dat is een derde van het totale gezinsbudget. Pubers vreten je portemonnee op en eisen alleen maar meer geld voor sport kleding mobieltje chips cola snoep en zakgeld.

Plee kalender, vitamine dooddoeners?

Vanochtend weer even bijgepraat door mijn plee kalender. Laat ik met een dooddoener beginnen. Een echte dooddoener. Vraag: “Zijn toegevoegde vitamines in voeding wel gezond?”. Antwoord wat we allemaal wel weten. Het is een marketingtrucje volgens de Wageningen deskundigen. Vitamine C toevoegen aan vruchtensapjes of yoghurtjes is compleet nutteloos. Eet liever groente of fruit. Is niet alleen een normale bron van vitamines, maar is in 100% van de gevallen ook veel gezonder. Ik noem suiker en zeg verder niks. Gewoon normaal gezond eten, dan heb je al die gefabriceerde meuk helemaal niet nodig. Het is dus niet zozeer dat die toegevoegde vitamines nou ongezond zijn, maar de rest van de toevoegingen. Er is blijkbaar een uitzondering voor vitamine B12, maar dat is dan weer speciaal voor veganisten. Die hebben daar een tekort aan. Denk je dus op je veganistische tenenslippers gezond bezig te zijn, ga je toch nog dood aan vitamine B12 tekort. Maar dat is dan ook een keuze.

Conclusie. Niet alleen het toevoegen van vitamines is totaal nutteloos. Het produkt waar het aan is toegevoegd is nutteloos. Maar ja wel een hele groep marketingmensen die dan weer broodloos worden. Hopelijk werken er niet teveel veganisten als marketingmens op die afdelingen. Broodloos en ook nog eens een tekort aan vitamine B12. Einde.

NodeJS app weergeven p1monitor data

Voor het even snel bekijken waar onze zonnepanelen nu mee bezig zijn, heb ik een raspberry pi met daarop p1monitor gekoppeld aan onze slimme meter. p1monitor heeft een complete website geintegreerd, maar deze is niet responsive en schaalt helemaal niet lekker op een telefoon. En al die grafische metertjes zijn leuk, maar een eenvoudige tabelweergave is voor mij meer dan voldoende:

Dit is alles wat ik wil:

Een eenvoudig projectje, wat in een half uurtje is op te zetten.

Ik begin met het maken van een lege git repository op onze server. Deze repository wordt vervolgens op mijn chromebook gecloned naar een map die vervolgens in Visual Studio Code wordt geconfigureerd als workfolder. De ‘live’ app zal vervolgens met een pull bijgewerkt worden.

chromebook dev (vsc) — commit push –> central repository — pull — app

Hoe ik de git repo opzet, heb ik hier beschreven: New Git Repository.

In mijn geval heb ik een project gemaakt p1monitor-api. Deze ga ik eerst opzetten als een standaard nodejs express applicatie met ejs als template systeem. Deze app moet 2 dingen doen:

  1. data ophalen van de p1monitor api en deze ‘ombouwen’ naar een lokale api
  2. Deze api data op een heel eenvoudige website tonen, met een refresh-rate van 10 seconden.

Opzetten van een express applicatie (waarbij ik ervanuit ga dat een draaiende nodejs applicatie is geinstalleerd) is een fluitje van een cent. Draai daarvoor het volgende commando vanuit de werkfolder:

npx express-generator --view ejs --css --git

Na uitvoer van dit commando is dit de projectmap structuur:

Om de boel initieel draaiend te krijgen, voer ik in de folder het volgende 2 commando’s uit:

npm install
npm start

De eerste voert de installatie van de packages uit de package.json uit en het tweede commando start de applicatie op poort 3000.

Start in een browser de volgende url: localhost:3000 en als alles goed is krijg je deze pagina voorgeschoteld:

Het fundament van de applicatie werkt nu.

Het gaat hier om SPA een single page die gevoed wordt met data uit een rest api. Laten we met het eenvoudigste deel eerst verder gaan. Het allereenvoudigst nu is om de index.ejs aan te passen. Er zou ook voor een fixed index.html kunnen worden gekozen. Maar dat is voor nu meer aanpaswerk in de routers. Er wordt geen dynamic pagina data geproduceerd. De index.ejs is 100% html.

index.ejs:

<!DOCTYPE html>
<html>
  <head>
    <title>P1 data</title>
    <link rel='stylesheet' href='/stylesheets/style.css' />
  </head>
  <body>
    <h2>Huidig</h2>
    <p>Verbruik: <span id="wattcons"></span>&nbsp;<span>watt</span></p>
    <p>Levering: <span id="wattprod"></span>&nbsp;<span>watt</span></p>

    <h2>Dag</h2>
    <p>Verbruikt: <span id="kwhcons"></span>&nbsp;<span>kWh</span></p>
    <p>Geleverd: <span id="kwhprod"></span>&nbsp;<span>kWh</span></p>
    <br>
    <p>Gas: <span id="m3"></span>&nbsp;<span>m<sup>3</sup></span></p>
  </body>
</html>

Het ophalen van de data en deze realtime weergeven wordt met een brokje javascript gedaan. Omdat dit een zo minimale website is, heb ik het javascript in de body geplaatst. Om te beginnen heb ik Axios als http handler gebruikt:

<script src="https://unpkg.com/axios/dist/axios.min.js"></script>

Vervolgens het script om api data op te halen (2 endpoints) en dit in de website te parsen.

<script>

async function getData() {
  try {
    let endpoints = [
    './api/current',
    './api/day'
  ];

  Promise.all(endpoints.map((endpoint) => axios.get(endpoint))).then(([{data: current}, {data: day}] )=> {
        document.getElementById('wattcons').innerHTML=current.CONSUMPTION_W;
        document.getElementById('wattprod').innerHTML=current.PRODUCTION_W;
        document.getElementById('kwhcons').innerHTML=day.CONSUMPTION_DELTA_KWH.toFixed(1);
        document.getElementById('kwhprod').innerHTML=day.PRODUCTION_DELTA_KWH.toFixed(1);
        document.getElementById('m3').innerHTML=day.CONSUMPTION_GAS_DELTA_M3.toFixed(1);
      });
  } catch (error) {
    console.error(error);
  }
}

getData();
setInterval(function(){
   getData();
}, 10000);

</script>

Deze pagina laadt nu wel, maar zal in de console 404 meldingen geven. Er moeten nog 2 api’s worden toegevoegd. /api/day en /api/current/. Allereerst de router zelf. Deze maakt gebruik van Axios om data van de p1 rest api te halen en door de routen naar onze rest api. Installeer deze eerst (en save als dependency):

npm install axios -s

Voor de router zelf herbruik de user.js in de routes folder. Deze hernoem ik naar api.js en vervang alles met deze code:

const createError = require('http-errors');

const express = require('express');
const router = express.Router();
const axios = require('axios');

router.get('/day', async function(req, res, next) {
    try {
        const response = await axios.get('http://p1monitor/api/v1/powergas/day?limit=1&json=object');
        console.log(response.data[0]);
        res.json(response.data[0]);
    } catch (error) {
        console.error(error);
        res.json({message:error});
      }
});

router.get('/current', async function(req, res, next) {
    try {
        const response = await axios.get('http://p1monitor/api/v1/smartmeter?limit=1&json=object');
        //console.log(response.data[0]);
        res.json(response.data[0]);
    } catch (error) {
        console.error(error);
        res.json({message:error});
      }
});

/* GET users listing. */
router.get('/', async function(req, res, next) {
    res.render('p1');
});

module.exports = router;

Nu moet de api nog bekend worden gemaakt als router mogelijkheid. Hiervoor pas ik de user regel aan naar api in de app.js:

var indexRouter = require('./routes/index');
//var usersRouter = require('./routes/users');
var apiRouter = require('./routes/api');

en

app.use('/', indexRouter);
//app.use('/users', usersRouter);
app.use('/api', apiRouter);

Voordat dit alles geupload wordt naar de git repo, eerst nog 2 bestanden toevoegen .env en .gitignore. Die .env doen we nu nog even niks mee, maar de .gitignore wel. Zo hoeft de hele node_modules boom niet geimporteerd te worden. En nog wat andere directories ook niet. Er zijn talloze voorbeelden te vinden op internet, wat wel en wat niet. De mijne ziet er zo uit:

Deze variant werkt heel goed, binnen mijn eigen netwerk, waarbij aangenomen wordt dat de raspberry pi in de netwerk dns bekend is als p1monitor. Als je deze app ook buiten de deur wil gebruiken, dan zul je een portforward in je modem router moeten instellen. Deze instelling valt ver buiten de scope van deze blog en is per modem en provider anders. Voor de beeldvorming, bij ons thuis is het geconfigureerd in de fritzbox en is deze gekoppeld via een dynamic dns service.

Daarom toch nog maar even wat aanpassingen. Om de environment file beschikbaar te stellen, is het nodig om dotenv te installeren:

npm install dotenv -s

De .env file wordt nu gevuld met een aantal variabelen. Omdat ik deze app achter een proxie draai, is het in sommige gevallen nodig om het volledige pad op te nemen. Omdat ik meerdere apps draai, heb ik verschillende poortnummers. In ontwikkel is 3000 prima, maar in produktie zal het iets van 30006 worden. Het is de zevende app. Ook de url van de p1monitor is beter om die niet wereldkundig te maken. De eerste stap van security is de obscurity :-). Daarom 3 parameters, die ik in ontwikkel vul met ontwikkelwaardes:

Om dotenv te gebruiken, zet ik gewoonlijk deze regel ergens bovenin de app.js file, in ieder geval ergens voordat de config gebruikt moet worden.

require('dotenv').config()

Het gebruik van het poortnummer uit deze file wordt in de /bin/www file gebruikt. Hoeft niks voor te gebeuren.

Zie deze regel

Ik persoonlijk voeg aan het eind van deze file nog even een console message toe:

Als de app nu opnieuw gestart wordt, dan krijg je dit in de log te zien:

Vraag aan chatGPT: Ken je een goede voetreflex therapeut in Zeist.

Om een goede voetreflextherapeut in Zeist te vinden, raad ik je aan om de volgende stappen te volgen:

  1. Vraag om aanbevelingen: Vraag vrienden, familieleden of collega’s of ze een goede voetreflextherapeut in Zeist kennen. Persoonlijke aanbevelingen kunnen waardevol zijn.
  2. Online zoeken: Gebruik online zoekmachines en sociale media om voetreflextherapeuten in Zeist te vinden. Je kunt zoektermen zoals “voetreflextherapeut Zeist” gebruiken.
  3. Check recensies: Als je potentiële therapeuten hebt gevonden, zoek dan naar recensies en beoordelingen van hun diensten. Dit kan je een idee geven van de ervaringen van andere patiënten.
  4. Contact opnemen: Neem contact op met de therapeuten die je interesseren en stel vragen over hun achtergrond, ervaring en behandelingsaanpak. Dit kan je helpen om te bepalen of ze geschikt zijn voor jouw behoeften.
  5. Raadpleeg brancheorganisaties: Je kunt ook contact opnemen met brancheorganisaties voor complementaire en alternatieve geneeskunde, zoals de Vereniging van Nederlandse Reflexzone Therapeuten (VNRT), voor aanbevelingen.
  6. Overleg met je huisarts: Als je twijfelt of voetreflextherapie geschikt is voor jouw specifieke gezondheidssituatie, overleg dan met je huisarts voordat je een therapeut kiest.

Onthoud dat het belangrijk is om met een gekwalificeerde en erkende voetreflextherapeut te werken om de beste zorg te ontvangen.

Advies van Johannes : voetreflextherapie-zeist.nl

Aan alles komt een eind

In Oktober vorig jaar zijn we overgestapt van Ziggo naar glasvezel. Ons emailadres bleef nog wel bestaan, maar sinds vandaag krijg je direct een ‘Undelivered Mail Returned to Sender’ terug.

Weggaan van Ziggo was toch wel even een dingetje. Want je moet weten dat ik in 1994, toen ik nog in Wageningen studeerde, mee ging doen aan een studenteninternetproject. Daarvoor kreeg je een kabelmodem op je kamer die via de tv aansluiting was aangesloten op het universiteitsnetwerk. Het was de begintijd van internet, het www was net een jaar geleden uitgevonden en er bestonden een paar duizend internetpagina’s. Maar goed vanaf het allereerste begin had ik dus een kabelmodem. Eerst een 10 megabits, wat voor die tijd natuurlijk waanzinnig snel was. Iedereen zat nog met 24k4 modems te kloten met een xs4all verbinding ed de echt snellen hadden een 56k6 modem. En ik, ik had 10 Megabit. De verhouding was natuurlijk helemaal zoek.

Even een verhaaltje tussendoor. Je moet weten dat in de begintijd van internet bestonden er geen zoekmachines. Alles was met links aan elkaar vastgeknoopt. In je Mosaic browser moest je bookmarks van websites opslaan als referentie. Mosaic, de prehistorie van webbrowsen. Ver voordat Netscape, Chrome, Internet Explorer bestonden.

Maar goed met Joost, een vriend van me, had ik gehoord dat je ‘porno plaatjes’ op internet kon vinden. Dat is uiteindelijk een zoektocht geworden van een paar weken. En toen hadden we 1 zeer lage resolutie gif van een paar tieten gevonden. Later bleek dat we helemaal verkeerd zochten. Voor vunzigheid moest je niet op het www zijn, maar op een veel duisterder plek, de nieuwsgroepen. Daar werd de porno per kilo geupload – toen moest je de berichten nog wel handmatig decripten naar bruikbare plaatjes. En later toen ik werkte had ik een projectleider die avonden en nachten al die nieuwsgroepen leeg zat te slurpen. En alles op cd-roms brandde en uitdeelde op zijn werk. Was een beetje een vies mannetje.

Maar goed terug naar het kabelmodem. In 1994 had ik dus al een kabelmodem. En ik ben eigenlijk altijd bij ziggo en alle voorgangers gebleven. Ook toen ik verhuisde van de studentenflat naar een gewone flat en later naar Zeist. Tot afgelopen November heb ik dus nooit anders dan kabelinternet gehad. Maar afgelopen jaar hebben ze de hele wijk aangesloten op glasvezel en een aanbieder kwam met wel een heel scherpe prijs van 1gig verbinding voor een paar tientjes per maand. Dat scheelde me dit jaar ongeveer 450 euro. Geld waar je ook andere dingen voor kunt doen.

Na 28 jaar heb ik daarom afscheid genomen van de good old kabel. En om eerlijk te zijn, het bevalt goed.

Gas tarieven

Vandaag een offerte gekregen van een energieleverancier. Naam doet er niet zoveel toe. Ik schrok van de inhaligheid van onze overheid. Omdat wij niet op gas stoken en koken, verbruiken wij wat gas om te douchen. Hier gaan we van uit dat we zo rond de 300 kuub per jaar verstoken in onze huishouding.

In de nu voor me liggende offerte komen we dan op ruim 700 euro per jaar uit. Wie snoept er wat op van dit bedrag:

WieEenheidsprijsAantalBedrag% van totaal
Levering€ 0,76 (incl btw) per kuub300 kuub€ 22833%
Overheidsheffing (belasting€ 0,49 met daarover € 0,10 btw per kuub300 kuub€ 17825%
Vaste leveringskosten€ 7,79 per maand12 maanden€ 9313%
Netbeheerkosten Stedin€ 17,25 per maand12 maanden€ 20729%
Totaal€ 706

Vooral die kwart overheidsheffing. Zoals op de nota is het 0.49 per kuub zonder btw. Dat is een hele grote wtf. We betalen dus belasting over een belasting. Hoe fucking transparant wil je het hebben. Dat spekken van de staatskas, moeten we snel mee stoppen. En 700 euro waarvan 66% vaste kosten uitgeven om een beetje te douchen vind ik persoonlijk een iets minder plan.

Laat me niet teveel in de negatieve emotie blijven hangen en deze ombuigen naar positieve energie. Energie die er al is. De zon. Zonnepanelen hebben we al. Maar, zoals eerder gezegd, gas gebruiken we om te douchen. Kunnen we die zonneenergie niet gebruiken om te douchen en is een warmwaterboiler misschien een oplossing. Zo’n boiler ken ik nog van vroeger. Dat was altijd op = op en dan maar koud afdouchen en lekker door het huis schreeuwen: ‘Wie heeft %$#@^&*(&# al het water verbruikt’. Maar daar worden we hard van.

Maar het kan nog extremer. Deze boiler aansluiten op electra EN een eigen zonnewarmtecollector. We hebben nog een stukje dak over (de dakkapel), kunnen we daar nou niet iets met een zonneboiler gaan doen. Ga ik even over nadenken.