Obsah:

Zjednodušenie internetu vecí: ESP-MicroPython-MQTT-ThingSpeak: 12 krokov
Zjednodušenie internetu vecí: ESP-MicroPython-MQTT-ThingSpeak: 12 krokov

Video: Zjednodušenie internetu vecí: ESP-MicroPython-MQTT-ThingSpeak: 12 krokov

Video: Zjednodušenie internetu vecí: ESP-MicroPython-MQTT-ThingSpeak: 12 krokov
Video: Tutorial on Micropython Using NodeMCU 2024, Júl
Anonim
Zjednodušenie internetu vecí: ESP-MicroPython-MQTT-ThingSpeak
Zjednodušenie internetu vecí: ESP-MicroPython-MQTT-ThingSpeak

V mojom predchádzajúcom návode, MicroPython na ESP pomocou Jupytera, sme sa naučili nainštalovať a spustiť MicroPython na zariadení ESP. Použitím Jupyter Notebooku ako vývojového prostredia sme sa tiež naučili čítať zo senzorov (teplota, vlhkosť a svietivosť), používame niekoľko komunikačných protokolov a metód, analógové, digitálne, 1-Wire a I2C, tento posledný na zobrazenie našich zachytených údaje na OLED displeji.

Teraz v tomto návode pomocou protokolu MQTT získame všetky zachytené údaje a odošleme ich do služby IoT, ThingSpeak.com a do mobilnej aplikácie (Thingsview), kde sa môžeme prihlásiť a hrať s dátami.

Tu je blokový diagram nášho projektu:

Obrázok
Obrázok

Krok 1: BoM - kusovník

  1. NodeMCU - 8,39 USD
  2. Snímač teploty a relatívnej vlhkosti DHT22 - 9,95 USD
  3. Vodotesný snímač teploty DS18B20 - 5,95 USD
  4. OLED displej SSD1366- 8,99 USD (voliteľné)
  5. LDR (1x)
  6. LED diódy (1x) (voliteľné)
  7. Tlačidlo (1x)
  8. Rezistor 4K7 ohm (2x)
  9. Rezistor 10K ohm (1x)
  10. Rezistor 220 ohm (1x)

Krok 2: Hw

Hw
Hw

Hw, ktorý tu v zásade použijeme, je rovnaký ako v tutoriále: Micropython na ESP pomocou Jupytera. Pozrite sa na to pre všetky HW pripojenia.

Výnimkou je servo, ktoré v tomto projekte nebudeme používať.

Hore vidíte plný HW. Pripojte zariadenia podľa obrázku.

Krok 3: Micropython, REPL, Jupyter

Micropython, REPL, Jupyter
Micropython, REPL, Jupyter
Micropython, REPL, Jupyter
Micropython, REPL, Jupyter

Na svojom zariadení ESP musíte mať načítaný interpret Micropython. Po načítaní by ste mali svoj ESP naprogramovať akýmkoľvek z dostupných spôsobov/IDE, ktoré sú k dispozícii, ako napríklad:

  • ODPOVEĎ
  • Notebook Jupyter
  • Mu
  • ESPCut (iba Windows)
  • … atď

V mojom návode Micropython na ESP Pomocou programu Jupyter som podrobne popísal, ako stiahnuť a nainštalovať interpret MicroPython, ESPTool na správu zariadení ESP a ako používať Jupyter Notebook ako vývojové prostredie. Neváhajte použiť to, čo je pre vás pohodlnejšie.

Celý vývoj väčšinou robím na Jupyter Notebook a keď dostanem konečný kód, skopírujem ho do Geany a načítam ho do svojho ESP pomocou Ampy.

Krok 4: Senzory

Senzory
Senzory

Nainštalujme knižnice, definujeme GPIO, vytvoríme objekty, funkcie pre všetky senzory jednotlivo:

A. DHT (teplota a vlhkosť)

Nainštalujme si knižnicu DHT a vytvorte objekt:

z dht importu DHT22

z importu stroja Pin dht22 = DHT22 (Pin (12))

Teraz vytvorte funkciu na čítanie senzora DHT:

def readDht ():

dht22.measure () návrat dht22.temperature (), dht22.humidity () Otestujte funkciu DHT

vytlačiť (readDht ())

Výsledkom by mal byť napríklad:

(17.7, 43.4)

B. DS18B20 (vonkajšia teplota)

Nainštalujme knižnice a vytvorte objekt:

import onewire, ds18x20

čas importu # Definujte, ktorý pin bude pripojené 1-vodičové zariadenie ==> pin 2 (D4) dat = Pin (2) # vytvorte objekt onewire ds = ds18x20. DS18X20 (onewire. OneWire (dat)) Vyhľadajte zariadenia na bu

senzory = ds.scan ()

tlač ('nájdené zariadenia:', senzory)

Vytlačený výsledok nie je skutočne dôležitý. Čo budeme potrebovať, je prvý detekovaný senzor: snímače [0]. A teraz môžeme vytvoriť funkciu na čítanie údajov senzora:

def readDs ():

ds.convert_temp () time.sleep_ms (750) návrat ds.read_temp (snímače [0])

Vždy je dôležité otestovať snímač pomocou vytvorenej funkcie

vytlačiť (readDs ()) Ak získate hodnotu teploty, váš kód je správny

17.5

C. LDR (svietivosť)

LDR bude používať analógový pin nášho ESP (je to iba jeden v prípade ESP8266 a niekoľko pre ESP32).

Podrobnosti nájdete v mojom tutoriáli k ESP32.

Rovnako ako predtým:

# importovaná knižnica

zo strojového importu ADC # Definujte objekt adc = ADC (0) Na prečítanie hodnoty ADC je možné použiť jednoduchú funkciu: adc.read (). Pamätajte však, že interný ADC bude prevádzať napätie medzi 0 a 3,3 V na zodpovedajúce digitálne hodnoty, pohybujúce sa od 0 do 1023. Akonáhle sa zaujímame o „Svietivosť“, budeme považovať maximálne svetlo za maximálnu zachytenú hodnotu zo snímača (v mojom prípad 900) a minimálnym svetlom, ktoré je v mojom prípade 40. Keď máme tieto hodnoty, môžeme „namapovať“hodnotu od 40 do 900 pri 0 až 100% svietivosti. Za týmto účelom vytvoríme novú funkciu

def readLdr ():

lumPerct = (adc.read ()-40)*(10/86) # previesť v percentách („mapa“) spätné kolo (lumPerct)

Funkciu by ste mali otestovať pomocou print (readLDR ()). Výsledkom by malo byť celé číslo medzi o a 100.

D. Tlačidlo (digitálny vstup)

Tu používame tlačidlo ako digitálny snímač, ale môže to byť „ozvena“pohonu (napríklad čerpadlo, ktoré bolo zapnuté/vypnuté).

# definujte kolík 13 ako vstup a aktivujte vnútorný vyťahovací odpor:

button = Pin (13, Pin. IN, Pin. PULL_UP) # Funkcia na čítanie stavu tlačidla: def readBut (): tlačidlo návratu.hodnota ()

Môžete otestovať čítanie tlačidla pomocou funkcie print (readBut ()). Bez stlačenia výsledku by mala byť „1“. Po stlačení tlačidla by mal byť výsledok „0“

Krok 5: Lokálne zaznamenanie a zobrazenie všetkých údajov senzora

Lokálne zaznamenávanie a zobrazenie všetkých údajov zo senzorov
Lokálne zaznamenávanie a zobrazenie všetkých údajov zo senzorov

Teraz, keď sme pre každý senzor vytvorili jednu funkciu, vytvoríme posledný, ktorý bude čítať všetky súčasne:

def colectData ():

temp, hum, = readDht () extTemp = readDs () lum = readLdr () butSts = readBut () návratová teplota, brum, extTemp, lum, butSts Teraz, ak použijete

print (colectData ())

Výsledkom bude n -tica, ktorá obsahuje všetky zachytené údaje zo senzorov:

(17.4, 45.2, 17.3125, 103, 1)

Tieto údaje môžeme tiež voliteľne zobraziť na miestnom displeji:

# importujte knižnicu a vytvorte objekt i2c

zo strojového importu I2C i2c = I2C (scl = Pin (5), sda = Pin (4)) # importovať knižnicu a vytvoriť objekt oled import ssd1306 i2c = I2C (scl = Pin (5), sda = Pin (4)) oled = ssd1306. SSD1306_I2C (128, 64, i2c, 0x3c) # vytvorte funkciu: def displayData (temp, hum, extTemp, lum, butSts): oled.fill (0) oled.text ("Temp:" + str (temp) + "oC", 0, 4) oled.text ("Hum:" + str (hum) + "%", 0, 16) oled.text ("ExtTemp:" + str (extTemp) + "oC", 0, 29) oled.text ("Lumin:" + str (lum) + "%", 0, 43) oled.text ("Tlačidlo:" + str (butSts), 0, 57) oled.show () # zobrazenie údajov pomocou funkcie displayData (temp, hum, extTemp, lum, butSts)

Voliteľne uvediem aj LED diódu, ktorá má byť ZAPNUTÁ, keď začneme čítať senzory, a zhasne po zobrazení týchto údajov. Pomôže to potvrdiť, že program funguje, keď máme ESP odpojené od počítača a beží automaticky.

„Hlavná funkcia by teda bola:

# Hlavná funkcia na čítanie všetkých senzorov

def main (): # zobrazenie údajov s funkciou led.on () temp, hum, extTemp, lum, butSts = colectData () displayData (temp, hum, extTemp, lum, butSts) led.off ()

Po vykonaní príkazu main () získame údaje senzora zobrazené na OLED, ako je znázornené na obrázku.

Krok 6: Spustenie kódu miestnej stanice pri spustení ESP

Spustenie kódu miestnej stanice pri spustení ESP
Spustenie kódu miestnej stanice pri spustení ESP

Môžeme mať všetko, čo bolo doteraz vyvinuté v jednom súbore, na vykonanie naším ESP.

Otvorme ľubovoľný textový editor a v ňom všetok kód:

# importovať obecné knižnice

z importu stroja Čas importu PINu # definujte pin 0 ako výstupnú LED = Pin (0, Pin. OUT) # DHT z importu dht DHT22 dht22 = DHT22 (Pin (12)) # Funkcia na čítanie DHT def readDht (): dht22.measure () return dht22.temperature (), dht22.humidity () # DS18B20 import onewire, ds18x20 # Define which pin the 1-wire device will be connected ==> pin 2 (D4) dat = Pin (2) # Create the onewire objekt ds = ds18x20. DS18X20 (onewire. OneWire (dat)) # skenovanie zariadení na zbernici senzory = ds.scan () # funkcia na čítanie DS18B20 def readDs (): ds.convert_temp () time.sleep_ms (750) návrat kolo (ds.read_temp (snímače [0]), 1) # LDR zo strojového importu ADC # Definujte objekt adc = ADC (0) #funkcia na čítanie svietivosti def readLdr (): lumPerct = (adc.read ()-40) *(10/86) # previesť v percentách („mapa“) spätné kolo (lumPerct) # definovať kolík 13 ako vstup a aktivovať vnútorný odpínač: tlačidlo = kolík (13, pin. IN, pin. PULL_UP) # Funkcia na čítanie stavu tlačidla: def readBut (): tlačidlo návratu.value () # Funkcia na čítanie všetkých údajov: def cole ctData (): temp, hum, = readDht () extTemp = readDs () lum = readLdr () butSts = readBut () návratová teplota, hum, extTemp, lum, butSts # importná knižnica a vytvorenie objektu i2c zo strojového importu I2C i2c = I2C (scl = Pin (5), sda = Pin (4)) # importovať knižnicu a vytvoriť objekt oled import ssd1306 i2c = I2C (scl = Pin (5), sda = Pin (4)) oled = ssd1306. SSD1306_I2C (128, 64, i2c, 0x3c) # vytvorte funkciu: def displayData (temp, hum, extTemp, lum, butSts): oled.fill (0) oled.text ("Temp:" + str (temp) + "oC", 0, 4) oled.text ("Hum:" + str (hum) + "%", 0, 16) oled.text ("ExtTemp:" + str (extTemp) + "oC", 0, 29) oled. text ("Lumin:" + str (lum) + "%", 0, 43) oled.text ("Button:" + str (butSts), 0, 57) oled.show () # Hlavná funkcia na čítanie všetkých senzorov def main (): # zobrazenie údajov s funkciou led.on () temp, hum, extTemp, lum, butSts = colectData () displayData (temp, hum, extTemp, lum, butSts) led.off () '' '- ----- spustite hlavnú funkciu -------- '' 'main ()

Uložte ho napríklad ako localData.py.

