Skip to content

Instantly share code, notes, and snippets.

@infontology
Last active May 20, 2019 12:19
Show Gist options
  • Save infontology/4706d8908b6783fb6bee19596542f6a2 to your computer and use it in GitHub Desktop.
Save infontology/4706d8908b6783fb6bee19596542f6a2 to your computer and use it in GitHub Desktop.
Display the source blob
Display the rendered blob
Raw
{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Luftdata\n",
"\n",
"Simon Winter, Infontology http://infontology.org\n",
"\n",
"\n",
"\n",
"I den här lektionen ska vi se hur man kan hitta data för luftföroreningar från det nätverk av sammankopplade sensorer som finns på Luftdata.se"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Lektionen går igenom att använda koordinater och att skicka ett anrop till en server och få ett svar som json, titta på svaret och gå igenom det tills man hittar det värde man är intresserad av.\n",
"\n",
"Det enda beroendet är biblioteket requests. https://python-requests.org/ Det finns förinstallerat på exempelvis Colaboratory.\n",
"\n",
"Länk för att köra på Colaboratory: https://colab.research.google.com/github/infontology/luftdata/blob/master/Luftdata.ipynb"
]
},
{
"cell_type": "code",
"execution_count": 74,
"metadata": {},
"outputs": [],
"source": [
"import requests"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"All information vi letar efter finns på luftdata.se. För att deras server ska förstå vår fråga behöver vi ange den i ett speciellt format. Här är ett exempel:\n",
"\n",
"http://api.luftdaten.info/v1/filter/area=55.589579,12.943910,2\n",
"\n",
"Klicka på länken eller kopiera och klistra in den i en webbläsare. Svaret man får innehåller en massa information, och nånstans finns det vi letar efter.\n",
"\n",
"Först ska vi skapa vår egen url, och lägga våra koordinater i variablerna latitude och longitude."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Leta upp dina koordinater på Google maps\n",
"\n",
"Börja med att gå hit för instruktioner om att hitta plats.\n",
"https://support.google.com/maps/answer/18539?co=GENIE.Platform%3DDesktop&hl=sv\n",
"\n",
"Mata in dina värden för latitude och longitude i nästa cell. Tänk på att det är decimalpunkt som gäller.\n",
"\n",
"Om man bor i ett tätbebyggt område och väljer distance till ett högt värde riskerar man att få väldigt många sensorer som svar, så börja med 2-10 kilometer"
]
},
{
"cell_type": "code",
"execution_count": 75,
"metadata": {},
"outputs": [],
"source": [
"latitude = '55.611437'\n",
"longitude = '12.994264'\n",
"distance = '2' # Avstånd i kilometer"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Med hjälp av koordinaterna så skapar vi urlen. Lämna tomma platser inom {} i textsträngen, och ge variabelnamnen i format-parentesen"
]
},
{
"cell_type": "code",
"execution_count": 76,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"'http://api.luftdaten.info/v1/filter/area=55.611437,12.994264,2'"
]
},
"execution_count": 76,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"url = 'http://api.luftdaten.info/v1/filter/area={},{},{}'.format(latitude, longitude, distance)\n",
"url ## Om man ger ett variabelnamn på sista raden av en cell skrivs värdet ut. Det går också att göra print(url)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Requests-biblioteket gör det lätt att hantera frågor till servern. "
]
},
{
"cell_type": "code",
"execution_count": 77,
"metadata": {},
"outputs": [],
"source": [
"response = requests.get(url)"
]
},
{
"cell_type": "code",
"execution_count": 78,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"6"
]
},
"execution_count": 78,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"sensors = response.json()\n",
"number_of_sensors = len(sensors)\n",
"number_of_sensors"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Om number_of_sensors är större än 0 så finns det sensorer i listan. Då kan man få fram sensorvärdena på olika sätt. Det första värdet ligger alltid i sensors[0]"
]
},
{
"cell_type": "code",
"execution_count": 79,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"{'id': 3684368652,\n",
" 'sensor': {'pin': '1',\n",
" 'id': 16149,\n",
" 'sensor_type': {'manufacturer': 'Nova Fitness', 'name': 'SDS011', 'id': 14}},\n",
" 'location': {'country': 'SE',\n",
" 'indoor': 0,\n",
" 'latitude': '55.606',\n",
" 'id': 8180,\n",
" 'altitude': '8.2',\n",
" 'exact_location': 0,\n",
" 'longitude': '13.024'},\n",
" 'sampling_rate': None,\n",
" 'sensordatavalues': [{'id': 7812380304, 'value_type': 'P1', 'value': '15.43'},\n",
" {'id': 7812380306, 'value_type': 'P2', 'value': '12.17'}],\n",
" 'timestamp': '2019-05-20 12:12:29'}"
]
},
"execution_count": 79,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"sensors[0]"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Själva värdena ligger i sensordatavalues"
]
},
{
"cell_type": "code",
"execution_count": 80,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"[{'id': 7812380304, 'value_type': 'P1', 'value': '15.43'},\n",
" {'id': 7812380306, 'value_type': 'P2', 'value': '12.17'}]"
]
},
"execution_count": 80,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"sensors[0]['sensordatavalues']"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Det finns olika typer av värden:\n",
"\n",
"* P1 är PM10, alltså partiklar mindre än 10 mikrometer\n",
"* P2 är PM2.5, alltså partiklar mindre än 2,5 mikrometer\n",
"* temperature är temperatur\n",
"* humidity är luftfuktighet\n",
"* pressure är lufttryck"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Man kan loopa genom sensorvärdena på olika sätt, exempelvis så här:"
]
},
{
"cell_type": "code",
"execution_count": 81,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Sensorvärden:\n",
"{'id': 7812380304, 'value_type': 'P1', 'value': '15.43'}\n",
"{'id': 7812380306, 'value_type': 'P2', 'value': '12.17'}\n",
"\n",
"\n",
"Sensorvärden:\n",
"{'id': 7812380431, 'value_type': 'humidity', 'value': '62.57'}\n",
"{'id': 7812380432, 'value_type': 'pressure', 'value': '100727.06'}\n",
"{'id': 7812380430, 'value_type': 'temperature', 'value': '20.91'}\n",
"{'value_type': 'pressure_at_sealevel', 'value': 100823.04}\n",
"\n",
"\n",
"Sensorvärden:\n",
"{'id': 7812394835, 'value_type': 'P1', 'value': '14.68'}\n",
"{'id': 7812394837, 'value_type': 'P2', 'value': '12.25'}\n",
"\n",
"\n",
"Sensorvärden:\n",
"{'id': 7812414393, 'value_type': 'P1', 'value': '18.17'}\n",
"{'id': 7812414394, 'value_type': 'P2', 'value': '12.43'}\n",
"\n",
"\n",
"Sensorvärden:\n",
"{'id': 7812414500, 'value_type': 'humidity', 'value': '62.53'}\n",
"{'id': 7812414501, 'value_type': 'pressure', 'value': '100717.98'}\n",
"{'id': 7812414499, 'value_type': 'temperature', 'value': '20.87'}\n",
"{'value_type': 'pressure_at_sealevel', 'value': 100813.96}\n",
"\n",
"\n",
"Sensorvärden:\n",
"{'id': 7812429027, 'value_type': 'P1', 'value': '17.07'}\n",
"{'id': 7812429028, 'value_type': 'P2', 'value': '13.03'}\n",
"\n",
"\n"
]
}
],
"source": [
"for sensor in sensors:\n",
" print ('Sensorvärden:')\n",
" for value in sensor['sensordatavalues']:\n",
" print (value)\n",
" print ('\\n')"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Naturvårdsverket har mer information om de här mätvärdena här https://www.naturvardsverket.se/Sa-mar-miljon/Klimat-och-luft/Luftfororeningar/Partiklar/ "
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Här finns gräns- och målvärden för luftkvalitet https://www.naturvardsverket.se/Stod-i-miljoarbetet/Vagledningar/Luft-och-klimat/Miljokvalitetsnormer-for-utomhusluft/Gransvarden-malvarden-utvarderingstrosklar/ "
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Är de värden du fått fram bra eller dåliga om man jämför med gräns- och målvärden?"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Referenser\n",
"\n",
"Baserat på APIet som beskrivs här:\n",
"https://luftdata.se/data/"
]
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.7.2"
}
},
"nbformat": 4,
"nbformat_minor": 2
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment