Google Sheets: databáze chudého muže

Získat měřením libvolnou sadu hodnot je zpravidla ta jednodušší polovina úkolu, druhá bývá náročnější — rozumně data zpracovat, uložit a zobrazit. V tomto zápisku se podíváme na zoubek Google Sheets, které mohou zastat všechny tyto role.

V předchozím díle jsme si povídali o měření teploty pomocí 1-wire teploměrů. Pokud máme naměřené hodnoty, bylo by šikovné data vizualizovat tak, aby byly patrné aktuální hodnoty a trendy. Typicky můžete teploměry měřit teplotu na chatě a před příjezdem zkontrolovat, do jak velké zimy se můžete těšit.

Ukázkový graf z Google Sheets

Google Sheets jsou klasický spreadsheet, který jistě znáte. Když se ale vhodně zkombinují s technologií Google Forms a trochou Python magie, můžete je použít jako jednoduchou time series databázi.

Google Forms

Pro naší hypotetickou úlohu budeme chtít ukládat a vizualizovat hodnoty ze dvou různých datových řad, řekněme z vnějšího a vnitřního teploměru. V Google Forms si vytvoříme nový formulář kliknutím na tlačítko  vpravo dole. Formulář si interaktivně můžeme pojmenovat (název může být libovolný), první políčko nazveme „Vnitřní teplota“ a typ nastavíme na , obdobně přidáme druhé políčko stisknutím tlačítka (Duplikovat) a vyplněním „Vnější teplota.“ Cílem je formulář vypadající takto:

Ukázkový Google Formulář
Ukázkový Google Formulář

Nyní se přepneme na záložku Odpovědi, kde klikneme na tlačítko (Vytvoření tabulky). Zde si vybereme nebo vytvoříme nový Google Sheet dokument. Po nastastavení tabulky opět klikneme na  a zobrazí se nám propojená tabulka. Tady následuje důležitý krok, v menu Soubor / Nastavení tabulky… musíme změnit nastavení Jazyk na Spojené státy (jinak nám nebude fungovat korektně zpracování desetinných čísel).

Získání odkazu na Google Form

Přepneme se zpátky na návrh formuláře a klikneme na tlačítko Poslat (vpravo nahoře). V dialogu vybereme záložku pro získání odkazu, ikona . Stiskneme tlačítko Kopírovat a získáme odkaz ve tvaru:

https://docs.google.com/forms/d/e/1FAIpQLSdrmpMxSicngT1OCV9aFPC-VDtOVxEFzg0hk5JRSbjbhpIeNw/viewform?usp=sf_link

Tento odkaz nám nyní poslouží k troše reverse engeneeringu. Google si totiž každé vstupní pole mapuje na vlastní jednoznačný identifikátor. Ten pro každé vstupní pole musíme někde získat.

Otevřeme si tedy odkaz v prohlížeči (samozřejmě váš odkaz, ne můj 🙂 ) a uvidíme náš formulář, který můžeme vyplnit. Než to ale zkusíme, otevřeme si v prohlížeči ještě Nástroje pro vývojáře (v Google Chrome to jsou DevTools a klávesová zkratka Ctrl+Shift+I) ve kterých se přepneme na záložku Network.

A nyní do každého políčka formuláře napíše libovolný jedinečný text, který nám umožní toto políčko za chvíli identifikovat, třeba takhle:

Klikneme na Odeslat a podíváme se do DevTools na síťový provoz. Podle sloupce Name najdeme dokument nazvaný formResponse, ten rozklikneme a jdeme dolovat.

První položka, která nás zajímá, je URL, na které data odešla. V části General / Request URL náme něco v tomto tvaru:

https://docs.google.com/forms/d/e/1FAIpQLSdrmpMxSicngT1OCV9aFPC-VDtOVxEFzg0hk5JRSbjbhpIeNw/formResponse

Druhá pro nás důležitá informace je mapování parametrů na jednoznačná ID pro tento konkrétní formulář. V panelu Network se posuneme až na konec a tady vidíme část Form Data:

A odtud si již můžeme sepsat (proto jsme chtěli unikátní hodnoty), mapování formulářových polí:

  • Vnitřní teplota — entry.1436654893
  • Hodnota 456 je Vnější teplota — entry.1962412269

Teď máme vše, co jsme potřebovali k programovému zasílání dat, tj. URL, na které budeme posílat data a identifikátory, pod kterými data budeme posílat.

Vyplňování formuláře z Pythonu

Poslání formuláře z Pythonu je již trivialitou, obzvláště pokud použijeme modul requests. Tenhle šikovný nástroj nám zásadně usnadní poskládání dat pro zaslání pomocí HTTP POST spolu s korektním obsloužením chyb, takže vzhůru k kódu:

import requests

FORM_URL = "https://docs.google.com/forms/d/e/1FAIpQLSdrmpMxSicngT1OCV9aFPC-VDtOVxEFzg0hk5JRSbjbhpIeNw/formResponse"

ID_VNITRNI = "entry.1436654893"
ID_VNEJSI = "entry.1962412269"

vnitrni = 21.3
vnejsi = -5.7

post_data = {
        ID_VNITRNI: vnitrni,
        ID_VNEJSI: vnejsi,
}
response = requests.post(FORM_URL, data=post_data)
response.raise_for_status()

V kódu je nejprve naimportován modul requests, dále jsou nadefinovány konstanty, které jsme získali v předchozím kroku z našeho formuláře. Řádky 8 a 9 přiřazují naměřené hodnoty proměnným, tyto si v reálném kódu nahraďte funkcemi měřícími teplotu, třeba těmi z předchozího zápisku o 1-wire teploměrech. Do slovníku post_data uložíme naměřené hodnoty pod identifikátory jednotlivých políček formuláře. Řádkem 15 tato data pošleme pomocí HTTP metody POST do Google Forms, získáme návratovou odpověď a v případě, že došlo k chybě na řádku 16 vyvoláme výjimku.

Po spuštění tohoto kódu se můžete přesvědčit, že do tabulky propojené s formulářem přibyla nová řádka společně s časovou značkou odeslání:

Nyní již máte data uložena v Google Sheet a můžete použít libovolný z grafů, popř. libovolnou agregační funkci, jako je minimum nebo průměr pro vizualizaci dat vám, uživateli. Th-th-th-that’s all folks!

Závěrem

Pokud některou položku nechcete odesílat (třeba, že se vám její hodnotu nepovedlo změřit), prostě ji ve výsledném slovníku neuvádějte, Google Forms do tabulky vloží prázdnou hodnotu.

Uvedený způsob ukládání dat je elegantní a rychlý především pro prototypování, v principu se jedná o jednoduché poskládání HTTP POST. Odtud je už jen krok k tomu použít nějaké sofistikovanější řešení typu InfluxDB a Grafana, kde sice můžete mít mnohem hezčí grafy a metery, ale jejich zprovoznění je mnohonásobně náročnější, než založení formuláře v Google Form.

Případné dotazy a návrhy diskutujte opět ve vláknech tohoto twítu, a pokud se vám článek líbil, sdílejte!