Na spustenie tohto kódu priamo na vašom termináli budete potrebovať Ampy.

Najprv na termináli informujme Ampy náš sériový port:

export AMPY_PORT =/dev/tty. SLAB_USBtoUART

Teraz môžeme vidieť súbory, ktoré sú v našom koreňovom adresári ESP:

ampy ls

Ako odpoveď dostaneme boot.py, to je prvý súbor, ktorý sa spustí v systéme.

Teraz pomocou Ampy načítame náš python Script LocalData.py ako /main.py, aby sa skript spustil hneď po zavedení:

ampy put localData.py /main /py

Ak teraz použijeme príkaz amp ls, v ESP uvidíte 2 súbory: boot.py a main.py

Resetovaním vášho ESP sa program localData.py spustí automaticky a na displeji sa zobrazia údaje senzora.

Vyššie uvedená obrazovka Terminálu ukazuje, čo sme urobili.

S vyššie uvedeným kódom sa displej zobrazí iba raz, ale môžeme definovať slučku na funkcii main (), ktorá bude zobrazovať údaje o každom definovanom časovom intervale (PUB_TIME_SEC), a napríklad kým nestlačíme tlačidlo:

# slučka získava údaje, kým nestlačíte tlačidlo

while button.value (): led.on () temp, hum, extTemp, lum, butSts = colectData () displayData (temp, hum, extTemp, lum, butSts) led.off () time.sleep (PUB_TIME_SEC)

Premenná PUB_TIME_SEC musí byť deklarovaná do času, kedy chcete mať vzorky.

Na vylepšenie nášho kódu by bolo dobré informovať, že vyjdeme zo slučky, preto definujeme 2 nové všeobecné funkcie, jednu na vymazanie displeja a druhú na blikanie diódy LED určitý počet krát.

# Jasný displej:

def displayClear (): oled.fill (0) oled.show () # create a blink function def blinkLed (num): for i in range (0, num): led.on () sleep (0,5) led.off () spánok (0,5)

Teraz môžeme prepísať našu hlavnú () funkciu:

while button.value ():

led.on () temp, hum, extTemp, lum, butSts = colectData () displayData (temp, hum, extTemp, lum, butSts) led.off () time.sleep (PUB_TIME_SEC) blinkLed (3) displayClear ()

Konečný kód je možné stiahnuť z môjho GitHub: localData.py a tiež z Jupyter Notebooku použitého na vývoj celého kódu: Jupyter Local Data Development.

Krok 7: Pripojenie ESP k lokálnej WiFi

Pripojenie ESP k lokálnej WiFi
Pripojenie ESP k lokálnej WiFi

Sieťový modul slúži na konfiguráciu pripojenia WiFi. Existujú dve rozhrania WiFi, jedno pre stanicu (keď sa ESP8266 pripája k smerovaču) a druhé pre prístupový bod (pre ostatné zariadenia sa pripája k ESP8266). Tu bude náš ESP pripojený k miestnej sieti. Zavolajme do knižnice a definujme svoje sieťové poverenia:

importná sieť

WiFi_SSID = "VAŠA SSID" WiFi_PASS = "VAŠE HESLO"

Na pripojenie ESP k vašej lokálnej sieti je možné použiť nižšie uvedenú funkciu:

def do_connect ():

wlan = network. WLAN (network. STA_IF) wlan.active (True) if not wlan.isconnected (): print ('connections to network…') wlan.connect (WiFi_SSID, WiFi_SSID) while not wlan.isconnected (): pass print ('konfigurácia siete:', wlan.ifconfig ())

Po spustení funkcie môžete získať IP adresu:

do_connect ()

Výsledkom bude:

konfigurácia siete: ('10.0.1.2 ',' 255.255.255.0 ', '10.0.1.1', '10.0.1.1 ')

V mojom prípade 10.0.1.2 bola adresa IP ESP.

Krok 8: ThingSpeak

ThingSpeak
ThingSpeak

V tomto mieste sme sa naučili zachytávať údaje zo všetkých senzorov a zobrazovať ich na našej OLED. Teraz je načase zistiť, ako tieto údaje odoslať na platformu IoT, ThingSpeak.

Poďme začať!

Najprv musíte mať účet na ThinkSpeak.com. Ďalej podľa pokynov vytvorte kanál a poznačte si svoje ID kanála a kľúč rozhrania API na zápis.

