Už delší dobu jsem uvažoval, že si domů pořídím meteorologickou stanici s možností posílat data někam na server. S ohledem na cenu jsem uvažoval především o tom, že si postavím něco na ESP8266. Home made řešení je super zábava na dlouhé hodiny :). Horší to je pak se samotným provozem. Venkovní čidla by musela být napájená z baterie, a i při rozumné optimalizaci odběru a použití např. článků 18650 se i tak nevyhnu hlídání stavu baterií, relativně častému nabíjení baterií atd. Taky bych musel vymyslet umístění stanice, jelikož nemám terasu kam bych jí mohl položit. Všechny tyto důvody, spolu s nedostatkem času, mě nakonec vedli k zamyšlení, jestli není možné získat tyto data z nějakého kvalitního veřejného zdroje. Podmínkou především bylo to, aby se čidla, stanice nacházeli co nejblíže mému bydlišti a poskytovala v rámci možností stabilně kvalitní data.

Meteorologické stanice státních institucí a škol byla moje první volba. Při jejich využití narazíte ale na dva problémy:

  • stanice se často nachází kilometry od bydliště, logicky hustota těchto stanic není především na venkově velká
  • často nemají veřejné API

METAR, TAF

Metaris – http://metaris.tucnacek.cz/
Metaris – http://metaris.tucnacek.cz/

Jedná se o velmi kvalitní zdroj, který je možné strojově zpracovávat. Dá se sehnat hned několik veřejných API, včetně různých databank s historickými daty. Kromě aktuálního stavu počasí, nabízí tento zdroj i krátkodobou předpověď (TAF).

Již neaktuální, ale hezký generátor grafů z Metar: http://metaris.tucnacek.cz/. Škoda, že autor již skript neudržuje a nedal jej k dispozici komunitě.

Tento zdroj jsem se rozhodl nepoužít, jelikož se nejbližší meteostanice na LKPR (http://meteo.rlp.cz/) nachází docela daleko od mého bydliště a mou primární motivací bylo nahrazení domácí meteostanice daty z blízkého zdroje.

NETATMO (https://netatmo.com)

Při hledání jsem ale narazil na velmi zajímavý zdroj dat, který nakonec vedl k tomu, že pro mě nedává smysl pořizovat si vlastní meteostanici a vystačím si s daty z tohoto zdroje. Tím zdrojem jsou data z meteostanic Netatmo. Překvapilo mě, kolik stanic se nachází v mém okolí – 4 stanice v okruhu do 1km.

Na tyto stanice jsem narazil před nějakým časem, když jsem hledal způsob jak měřit obsah CO2 v domácnosti (a tím řídit např. mikroventilaci). Čeho jsem si ale před cca 1 rokem nevšiml, jak jsou tyto stanice u nás oblíbené. Stačí se podívat na interaktivní mapu stanic (https://weathermap.netatmo.com/) a na první pohled je vidět, jaké množství těchto stanic se v ČR nachází.

Netatmo Weather Map – https://weathermap.netatmo.com/
Netatmo Weather Map – https://weathermap.netatmo.com/

Nespornou výhodou toho zdoje dat je, že výrobce těchto zařízení nabízí veřejné API pro získání dat z meteostanic. Popis rozhraní najdete na stránce Netatmo Connect.

Operace Getpublicdata slouží pro získaní veřejných dat z meteostanic. Nevrací data pouze za jednu stanici, ale data ze všech stanic ve čtverci, určeného souřadnicemi pravého horního rohu a levého dolního rohu. Např. pro oblast kolem Podolské vodárny a Podolí:

  • lat_ne: 50.0529053, lon_ne: 14.4244606
  • lat_sw: 50.0438864, lon_sw: 14.4138844

Pro získání souřadnic můžete využít Google Mapy, nebo Mapy od Seznamu. Pravým tlačítkem klikněte mimo nějaký objekt a vyberte možnost Co je zde? (What’s here?). Jestli jste neklikli na silnici, nebo nějaký objekt, zobrazí se vám souřadnice daného bodu.

Získání souřadnic pro API rozhraní
Získání souřadnic pro API rozhraní

Samotné volání prostřednictvím GET metody je jednoduché. Při volání je nutné použít tzv. access_token. Jak jej získat ukážu v příštím článku. Pro jednoduché testy si vystačíte s tokenem, pro testy API ze stránek Netatmo. Ve své finální aplikaci byste si měli zaregistrovat svoji vlastní aplikaci. Aplikace si pak na základě id aplikace a klíče vyžádá časově omezený access_token. Zajímavý je ještě parametr filter, který určuje, jestli v odpovědi dostanete i data, která Netatmo hodnotí jako chybná, neobvyklá.

Netatmo API request

Dostanete výstup:


{
    "body": [
        {
            "_id": "70:ee:50:28:b7:3c",
            "place": {
                "location": [
                    14.421939283328,
                    50.04939611442
                ],
                "altitude": 265,
                "timezone": "Europe\/Prague"
            },
            "mark": 15,
            "measures": {
                "02:00:00:28:b7:ac": {
                    "res": {
                        "1518936375": [
                            1.3,
                            83
                        ]
                    },
                    "type": [
                        "temperature",
                        "humidity"
                    ]
                },
                "05:00:00:03:e5:74": {
                    "rain_60min": 0,
                    "rain_24h": 0,
                    "rain_live": 0,
                    "rain_timeutc": 1518936407
                },
                "70:ee:50:28:b7:3c": {
                    "res": {
                        "1518936416": [
                            1029.4
                        ]
                    },
                    "type": [
                        "pressure"
                    ]
                }
            },
            "modules": [
                "05:00:00:03:e5:74",
                "02:00:00:28:b7:ac",
                "06:00:00:01:dd:f0"
            ],
            "module_types": {
                "05:00:00:03:e5:74": "NAModule3",
                "02:00:00:28:b7:ac": "NAModule1",
                "06:00:00:01:dd:f0": "NAModule2"
            }
        },
        {
            "_id": "70:ee:50:01:d0:c2",
            "place": {
                "location": [
                    14.424685478211,
                    50.050989024964
                ],
                "altitude": 261,
                "timezone": "Europe\/Prague"
            },
            "mark": 12,
            "measures": {
                "02:00:00:01:ed:68": {
                    "res": {
                        "1518936453": [
                            -0.1,
                            92
                        ]
                    },
                    "type": [
                        "temperature",
                        "humidity"
                    ]
                },
                "70:ee:50:01:d0:c2": {
                    "res": {
                        "1518936478": [
                            1028.6
                        ]
                    },
                    "type": [
                        "pressure"
                    ]
                }
            },
            "modules": [
                "02:00:00:01:ed:68"
            ],
            "module_types": {
                "02:00:00:01:ed:68": "NAModule1"
            }
        },
        {
            "_id": "70:ee:50:02:79:64",
            "place": {
                "location": [
                    14.4205145,
                    50.0460132
                ],
                "altitude": 214,
                "timezone": "Europe\/Prague"
            },
            "mark": 0,
            "measures": {
                "02:00:00:02:7f:0c": {
                    "res": {
                        "1518936805": [
                            2.3,
                            75
                        ]
                    },
                    "type": [
                        "temperature",
                        "humidity"
                    ]
                },
                "70:ee:50:02:79:64": {
                    "res": {
                        "1518936807": [
                            1029.6
                        ]
                    },
                    "type": [
                        "pressure"
                    ]
                }
            },
            "modules": [
                "02:00:00:02:7f:0c"
            ],
            "module_types": {
                "02:00:00:02:7f:0c": "NAModule1"
            }
        },
        {
            "_id": "70:ee:50:1f:54:2a",
            "place": {
                "location": [
                    14.400754811835,
                    50.044155466943
                ],
                "altitude": 247,
                "timezone": "Europe\/Prague"
            },
            "mark": 15,
            "measures": {
                "02:00:00:1f:74:42": {
                    "res": {
                        "1518936809": [
                            0.5,
                            86
                        ]
                    },
                    "type": [
                        "temperature",
                        "humidity"
                    ]
                },
                "70:ee:50:1f:54:2a": {
                    "res": {
                        "1518936837": [
                            1024.3
                        ]
                    },
                    "type": [
                        "pressure"
                    ]
                }
            },
            "modules": [
                "02:00:00:1f:74:42"
            ],
            "module_types": {
                "02:00:00:1f:74:42": "NAModule1"
            }
        },
        {
            "_id": "70:ee:50:20:f7:58",
            "place": {
                "location": [
                    14.405836,
                    50.04473
                ],
                "timezone": "Europe\/Prague"
            },
            "measures": {
                "05:00:00:02:25:36": {
                    "rain_60min": 0,
                    "rain_24h": 0,
                    "rain_live": 0,
                    "rain_timeutc": 1518936407
                }
            },
            "modules": [
                "02:00:00:20:9e:56",
                "05:00:00:02:25:36"
            ],
            "module_types": {
                "02:00:00:20:9e:56": "NAModule1",
                "05:00:00:02:25:36": "NAModule3"
            }
        },
        {
            "_id": "70:ee:50:04:bc:46",
            "place": {
                "location": [
                    14.423838,
                    50.052702
                ],
                "altitude": 240.808868,
                "timezone": "Europe\/Prague"
            },
            "measures": {
                "70:ee:50:04:bc:46": {
                    "res": {
                        "1518936571": [
                            1021.2
                        ]
                    },
                    "type": [
                        "pressure"
                    ]
                }
            },
            "modules": [
                "02:00:00:04:d3:da"
            ],
            "module_types": {
                "02:00:00:04:d3:da": "NAModule1"
            }
        },
        {
            "_id": "70:ee:50:06:b4:f6",
            "place": {
                "location": [
                    14.4207804,
                    50.0540163
                ],
                "altitude": 207,
                "timezone": "Europe\/Prague"
            },
            "mark": 10,
            "measures": {
                "02:00:00:06:76:dc": {
                    "res": {
                        "1518936294": [
                            1.2,
                            84
                        ]
                    },
                    "type": [
                        "temperature",
                        "humidity"
                    ]
                },
                "70:ee:50:06:b4:f6": {
                    "res": {
                        "1518936341": [
                            1023.4
                        ]
                    },
                    "type": [
                        "pressure"
                    ]
                }
            },
            "modules": [
                "02:00:00:06:76:dc"
            ],
            "module_types": {
                "02:00:00:06:76:dc": "NAModule1"
            }
        },
        {
            "_id": "70:ee:50:29:41:8c",
            "place": {
                "location": [
                    14.422347,
                    50.054761
                ],
                "altitude": 220,
                "timezone": "Europe\/Prague"
            },
            "mark": 12,
            "measures": {
                "02:00:00:29:6b:4c": {
                    "res": {
                        "1518936384": [
                            -0.3,
                            92
                        ]
                    },
                    "type": [
                        "temperature",
                        "humidity"
                    ]
                },
                "05:00:00:04:7f:56": {
                    "rain_60min": 0,
                    "rain_24h": 0,
                    "rain_live": 0,
                    "rain_timeutc": 1518936396
                },
                "06:00:00:02:5e:78": {
                    "wind_strength": 1,
                    "wind_angle": 339,
                    "gust_strength": 2,
                    "gust_angle": 357,
                    "wind_timeutc": 1518936396
                },
                "70:ee:50:29:41:8c": {
                    "res": {
                        "1518936397": [
                            1028.6
                        ]
                    },
                    "type": [
                        "pressure"
                    ]
                }
            },
            "modules": [
                "02:00:00:29:6b:4c",
                "05:00:00:04:7f:56",
                "06:00:00:02:5e:78"
            ],
            "module_types": {
                "02:00:00:29:6b:4c": "NAModule1",
                "05:00:00:04:7f:56": "NAModule3",
                "06:00:00:02:5e:78": "NAModule2"
            }
        },
        {
            "_id": "70:ee:50:28:eb:44",
            "place": {
                "location": [
                    14.4160564,
                    50.0389519
                ],
                "altitude": 263,
                "timezone": "Europe\/Prague"
            },
            "mark": 10,
            "measures": {
                "02:00:00:2b:45:f8": {
                    "res": {
                        "1518936186": [
                            0.9,
                            84
                        ]
                    },
                    "type": [
                        "temperature",
                        "humidity"
                    ]
                },
                "70:ee:50:28:eb:44": {
                    "res": {
                        "1518936204": [
                            1028.1
                        ]
                    },
                    "type": [
                        "pressure"
                    ]
                }
            },
            "modules": [
                "02:00:00:2b:45:f8"
            ],
            "module_types": {
                "02:00:00:2b:45:f8": "NAModule1"
            }
        }
    ],
    "status": "ok",
    "time_exec": 0.03387188911438,
    "time_server": 1518936879
}

Co se týče dokumentace, tak především popis parametrů a především výstupu by mohl být mnohem podrobnější, protože podoba výstupu mi nepřijde moc šťastná a liší se např. pro dešťový senzor, kdy pro teplotu, vlhkost a tlak má příslušný modul atribut type, v případě dešťového modulu tomu tak není. To samé platí i pro modul měření síly a směru větru.

U rozhraní jsou nastaveny limity – Netatmo rate limits. Domnívám se, že pro většinu jednoduchých aplikací jsou tyto limity dostatečné.

K dispozici je samozřejmě více různých zdrojů, z kterých je možné čerpat meteorologická data. Na Netatmo se mi líbí především to, že se jedná o stanice v bezprostřední blízkosti a tak má člověk pocit, jako kdyby data čerpal z vlastní stanice za oknem.

V příštím článku bych chtěl ukázat, jak se napojit na Netatmo API a jak tyto data využít ve své aplikaci.