Nedavno sam zamijenio svoju skoro 10 godina staru uradi-sam žičnu Ethernet meteo stanicu baziranu na Arduinu (DHT22 + BMP085 + Geiger brojač sa SMB-20 cijevima montiran u drvenu kućicu u dvorištu) s novom integriranom stanicom s Aliexpressa, NicetyMeter 0310 Professional WiFi Weather Station koja, unatoč glupavom nazivu brenda, nije loša za cijenu po kojoj se može nabaviti.
Hardver
Meteo stanica sastoji se od displeja s mogućnošću spajanja na wifi mrežu (napaja se s tri AAA baterije i opcionalnim strujnim adapterom koji je opcionalan samo ako ne mislite koristiti Wifi, ako mislite, bez njega ne radi) i integriranim senzorom koji izgledom dosta podsjeća na Davis Vantage Vue (donje fotke su s web stranice prodavača), ali ima i UV senzor i usput mjeri sunčevo zračenje. Dolazi s kompletom za montažu, a osnovna razlika u odnosu na puno skuplje Davis “nadahnuće” je činjenica da vanjska jedinica ne puni svoje baterije (dakle solarni panel se koristi za napajanje senzora tijekom dana, a tri minjonke ga napajaju preko noći), što znači da se baterije moraju povremeno mijenjati. Proizvođač tvrdi da bi trebale potrajati barem godinu dana, što još trebam provjeriti. Nadopuna – upozorenje za nisku razinu baterije na unutarnjoj konzoli upalilo se nakon 19 mjeseci rada.
Kratkim guglanjem postaje očito da se ova kombinacija displeja i senzora prodaje pod različitim nazivima (Sainlogic WS 0310 i Ragova, između ostalog), dok se vanjski senzor koristi u još više kombinacija prijemnika i trgovačkih marki. Proizvođač je, čini se, StarMeter Instruments.
Cijela stvarčica nudi dobar odnos cijene i kvalitete, a nije šaomi. Kućište je od čvrste ABS plastike, ne odaje dojam da će vam se raspasti u ruci i ne djeluje jeftino. Jedini problem koji sam imao s vanjskim senzorom je priloženi plastični stup za montažu se pomalo klima, pa jači udari vjetra znaju aktivirati klackalicu koja broji količinu oborina. Ovo je možda i moja krivica jer je senzor montiran na antenski stup visine jednog metra koji je, pak, na ljestvama od 7 metara koja su montirana na zadnji vanjski zid kuće.
Skidanje podataka sa stanice
Osim što prikazuje podatke u stvarnom vremenu, displej konzola te podatke šalje na servise Weather Underground i Weathercloud. Priloženi priručnik za uporabu čak je i solidno preveden na engleski i jednostavno je konfigurirati stanicu da logira podatke online, ali ja ne bih bio ja da mi je to dosta. Oba servisa imaju svoja ograničenja – Weathercloud prihvaća podatke samo svakih 10 minuta i daje vam pristup samo zadnjoj godini dana vaših podataka bez pretplate, dok Wunderground prihvaća ažuriranja svaku minutu, ali API key koji dobijete za čitanje podataka dozvoljava 1500 poziva dnevno, dakle smijete povući podatke samo jednom u minuti.
Kako mi je proritet bio izraditi sigurnosnu kopiju podataka s moje meteo stanice (i objaviti ih na druge servise) dok ne nađem bolje rješenje, postavio sam genijalno jednostavnu Google Apps skriptu leoherzoga WundergroundStationForwarder koja preuzima podatke s Wundergrounda i prosljeđuje ih drugim servisima. Stvar trenutno radi poprilično pouzdano. Kad sam to riješio, trebalo je zaviriti ispod haube. Senzor šalje podatke svakih 16 sekundi, ali ja imam podatke svaku minutu. Sramota!
Pogled u kućište
Kako je bila velika vjerojatnost da displej ima neku vrstu ESP8266 procesora (Soft AP konfiguracija i njen naziv, WeatherHome-CFxxxxx, bili su glavni razlozi za sumnju), nadao sam se da će taj procesor imati i nekakav serijski debug za čitanje podataka.
Bio sam skoro u pravu. Displej ima ESP-WROOM-02D-V1.4,, ali njegova jedina svrha je logiranje podataka na web servise i sinkronizacija sata preko NTP protokola. Četiri rupice za nožice (označene s P5) pokraj tog procesora su, odozgo prema dolje, VCC, GND, TXD, RXD
.
Port UART0 ne daje ništa korisnih podataka za debugging osim uobičajenog boot debuga tipičnog za ESP8266, pa mu je vjerojatna svrha fleširanje procesora. Boot log izgleda ovako:
ets Jan 8 2013,rst cause:1, boot mode:(7,7) waiting for host ets Jan 8 2013,rst cause:1, boot mode:(7,7) waiting for host ets Jan 8 2013,rst cause:2, boot mode:(3,7) load 0x40100000, len 2592, room 16 tail 0 chksum 0xf3 load 0x3ffe8000, len 764, room 8 tail 4 chksum 0x92 load 0x3ffe82fc, len 676, room 4 tail 0 chksum 0x22 csum 0x22 2nd boot version : 1.7(5d6f877) SPI Speed : 40MHz SPI Mode : QIO SPI Flash Size & Map: 16Mbit(1024KB+1024KB) jump to run user1 @ 1000 OS SDK ver: 2.0.0(e271380) compiled @ Mar 30 2018 18:54:06 phy ver: 1055_1, pp ver: 10.7 rf cal sector: 507 tcpip_task_hdl : 40107b28, prio:10,stack:512 idle_task_hdl : 40107bd8,prio:0, stack:384 tim_task_hdl : 40107d20, prio:2,stack:512 Load param success Timer Server: time.windows.com 20000128128128000001281280 ets Jan 8 2013,rst cause:2, boot mode:(3,6) load 0x40100000, len 2592, room 16 tail 0 chksum 0xf3 load 0x3ffe8000, len 764, room 8 tail 4 chksum 0x92 load 0x3ffe82fc, len 676, room 4 tail 0 chksum 0x22 csum 0x22 2nd boot version : 1.7(5d6f877) SPI Speed : 40MHz SPI Mode : QIO SPI Flash Size & Map: 16Mbit(1024KB+1024KB) jump to run user1 @ 1000 OS SDK ver: 2.0.0(e271380) compiled @ Mar 30 2018 18:54:06 phy ver: 1055_1, pp ver: 10.7 rf cal sector: 507 tcpip_task_hdl : 40107b28, prio:10,stack:512 idle_task_hdl : 40107bd8,prio:0, stack:384 tim_task_hdl : 40107d20, prio:2,stack:512 Load param success Timer Server: time.windows.com 20000128128128000001281280
Matična ploča ima i dva mikroprocesora (chip-on-board, zaliveni u epoksi smolu) koji pogone LCD displej i sve ostalo.
To sve ostalo uključuje:
- Dvožični I2C EEPROM i senzor tlaka zraka. EEPROM ima izvučene rupe za nožice.
- Prijemnik 433 MHz s izvučenim nožicama
- Senzor vlažnosti zraka
Kako je ESP8266 priključen na glavni procesor/procesore preko nožica IO 12
, IO 13
, IO 14
i IO 15
, očito je da komuniciraju preko SPI protokola, ali zaključio sam da bi istraživanje kako komuniciraju uzelo previše vremena, a procesor se javlja ESP modulu samo jednom u minuti kada treba logirati podatke. Podatke s vanjskog senzora morat ću pribaviti na neki drugi način.
Prisluškivanje komunikacije vanjskog senzora
Sljedeći je korak bio priključiti SDR (software-defined radio) prijemnik baziran na čipu RTL2832U (verzija 25 MHz do 1760 MHz, jeftikaner s Alija za 10 dolara) i vidjeti što on čuje na 433 MHz pomoću dekodera RTL_433. Nije razočarao. Najnovija verzija dekodera RTL_433 prepoznala ga je kao Cotech-367959 (i druge stanice koje koriste isti senzor, kao što su SwitchDoc Labs Weather FT020T, Sainlogic Weather Station WS019T i vjerojatno mnoge druge).
Imajte na umu da trenutno samo najnovija verzija RTL-433 podržava ovaj senzor u potpunosti i pravilno dekodira UV indeks i intenzitet sunčevog zračenja, dok Debian paket (ako ga instalirate s apt install rtl-433
) nema to dvoje, pa sam ga morao buildati iz sourcea za moj Orange Pi Zero na Armbianu.
Korištenje podataka
Ovo je pak značilo da podatke stanice jednostavno mogu uvesti u WeeWX pomoću weewx-sdr drajvera. Međutim, taj drajver trenutno ne podržava senzor Cotech-367959
, pa je trebal dodati tu klasu u datoteku sdr.py
. Ona se obično nalazi na weewx/user/sdr.py
nakon instalacije ekstenzije u weewx.
class Cotech367959Packet(Packet): # ['{"time" : "2022-04-28 14:25:59", "model" : "Cotech-367959", "id" : 109, "battery_ok" : 1, "temperature_F" : 63.000, "humidity" : 55, "rain_mm" : 16.200, "wind_dir_deg" : 296, "wind_avg_m_s" : 0.900, "wind_max_m_s" : 1.300, "light_lux" : 23093, "uv" : 14, "mic" : "CRC"}'] IDENTIFIER = "Cotech-367959" @staticmethod def parse_json(obj): pkt = dict() pkt['dateTime'] = Packet.parse_time(obj.get('time')) pkt['usUnits'] = weewx.METRIC sensor_id = obj.get('id') # changes every time you reset the outdoor sensor pkt['battery'] = 0 if obj.get('battery') == 'OK' else 1 pkt['temperature'] = to_C(Packet.get_float(obj, 'temperature_F')) pkt['humidity'] = Packet.get_float(obj, 'humidity') pkt['wind_gust'] = Packet.get_float(obj, 'wind_max_m_s') pkt['wind_speed'] = Packet.get_float(obj, 'wind_avg_m_s') pkt['wind_dir'] = Packet.get_float(obj, 'wind_dir_deg') pkt['total_rain'] = Packet.get_float(obj, 'rain_mm') pkt['light_lux'] = Packet.get_int(obj, 'light_lux') pkt['uv'] = Packet.get_int(obj, 'uv') / 10 pkt = Packet.add_identifiers(pkt, sensor_id, Cotech367959Packet.__name__) return pkt
Imajte na umu i da se vrijednost id
mijenja kad god pritisnete tipku za resetiranje na vanjskom senzoru. Ako ste identificirali svoj senzor i namjeravate ga trajno koristiti na ovaj način, preporučam da tu vrijednost zamijenite fiksnom.
Kao što smo uočili u komentarima članka, izvorni sdr.py nema funkciju koja radi konverziju stupnjeva Fahrenheita u Celsiusove, pa je trebate dodati (pomoćne funkcije počinju od 169. retka sdr.py).
def to_C(v): if v is not None: v = 5 / 9 * (v - 32) return v
Da biste vidjeli te podatke u WeeWXu, morate mapirati mjerenja u datoteci /etc/weewx/weewx.conf
:
[SDR] # This section is for the software-defined radio driver. # The driver to use driver = user.sdr [[sensor_map]] windDir = wind_dir.109.Cotech367959Packet windSpeed = wind_speed.109.Cotech367959Packet windGust = wind_gust.109.Cotech367959Packet outTemp = temperature.109.Cotech367959Packet outHumidity = humidity.109.Cotech367959Packet rain_total = total_rain.109.Cotech367959Packet UV = uv.109.Cotech367959Packet luminosity = light_lux.109.Cotech367959Packet
U gornjem primjeru 109
je ID moje stanice, vaš će se razlikovati (ako ga ne zamijenite fiksnim, što preporučam, vidi gore).
Sada sam imao gotovo sve podatke koje sam trebao, osim tlaka zraka – vanjska jedinica nema taj senzor. U tu svrhu na svoj Orange Pi / Raspberry Pi sam spojio BME180 breakout pločicu preko I2C porta. Podatke sam povukao u WeeWX ovim Bme280wx drajverom.
Trebalo je kombinirati podatke – vrijednosti senzora BME180 mapirao sam kao inHumidity
, inTemp
i pressure
u datoteci /etc/weewx/weewx.conf
kao u donjem primjeru.
[Bme280wx] i2c_port = 0 # OrangePi and older Raspberry Pi's use 0, usually it's 1 i2c_address = 0x76 usUnits = US temperatureKeys = inTemp temperature_must_have = "" pressureKeys = pressure pressure_must_have = outTemp humidityKeys = inHumidity humidity_must_have = ""
Uz to, treba reći WeeWXu da učita taj dodatni drajver u odjeljku Services
datoteke weewx.conf
.
[Engine] # The following section specifies which services should be run and in what order. [[Services]] data_services = "", user.bme280wx.Bme280wx
Vrijednost station_type
u odjeljku [Station]
mora biti navedena kao SDR, jer je to glavni drajver, a BME280 je dodatni.
[Station] [...] # Set to type of station hardware. There must be a corresponding stanza # in this file, which includes a value for the 'driver' option. station_type = SDR
Weewx s tim podatcima dostupan je na
https://meteo-valpovo.žnj.hr/
Budućnost
Kako ne polažem previše nade da će jeftini SDR prijemnik savršeno raditi godinama, možda ću pokušati složiti dedicirani prijemnik 433 MHz baziran na ESP32 ili ESP8266 procesoru koji će prosljeđivati podatke dalje. Za ovo mi nedostaje port RTL-433 dekodera u obliku biblioteke za Arduino, pa mi preostaje čekati da netko pametniji to odradi.
Za sada mi je dovoljno imati lokalnu kopiju podataka sa svoje meteo stanice i drugi način objavljivanja podataka na vanjskim servisima koji ne ovisi o samom prijemniku koji sam dobio sa stanicom jer sumnjam da će izaći ažuriranje firmvera u slučaju da Weather Underground ili WeatherCloud iznenada promijene svoje API-je za slanje podataka.