Hore vidíte 5 polí, ktoré budú použité na našom kanáli.

Krok 9: Protokol MQTT a pripojenie ThingSpeak

Protokol MQTT a pripojenie ThingSpeak
Protokol MQTT a pripojenie ThingSpeak

MQTT je architektúra publikovania/prihlásenia na odber, ktorá je vyvinutá predovšetkým na pripojenie zariadení s obmedzenou šírkou pásma a obmedzeným výkonom prostredníctvom bezdrôtových sietí. Je to jednoduchý a ľahký protokol, ktorý beží cez sokety TCP/IP alebo WebSockets. MQTT cez WebSocket môže byť zabezpečený pomocou SSL. Architektúra publikovania/predplatného umožňuje odosielanie správ na klientske zariadenia bez toho, aby zariadenie potrebovalo nepretržite dotazovať server.

Maklér MQTT je ústredným bodom komunikácie a má na starosti odosielanie všetkých správ medzi odosielateľmi a oprávnenými príjemcami. Klient je akékoľvek zariadenie, ktoré sa pripája k maklérovi a môže publikovať témy alebo sa prihlásiť na odber tém na prístup k informáciám. Téma obsahuje informácie o smerovaní pre makléra. Každý klient, ktorý chce odosielať správy, ich publikuje na určitú tému a každý klient, ktorý chce dostávať správy, sa prihlási na určitú tému. Maklér doručí všetky správy so zodpovedajúcou témou príslušným klientom.

ThingSpeak ™ má sprostredkovateľa MQTT na adrese URL mqtt.thingspeak.com a portu 1883. Maklér ThingSpeak podporuje publikovanie MQTT aj prihlásenie na odber MQTT.

V našom prípade použijeme: MQTT Publish

Obrázok
Obrázok

Obrázok popisuje štruktúru témy. Na zverejnenie je potrebný kľúč API rozhrania Write. Maklér potvrdzuje správnosť CONNECTrequest pomocou CONNACK.

Protokol MQTT je podporovaný vo vstavanej knižnici v binárnych súboroch Micropython-tento protokol je možné použiť na odosielanie údajov z vášho ESP8266 cez WIFI do bezplatnej cloudovej databázy.

Použime knižnicu umqtt.simple:

z umqtt.simple import MQTTClient

A keď poznáme naše SERVER ID, je možné vytvoriť náš klientský objekt MQTT:

SERVER = "mqtt.thingspeak.com"

client = MQTTClient ("umqtt_client", SERVER)

Teraz, keď máte poruke poverenia ThingSpeak:

CHANNEL_ID = "VAŠE ID KANÁLU"

WRITE_API_KEY = "VÁŠ KĽÚČ TU"

Vytvorme si „tému“MQTT:

topic = "channels/" + CHANNEL_ID + "/publikovať/" + WRITE_API_KEY

Nechajme svoje údaje odoslať do služby ThingSpeak IoT Service pomocou vytvorenej funkcie a priradme jej odpoveď k špecifickým dátovým premenným:

temp, hum, extTemp, lum, butSts = colectData ()

Keď sú tieto premenné aktualizované, môžeme vytvoriť naše „užitočné zaťaženie MQTT“:

užitočné zaťaženie = "field1 ="+str (temp)+"& field2 ="+str (hum)+"& field3 ="+str (extTemp)+"& field4 ="+str (lum)+"& field5 ="+str (butSts)

A je to! Sme pripravení odoslať údaje do ThinsSpeak, jednoducho pomocou troch riadkov kódu nižšie:

client.connect ()

client.publish (téma, užitočné zaťaženie) client.disconnect ()

Teraz, keď prejdete na stránku svojho kanála (ako ja vyššie), uvidíte, že každé z 5 polí bude obsahovať údaje súvisiace s vašimi senzormi.

Krok 10: Záznamník údajov senzora

Senzorový záznamník dát
Senzorový záznamník dát

Teraz, keď vieme, že iba s niekoľkými riadkami kódu je možné odosielať údaje do služby IoT, vytvorme funkciu slučky, ktorá to bude robiť automaticky v pravidelnom časovom intervale (podobne ako sme to urobili s „Miestnymi údajmi“ ).

Použitím tej istej premennej (PUB_TIME_SEC), deklarovanej predtým, jednoduchá hlavná funkcia na nepretržité zaznamenávanie údajov a ich zaznamenávanie na našom kanáli by bolo:

