Med cURL och jq går det att extrahera data från API:er direkt från kommandoraden. Jq är en JSON-tolkare och beskrivs av utvecklarna som sed och awk för JSON.

Arkiv Bild: Pexels

Här kommer vi att extrahera aktuell temperatur med tidsstämpel från SMHIs öppna API. Detta är samma API som vi använde i Pythonmiljö i Docker.

API:et vi kommer hämta temperaturen från är http://opendata-download-metobs.smhi.se/api/version/1.0/parameter/1/station/62180/period/latest-hour/data.json.

För att slippa ange den långa adressen till API:et varenda gång vi ska laborera med jq kommer vi att spara ner svaret i en variabel.

$> smhidata=$(curl -s http://opendata-download-metobs.smhi.se/api/version/1.0/parameter/1/station/62180/period/latest-hour/data.json) 

Skriver vi ut innehållet från variabeln är det oformaterad JSON, vilket är väldigt svårläst.

$> echo $smhidata
{"value":[{"date":1659776400000,"value":"16.0","quality":"G"}],"updated":1659776400000,"parameter":{"key":"1","name":"Lufttemperatur","summary":"momentanvärde, 1 gång/tim","unit":"degree celsius"},"station":{"key":"62180","name":"Ängelholm-Barkåkra Flygplats","owner":"...

Vi börjar därför med att skriva ut JSON-filen med hjälp av jq så att den blir snyggt formaterad. Vi skriver ut innehållet med echo $smhidata | jq. Början av innehållet ser ut som nedan (innehållet är längre än vad som visas här):

{
  "value": [
    {
      "date": 1659776400000,
      "value": "16.0",
      "quality": "G"
    }
  ],
  "updated": 1659776400000,
  "parameter": {
    "key": "1",
    "name": "Lufttemperatur",
    "summary": "momentanvärde, 1 gång/tim",
    "unit": "degree celsius"
  },
  "station": {
    "key": "62180",
    "name": "Ängelholm-Barkåkra Flygplats",
    "owner": "Ängelholm Helsingborgs flygplats Holding AB",
    "ownerCategory": "CLIMATE",
    "measuringStations": "CORE",
    "height": 2
  },

Det som vi är intresserade av är bara temperaturen och tidsstämpeln. Dessa ligger i den yttre nivån i value. Vi börjar därför med att skriva ut endast detta:

$> echo $smhidata | jq -r '.value'
[
  {
    "date": 1659776400000,
    "value": "16.0",
    "quality": "G"
  }
]

Temperaturen och tidsstämpeln ligger här på den andra nivån, det vill säga innanför []. För att komma åt dessa värden behöver vi således först ta oss ner den nivån. Det gör vi genom att lägga till just [] efter value:

ANNONS FÖR VÅRA EGNA BÖCKER Demonerna på internet

$> echo $smhidata | jq -r '.value[]'
{
  "date": 1659776400000,
  "value": "16.0",
  "quality": "G"
} 

Nu kan vi fortsätta med att extrahera value, alltså temperaturen:

$> echo $smhidata | jq -r '.value[].value'
16.0

Tidsstämpeln kommer vi åt på samma sätt:

$> echo $smhidata | jq -r '.value[].date'
1659776400000

Notera dock att tidsstämpeln är i UNIX epoch time. Ett tidsformat som mäter antalet sekunder som förfallit sedan midnatt den 1 januari 1970 UTC. Men i detta fallet är formatet i millisekunder, vilket ställer till det vid omvandlingen till vanligt datumformat. Vi behöver därför först dividera talet med 1000 så att vi får det i sekunder. Till detta kan vi använda verktyget bc som står för Basic Calculator.

För att sedan omvandla från UNIX epoch time till vanligt datumformat använder vi date-kommandot. I Linux gör vi omvandlingen med date -d @$timestamp. Men under macOS använder vi istället date -r $timestamp.

$> timestamp=$(echo $smhidata | jq -r '.value[].date')
$> timestamp=$(echo "$timestamp / 1000" | bc)
$> date -d @$timestamp
lör  6 aug 2022 11:00:00 CEST

Vi kan också skriva ut flera fält samtidigt med jq. Vi behöver således inte skriva ut temperaturen och tidsstämpeln var för sig. Vi separar dem då med ett kommatecken.

$> echo $smhidata | jq -r '.value[].value, .value[].date'
16.0
1659776400000

Ett skript

Det är dags att sätta samman allting i ett skript. Här använder vi xargs för att göra hela omvandlingen från UNIX epoch time till vanligt datum på en och samma rad. xargs -I % talar om att vi vill föra in utdatan (tidsstämpeln utan millisekunder) vid platsen för procenttecknet, vilket här blir direkt efter @-tecknet för date-kommandot.

#!/bin/bash
PATH="/bin:/usr/bin:/usr/local/bin:/sbin:/usr/sbin:/usr/local/sbin"

## Spara båda värdena till en variabel. De hamnar som en sträng efter varandra
smhidata=$(curl -s http://opendata-download-metobs.smhi.se/api/version/1.0/parameter/1/station/62180/period/latest-hour/data.json \
    | jq -r '.value[].value, .value[].date')

## Första fältet i strängen är temperaturen
temperature=$(echo $smhidata | awk '{ print $1 }')

## Andra fältet i strängen är tidsstämpeln
timestamp=$(echo $smhidata | awk '{ print $2 }')

## Skriv ut resultatet och fixa tidsstämpeln med xargs för att slippa dubbla rader
echo "$temperature grader ($(echo $timestamp / 1000 | bc | xargs -I % date -d @%))"

När vi kör ovanstående skript får vi följande resultat:

$> ./get-smhi-data.sh
17.1 grader (lör  6 aug 2022 14:00:00 CEST)

Du hittar mer information om jqstedolan.github.io/jq. Mer information om curl hittar du på curl.se. Det finns också mycket information i deras respektive manualsida, man jq och man curl. För mer information om bc och xargs, se man bc och man xargs. För mer information om awk se man awk.