kým je pravda:

temp, hum, extTemp, lum, butSts = užitočné zaťaženie colectData () = "field1 ="+str (temp)+"& field2 ="+str (hum)+"& field3 ="+str (extTemp)+"& field4 ="+ str (lum)+"& field5 ="+str (butSts) client.connect () client.publish (téma, užitočné zaťaženie) client.disconnect () time.sleep (PUB_TIME_SEC)

Upozorňujeme, že je potrebné aktualizovať iba „užitočné zaťaženie“, akonáhle bude „téma“súvisieť s povereniami nášho kanála a nezmení sa.

Pri pohľade na svoju stránku kanála ThingSpeak uvidíte, že údaje sa budú načítavať nepretržite do každého poľa. Môžete prikryť LDR, priložiť ruku k snímačom teploty/hluku, stlačiť tlačidlo atď. A zistiť, ako kanál automaticky „zaznamená“tieto údaje pre budúcu analýzu.

Pri protokolovaní údajov by sme sa mali snažiť používať čo najmenej energie, takže by sme LED alebo displej nepoužívali lokálne. Tiež je bežné u zariadení ESP, dajte ich do „hlbokého spánku“, kde bude mikroprocesor v stave minimálnej energie, kým nenastane čas zachytiť údaje a odoslať ich na platformu IoT.

Ale akonáhle sa tu myšlienka učí, zahrňme tiež displej a LED, ako sme to urobili predtým. Pri tom bude naša funkcia „záznamníka“:

while button.value ():

led.on () temp, hum, extTemp, lum, butSts = colectData () displayData (temp, hum, extTemp, lum, butSts) led.off () temp, hum, extTemp, lum, butSts = colectData () užitočné zaťaženie = "field1 ="+str (temp)+"& field2 ="+str (hum)+"& field3 ="+str (extTemp)+"& field4 ="+str (lum)+"& field5 ="+str (butSts) klient.connect () client.publish (téma, užitočné zaťaženie) client.disconnect () time.sleep (PUB_TIME_SEC) blinkLed (3) displayClear ()

Kompletný skript microPython nájdete tu: dataLoggerTS_EXT.py a notebook Jupyter, ktorý bol použitý na vývoj, nájdete aj tu: IoT ThingSpeak Data Logger EXT.ipynb.

Ak chcete skript nahrať do systému ESP, na svojom termináli použite príkaz:

ampy put dataLoggerTS.py /main.py

A stlačte tlačidlo ESP - reset. Budete mať ESP zaznamenávať údaje a zaznamenávať ich na ThingSpeak.com, kým nebudete držať stlačené dno (počkajte, kým LED dióda 3 -krát nezačne blikať a OLED sa vypne).

Krok 11: Aplikácia ThingView

Aplikácia ThingView
Aplikácia ThingView

Zaznamenané údaje je možné zobraziť priamo na webe ThingSpeak.com alebo prostredníctvom aplikácie, napríklad ThingsView!

ThingView je aplikácia vyvinutá spoločnosťou CINETICA, ktorá vám umožňuje jednoduchú vizualizáciu kanálov ThingSpeak, stačí zadať ID kanála a ste pripravení ísť.

V prípade verejných kanálov bude aplikácia rešpektovať vaše nastavenia okien: farba, časový rozvrh, typ grafu a počet výsledkov. Aktuálna verzia podporuje čiarové a stĺpcové grafy, spline grafy sa zobrazujú ako čiarové grafy.

V prípade súkromných kanálov sa údaje zobrazia pomocou predvolených nastavení, pretože neexistuje spôsob, ako čítať nastavenia súkromných okien iba pomocou kľúča API.

Aplikáciu ThingView je možné stiahnuť pre ANDROID a IPHONE.

Krok 12: Záver

Záver
Záver

Ako vždy, dúfam, že tento projekt pomôže iným nájsť si cestu do vzrušujúceho sveta elektroniky!

Podrobnosti a konečný kód nájdete v mojom depozitári GitHub: IoT_TS_MQTT

Viac projektov nájdete na mojom blogu: MJRoBot.org

Saludos z juhu sveta!

Uvidíme sa pri mojom ďalšom pokyne!

Ďakujem, Marcelo

Odporúča: