Meteo stanica 0310 i kako izgleda ispod kućišta [foto] [18+]

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.

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 UndergroundWeathercloud. 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
Mainboard, bottom view

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).

RTL_433 identifies the station as Cotech-36759

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.

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.

Digitalna oglasna ploča

Ovoga puta donosim jedan jednostavan i jeftin projekt koji sam napravio za posao – digitalna oglasna ploča za školu u kojoj radim. Plan je bio prenamijeniti jedan veći LED TV, montirati ga u glavni hol kroz koji svi učenici prolaze i koristiti ga kao podsjetnik s korisnim, servisnim informacijama. U istom holu i roditelji najčešće čekaju termine za informacije, pa je cijela stvar i njima korisna.

Od “offline” rješenja i korištenja preglednika fotografija/videa s USB sticka smo, naravno, u startu odustali jer sam htio nešto što određen krug suradnika može lako ažurirati. Kako nam je dostupni TV opremljen HDMI-jem, odlučio sam se iskoristiti Raspberry Pi. Poduže guglanje i pregled dostupnih komercijalnih, polukomercijalnih i besplatnih rješenja za digital signage nije ponudilo jasnog favorita – rješenja su bila komplicirana za uređivanje i bila su fokusirana na video, nešto što sam smatrao nepotrebnim za ispisivanje kratkog teksta, nekoliko fotografija ili eventualne jednostavne animacije.

Na taj način odlučio sam se za kombinaciju web stranice i fullscreen browsera. Istestirao sam više kombinacija, uključujući i digital signage temu za WordPress, ali kod nje su mi nedostajale određene mogućnosti uređivanja. Kao logično rješenje nametnulo se prikazivanje HTML inačice nekog od online servisa za prezentacije, Microsoftov PowerPoint online i Presentations u Google Docsu. Pritom sam kod Microsoftovih kombinacija imao određene probleme s prijavom odnosno s javnim pristupom HTML verziji prezentacija, pa je konačni odabir pao na Google Docs Presentations.

Pripremio sam prezentaciju i opcijom objavljivanja na web dobio kod koji sam mogao otvoriti u Chromiumu na Raspberry Piju. Prikazao sam stranicu na cijelom ekranu i dobio nešto ovako:

Kao što vidite, ekran nije cijeli ispunjen jer Google inzistira na prikazivanju alatne trake na dnu ekrana.  Za uređivanje prikaza postoji poludokumentirana/nedokumentirana opcija “rm=minimal” koja uklanja i tu traku, pa URL za ugrađivanje izgleda ovako:

https://docs.google.com/presentation/d/[ID PREZENTACIJE]/embed?start=true&loop=true&delayms=15000&rm=minimal

Kad je već bilo izvjesno da će se raditi o HTML-u/CSS-u koji prikazuje iframe s prezentacijom, u cijelu kombinaciju sam dodao sat i prikaz vanjske temeprature u javascriptu.

HTML/JavaScript ovoga svega slobodno je dostupan na samoj stranici koja se koristi za prikaz na adresi https://kiosk.oskatancic.hr/, ali za svaki slučaj arhivirat ćemo ga i ovdje na blogu.

<!DOCTYPE html>
<html>
  <head>
    <link href="https://fonts.googleapis.com/css?family=Droid+Sans+Mono|Days+One|Source+Sans+Pro" rel="stylesheet" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1" />
    <meta charset="utf-8" />
    <title>Kiosk</title>
    <style>
html, body {
	background: white;
	padding: 0;
	margin: 0;
	width: 100%;
	height: 100%;
}

.container {
	width: 100%;
	height: 100%;
	overflow: hidden;
    z-index: 1;
}
.container iframe {
	height: 100%;
	width: 100%;
}

.boks {
    font-family: 'Droid Sans Mono', monospace;
	color: red;
	position: absolute;
	right: 2%;
	top: 5%;
    z-index: 2;
	width: 24%;
	height: 9%;
    font-weight: bold;
	display: flex;
    align-items: center;
    justify-content: center;
    font-size: 5vw;
	background: linear-gradient(#a6e3f8fa, #b9e9fafa);  
}

.kalendar {
    font-family: 'Helvetica', sans-serif;
    font-weight: bold;
	color: #1155cc;
	position: absolute;
	bottom: 1%;
	left: 6%;
	z-index: 2;
	width: 90%;
	height: 3.4vw;
	font-size: 2.9vw;
	overflow: hidden;
	background: #e5e5e5;
	overflow: hidden;
    margin: 0;
    padding: 0;
    list-style: none;
}
.kalendar li {
	height: 3.4vw;
	padding: 0px;
	margin: 0px 5px;
}

#boks2 {
	top: calc(5% + 9%);
	background: linear-gradient(#b9e9fa90, #c7edfa90);  
    font-family: 'Days One', sans-serif;
    font-weight: normal;
}

.clock {
}
ul {
	list-style: none;
	padding-left: 0px;
}

ul li {
	display: inline;
}

#point {
	position: relative;
    padding-left: 0px;
    padding-right: 0px;
}
#weather-temperature {
	z-index: 2;
}

/* Animations */
@-webkit-keyframes blink {
	0% { opacity: 1.0;}
	50% { opacity: 0;}
	100% { opacity: 1.0;};      
}

@-moz-keyframes blink {
	0% {opacity: 1.0;}        
	50% {opacity: 0;}
	100% {opacity: 1.0;};
}
</style>
  </head>
  <body>
  <div class="container">
    <iframe id="presentFrame"
    src="https://docs.google.com/presentation/d/[ID_PREZENTACIJE]/embed?start=true&amp;loop=true&amp;delayms=15000&amp;rm=minimal"
    frameborder="0" allowfullscreen="true" mozallowfullscreen="true" webkitallowfullscreen="true"></iframe>
  </div>
  <div class="boks">
    <div class="clock">
      <ul>
        <li id="hours"></li>
        <li id="point">:</li>
        <li id="min"></li>
        <li id="point">:</li>
        <li id="sec"></li>
      </ul>
    </div>
    <br />
  </div>
  <div class="boks" id="boks2">
    <div id="weather-temperature"></div>
  </div>
  <div id="kalendar-data" class="kalendar-boks"></div>
  <script src="js/jquery-1.12.4.min.js"></script> 
  <script type="text/javascript">
// Javascript za iscrtavanje sata
$(document).ready(function() {
        setInterval( function() {
                $(".clock").css("visibility", "visible");
                // Create a new Date() object and extract the seconds, minutes and hours...
                var time = new Date();
                var seconds = time.getSeconds();
                var minutes = time.getMinutes();
                var hours = time.getHours();
                $("#sec").html(( seconds < 10 ? "0" : "" ) + seconds);
                $("#min").html(( minutes < 10 ? "0" : "" ) + minutes);
                $("#hours").html(( hours < 10 ? "0" : "" ) + hours);
        },1000);
        
});
</script> 
  <script type="text/javascript">
// Osvježavanje temperature
$(function worker(){
        $.ajaxSetup ({
cache: false,
complete: function() {
	setTimeout(worker, 10*60*1000);
                }
        });
        // load() functions
        var loadUrl = "temp";
        $("#weather-temperature").html("...");
        $("#weather-temperature").load(loadUrl);
        // end  
});
</script> 
  <script type="text/javascript">
// osvježavanje prezentacije
var refreshMinutes = 30;
var timer=setInterval(function(){refreshFrame()}, refreshMinutes*60*1000);
function refreshFrame()
{
        // var iframe = document.getElementById('presentFrame');
        // var iframeURL = iframe.src;
        // iframe.src = iframeURL;
        window.location.reload(true);
}
</script> 
  <script type="text/javascript">
// Ispis kalendara
$(function worker(){
        $.ajaxSetup ({
cache: false,
complete: function() {
	setTimeout(worker, 10*60*1000);
	}
	});
	// load() functions
	var loadUrl = "kalendar.cache";
	$("#kalendar-data").html("...");
	$("#kalendar-data").load(loadUrl);
	// end  
});
</script> 
<script type="text/javascript">
  // ticker kalendara
function tick(){
    $('#kalendar li:first').fadeToggle( function () { $(this).appendTo($('#kalendar')).fadeToggle(); });
}
setInterval(function(){ tick () }, 6000);
</script></body>
</html>

Podatak o temperaturi dolazi iz PHP skripte koja je uzima dobiva iz baze i vraća čisti neformatirani tekst koji JavaScript periodično iščitava i prikazuje iznad prezentacije.

Događaje iz Google kalendara priprema druga PHP skripta, koja preko Google Docs API-ja povlači zadani broj događaja i formatira ih u obliku liste.

<?php
setlocale(LC_ALL, 'hr_HR.UTF-8');
$apikey = 'API_KEY'; // YOUR API key here!
$sada = date(DATE_ATOM);
$limit = new DateTime();
$limit = $limit->add(new DateInterval("P1M"))->format(DATE_ATOM);
$sada = urlencode($sada);
$limit = urlencode($limit);
$brojrezultata = 100;
$adresa = "https://www.googleapis.com/calendar/v3/calendars/oskatancic.hr_[ID_KALENDARA]%40group.calendar.google.com/events?maxResults=$brojrezultata&orderBy=startTime&singleEvents=true&timeMin=$sada&timeMax=$limit&key=$apikey";
$response = file_get_contents($adresa);
$eventi = json_decode($response, true)['items'];
	
echo "<ul id=\"kalendar\" class=\"kalendar\">";
if (!empty($eventi))
{
foreach ($eventi as $dogadjaj)
{
	if (array_key_exists('dateTime', $dogadjaj['start']))
	{
	$dan =  strftime("%A, %e.%-m", strtotime($dogadjaj['start']['dateTime']));
	$pocetak =  date("G:i", strtotime($dogadjaj['start']['dateTime']));
	$recenica_vrijeme = "$dan u $pocetak sati"; 
	}
	else if (array_key_exists('date', $dogadjaj['start']))
	{
	$dan =  strftime("%A, %e.%-m", strtotime($dogadjaj['start']['date']));
	$recenica_vrijeme = "$dan"; 
	}
	$opis = $dogadjaj['summary'];
	echo "<li style=\"display: list-item\">$recenica_vrijeme: $opis</li>";
}
}
else
{
	echo "Nema najavljenih događaja";
}
echo "</ul>"; 
?>

Što se tiče same pripreme Raspberry PI-ja, koristio sam zadnju inačicu Raspbiana (desktop varijanta) uz određene izmjene.

  1. Pomoću raspi-conf  treba uključiti automatsku prijavu u desktop korisnika “pi”
  2. Postaviti mrežu pomoću GUI ili shell alata (ako koristite bežičnu mrežu)
  3. Instalirati paket unclutter koji skriva strelicu miša
    sudo apt install unclutter 
  4. Urediti autostart korisnika koji se nalazi u ~/.config/lxsession/LXDE-pi/autostart
    @lxpanel --profile LXDE-pi
    @pcmanfm --desktop --profile LXDE-pi
    @xscreensaver -no-splash
    @point-rpi
    @unclutter -idle 0.1
    @xset s off
    @xset -dpms
    @xset s noblank
    @chromium-browser --app=https://kiosk.oskatancic.hr/ --temp-profile --no-touch-pinch --kiosk
    

Još jedna stvar koja se pokazala korisnom je uključivanje flaga u Chromiumu koji automatski ponovno učitava stranicu kada se uspostavi mrežna povezanost (ukoliko, recimo, osvježavanje prezentacije započne u trenutku kada RPI izgubi mrežnu povezivost). Jedini način za uključivanje ove opcije je iz Desktop verzije Chromea/Chromiuma preko chromium://flags.

Sve ovo je, naravno, vječito u izradi i stalno se mijenja, ali trebalo bi vam moći poslužiti kao osnova.

Modificiranje Huawei E3372 LTE sticka

Huawei E3372 LTE stick podržava sve LTE frekvencije koje koriste hrvatski provideri (VIPnet na 1800 MHz, te Hrvatski telekom na 1800 MHz u većim gradovima i 800 MHz u ruralnim područjima), te se nalazi u redovnoj ponudi HT-a po basnoslovnim cijenama (450 kn/60 € bez ugovora). Na svu sreću, na eBayu se isti taj stick prodaje za ispod 30€, gdje sam ja nabavio svoga. Radi se o inačici E3372h-153, i dolazi otključan tako da prima SIM kartice svih mreža.

Kako mi je plan bio saznati točnu frekvenciju na kojoj radi HT-ov LTE u mom mjestu, to sam pokušavao saznati iz statistike modema, ali na kraju nisam uspio s originalnim firmwareom latvijskog providera LMT (ta verzija firmwarea jest, doduše, ispisivala razinu i kvalitetu signala, ali nije nigdje bilo mogućnosti odabira frekvencijskog opsega). Isprobao sam, naravno, hrpu dostupnih updateova dostupnih u threadu na austrijskom forumu, pritom izgubio originalni WebUI koji je imao jačinu signala i zamijenio ga verzijom koja razinu signala nije imala, te blago rečeno zbrljao stvar.

Nakon toga sam pokušao prebaciti stick iz HiLink moda u “obični” surf-stick, gdje se on instalira kao modem i konekcije se odrađuju preko USB serijskog porta odnosno Mobile Partner aplikacije. Kako je AT command set Huaweija donekle poznat, ali nepotpuno dokumentiran, ni na taj način nisam uspio zabraniti frekvencijske opsege kako bih metodom eliminacije utvrdio radi li mi mreža na 800 ili 1800 MHz.

O ovom sticku ima pregršt informacija na ruskom forumu 4pda, ali čak i ako se dovoljno snalazite s ruskom ćirilicom i google translateom, download nije moguć bez prijave na forum, a za to trebate i registraciju i rješavanje captcha zadatka s brojevima na ruskom. To sam nekako uspio riješiti – capcha na stranici za registraciju traži da zbrojite dva broja koje vidite na slici (XX плюс XX равно), dok je capcha na stranici za prijavu puno zajebaniji, jer se radi o četveroznamenkastom broju pisanom riječima, u tri reda, pisanom ruskom ćirilicom (npr: девять тысяч восемьсот сорок семь ilivam devjat’ tisjač vosem’sot sorok sem’ odnosno 9847).

I sad sam bio na konju – na siteu se nalaze detaljne upute koje verzije firmwarea prolaze tvornički, kako dodati potpuni WebUI sa i bez modifikacije, kako pokrenuti ADB i Telnet server, te kako prebaciti modem u DEBUG način rada.

Nešto od dostupnih uputa sam iskoristio, dio sam pojednostavnio i sve iskušao na drugome sticku, tako da vrijedi standardni disklejmer: Meni radi™. Ako želite svoj E3372z-153 dovesti u još iskoristivije stanje, molim da pročitate CIJELE upute prije no što napravite bilo što od navedenog jer se su prvih par koraka način kako “pješice” doći do modifikacije na tvorničkom firmwareu. Ako vam nije važno sačuvati firmware koji ste dobili sa stickom, fleširajte odgovarajući firmware prema koraku 6, napravite korake 1-3 i nakon toga upucajte modificirani firmware – ne morate se zezati s koracima 4 i 5.

1. Prebacivanje u DEBUG mode

Prvi korak u svemu je prebacivanje uređaja na DEBUG način rada, koji daje pristup dodatnim COM portovima preko kojih ćete ga otključati/omogućiti ADB/pokrenuti busybox.

To se radi slanjem POST zahtjeva na web sučelje modema, obično http://192.168.8.1/CGI

Sadržaj post zahtjeva je:

<?xml version="1.0" encoding="UTF-8" ?> 
<api version="1.0">
  <header>
    <function>switchMode</function>
  </header>
  <body>
    <request>
      <switchType>1</switchType> 
    </request>
  </body>
</api>

Gotove skripte i curl koji ovo rade pronaći ćete u arhivi ovdje.

2. Uključivanje debug portova i izračunavanje OEM ključa neophodnog za pristup konzoli

Prebacite, dakle, modem u DEBUG mode pokretanjem skripte sw_debug_mode.cmd.

Preuzmite Huawei Modem Terminal, otpakirajte ga, pokrenite i spojite se na “FC – PC UI interface“. Kliknite na “Connect”.

PC-UI_interface

Aktivirajte konzolu s
AT^NVWREX=33,0,4,2,0,0,0

Vidjet ćete da je konzola aktivna jer će vam Huawei Modem Terminal početi ispisivati statistiku modema.

PC_UI_interface_connected

Vrijeme je da izračunamo OEM ključ. Preuzmite, otpakirajte i pokrenite program CalculatorOEM. Pošaljite naredbu

AT^NVRDEX=50502,0,128

Kao odgovor u prozoru terminala dobit ćete nešto u stilu:

Recieve: ^NVRDEX: 50502,0,128,60 DE 2A 11 94 B3 4C 64 78 93 C6 5B 3F 21 57 CC 8A 6C 7C 25 DC 5B E5 C4 61 7A DF B5 EC 5F B4 C2 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 62 7E F5 73 BC 33 24 87 39 33 8A 55 CD 75 33 72 05 9C 45 B8 5D BA C7 CC B0 72 6F 83 B0 D2 81 02 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00

Podebljani heksadecimalni dio zalijepite u CalculatorOEM kao što je prikazano u uputama i kliknite na Подобрать код. Nakon nekoliko minuta (izračun traje stvarno dugo i program izgleda kao da se smrznuo), dobit ćete svoj OEM ključ kojeg ćete si zapisati, trebat će vam kasnije. Na isti način možete doći i do NCK koda za otključavanje mreže, samo treba 50502 u naredbi zamijeniti s 50503.

CalculatorOEM

Resetirajte modem naredbom AT^RESET

Kad se podigne i dobijete web sučelje u browseru, ponovno ga prebacite u DEBUG mod gornjom skriptom.

3. Pokretanje telneta/busyboxa

Huawei Modem Terminal ćete sada spojiti na “FC – ShallB” port.

ShallB

U Send polje upišite svoj OEM kod i pritisnite Enter. Modem će odgovoriti s:

Recieve: Login success 
Recieve: EUAP>
Recieve: EUAP>

ShallB-login

Pokrenite busybox/telnet naredbom

busybox telnetd -l /bin/sh

Sada možete pokrenuti svoj omiljeni telnet klijent (PuTTy, KiTTY) i spojiti se telnet protokolom, port 23 na server 192.168.8.1

4. Trajno omogućavanje adb-a i telneta

Datoteke koje su nam potrebne za ovaj korak snimit ćemo na MicroSD karticu i ubaciti je u modem. Preuzmite i otpakirajte arhivu sa sljedećeg linka u root MicroSD kartice: ADB Daemon

Prvo ćemo montirati MicroSD karticu kako bismo mogli čitati/pisati s nje:

mount -t vfat /dev/block/mmcblk0p1 /mnt/sdcard

Montirat ćemo i /system RW modu (omogućujemo pisanje)

mount -o remount,rw /dev/block/mtdblock16 /system

adb daemon ćemo otpakirati u system/bin sljedećom naredbom:

busybox tar -xzvf /mnt/sdcard/adbd_s.tgz -C /system/bin

te na kraju dodati busybox i adb daemon u startup

echo -e "\nbusybox telnetd -l /bin/sh\n/system/bin/adbd &" >> /system/etc/autorun.sh

Nakon toga možete za probu ponovno pokrenuti modem naredbom reboot. Telnet i ADB vam trebaju biti dostupni bez ulaska u DEBUG mod.

5. Zamjena webUI-ja

Potrebne datoteke snimit ćemo na MicroSD karticu i ubaciti je u modem. Trebat će vam: kompletni webui17.100.06.00.03mod1.0, te nand_tools ako želite napraviti backup cijelog postojećeg webUI-ja, iako to možete i na drugi način.

Pod uvjetom da ste napravili sve iz prethodnih koraka, spojite se telnetom na modem i, ako je potrebno, montirajte SD karticu.

Ako želite, napravite sigurnosnu kopiju postojećeg sučelja. To možete na tri načina, ali za vraćanje bilo kojega od ta tri načina trebat će vam telnet pristup.

Možete iskopirati datoteke u tar arhivu:

busybox tar -cvf /mnt/sdcard/original-webui.tgz /app/webroot/*

ili napraviti dump cijele particije na kojoj se nalazi WebUI pomoću dd-a:

dd if=/dev/block/mtdblock15 of=/mnt/sdcard/webui.dd

ili isto to, ali pomoću nanddumpa:

/mnt/sdcard/nanddump -f /mnt/sdcard/webui.img /dev/mtd/mtd15

Možemo dalje. Prvo ćemo omogućiti pisanje u webroot mountu.

mount -o remount,rw /dev/block/mtdblock15 /app/webroot

Brišemo postojeći WebUI sljedećim naredbama:

rm -r /app/webroot/WebApp
rm -r /app/webroot/upnp

Modificirani WebUI koji smo pripremili na SD kartici otpakirat ćemo u webroot:

busybox tar -xzvf /mnt/sdcard/webui17.100.06.00.03mod1.0.tgz -C /app/webroot

Naletio sam na savjete bi trebalo resetirati modem na tvorničke postavke, ali u mom slučaju to nije bilo potrebno. To možete preko adb-a sljedećom skriptom: erase_userdata_e3372.rar

6. Zakrpa kernela koja omogućuje fleširanje modificiranog firmwarea

Zakrpe za verziju firmwarea koja je “tvornički” došla s mojim modemom nema (u prijevodu, nisam je našao), ali to se lako može riješiti. Napravite nadogradnju firmwarea na jednu od kompatibilnih verzija, a to su:

22.200.03.00.1134
21.180.01.00.00
21.180.01.00.143
22.180.05.00.00

Firmware je dostupan na austrijskom forumu, treba vam prvi iz rubrike “HI- Link Offiziell E3372h” (22.180.05.00.00).

Ako ga instalirate, izgubit ćete telnet/ADB, pa ćete taj dio procedure morati ponoviti.

Nakon što ste instalirali odgovarajući firmware i iznova omogućili telnet pristup, prebacite željeni kernel iz arhive u root SD kartice, kao i pripadajuće alate (nanddump, nandwrite).
Kerneli: dload_patch_kernels_HuaweiE3372h.7z
Nand alati: nand_tools.7z

Montirat ćemo SD karticu:

mount -t vfat /dev/block/mmcblk0p1 /mnt/sdcard

Izbrisati postojeći kernel:

/mnt/sdcard/dload_patch/flash_erase /dev/mtd/mtd7 0 0

Fleširati novi kernel – ovu naredbu promijenite ovisno o firmwareu koji imate! Odaberite odgovarajući kernel i samo njega.

/mnt/sdcard/dload_patch/nandwrite /dev/mtd/mtd7 /mnt/sdcard/dload_patch/kernel_22.XXX.XX.XX.XX.bin

I na kraju provjerite je li sve u redu tako što ćete napraviti dump.

/mnt/sdcard/dload_patch/nanddump -f /testdump.bin /dev/mtd/mtd7

Ako je sve u redu, možete resetirati modem i s gore navedenog foruma odabrati verziju firmwarea/WebUI-ja koji želite (s ADB-om, telnetom ili različitim inačicama drivera) – pripazite samo da u nazivu ima “M” što znači da već dolazi s kernelom koji omogućuje instaliranje drugih neslužbenih firmwarea/web sučelja.

Tu, naravno, možete odabrati i firmware bez Hilinka, ako više volite aplikaciju za spajanje i emulaciju modema. Imajte samo na umu da surf-stick inačice firmwarea idu web sučelja, a iz data stick firmware dashboardi sa softverom.

Adaptivni Quality of Service s routerom Zyxel VMG5313-B30 i OpenWRT-om

Naslov ne govori puno o ovom projektiću, ali valjda ću ga dovoljno pojasniti da nekome bude koristan.

Situacija je sljedeća – imam Iskonov VDSL s maksimalnom brzinom od 30 megabita, iako mi linija daje između 23 i 26 mbita. Uz to imam i Iskon TV i koji mi uredno oduzima dostupan bandwidth dok radi. Kako je “zakupljena” brzina veća od brzine spajanja modema, s isključenim IPTV prijemnikom mogu iskoristiti i ta preostala tri-četiri megabita.

Uz sve ovo, imam TP-LINK TL-WDR3600  router koji odrađuje PPPoE konekciju i N-WLAN na 2.5 i 5 GHz. Gore se vrti OpenWRT Barrier Breaker. Jedna od korisnih mogućnosti koju OpenWRT nudi je jednostavno podesiv Quality of Service koji jamči da će svi klijenti imati jednake šanse kod pristupa netu i koji smanjuje prioritet stvarima koje su sklone zakucati vezu (npr. P2P). Da bi QoS dobro radio, potrebno mu je točno reći s kojom brzinom raspolaže i tu je problem koji sam imao – ako stavim nižu brzinu nikada neću moći iskoristiti povećanje brzine kod isključenog IPTV prijemnika. Ako stavim višu, QoS jednostavno neće raditi svoj posao.

Potrebno je, dakle, automatski mijenjati maksimalnu brzinu downloada u QoS servisu OpenWRT-a ovisno o tome radi li prijemnik ili ne.

Uz Iskonovu VDSL uslugu isporučuje se VDSL2 router Zyxel VMG5313-B30 koji je bogat opcijama, ali većina ih je uredno skrivena od običnih korisnika. Više o mogućnostima i kako do njih doći možete naći na forumima, ali ja sam trebao rješenje koje funkcionira s uobičajenom razinom pristupa.

Rješenje je bilo sljedeće, u kratkim crtama:

1. Kako je moj VDSL2 router u bridge modu, prvo sam morao osigurati pristup do modema kroz redovni LAN. To sam napravio tako što sam dodao još jedan mrežni interface s fiksnom IP adresom u subnetu modema (to je kod Iskona 192.168.5.x).

Konkretno, u /etc/config/interfaces trebalo je dodati:

config interface 'modem'
        option proto 'static'
        option netmask '255.255.255.0'
        option ifname 'eth0.2'
        option ipaddr '192.168.5.254'

(uz, naravno, kvačicu pokraj “Bring up on boot”).

2. Sad kad imamo pristup modemu, trebamo se u njega ulogirati i pronaći način kako da doznamo radi li IPTV receiver.

Prvo je jednostavno, u skriptu ćemo curlom napraviti post na login stranicu i snimiti cookije.

curl -s -l -b /tmp/cookie -c /tmp/cookie http://192.168.5.1/login/login-page.cgi -d "AuthName=Administrator&Display=Administrator&AuthPassword=Administrator"

Drugo je bilo malo teže. Jedini način prepoznati radi li IPTV receiver bilo je pod System Monitor – Traffic Status gdje se nalazi broj paketa u uploadu i downloadu po sučeljima (VDSL_VoIP, VDSL_IPTV, VDSL_Management). Trebamo, dakle, izvući taj podatak dva puta u određenom vremenskom razmaku i vidjeti ima li promjene i kolika je.

Uz popriličnu gnjavažu s Curlom i ostalim alatima za manipulaciju stringovima, dobio sam nešto ovakvo:

curl -s -b /tmp/cookie -c /tmp/cookie  http://192.168.5.1/pages/systemMonitoring/trafficStatus/wan.html | sed -nr 's/.*VDSL_IPTV\|ptm0\.3\|(.*)@1\|VDSL_Management.*/\1/p' | cut -d, -f4

Dakle isto to ponovimo za 10 sekundi i ako je razlika veća, receiver vjerojatno radi (čak i kada je isključen, na tom interfaceu postoji slab promet od jednog do dva paketa u sekundi, ne više od 15 paketa u 10 sekundi).

3. Treći dio je zapravo najjednostavniji – preko UCI sučelja postaviti odgovarajuću vrijednost brzine i reloadati QoS.

uci set qos.wan.download=VRIJEDNOST
uci commit qos
/etc/init.d/qos reload

A evo i cijele skripte. Prvo /etc/qostuner.sh, koju naravno treba učiniti izvršnom (chmod +x /etc/qostuner.sh)

#!/bin/sh
logger="logger -p daemon.info $0 [email protected]"
WAIT="30"
HIGHER="24000"
LOWER="20500"
TRENUTNO=$(uci get qos.wan.download)
if [ "$TRENUTNO" == "$HIGHER" ]; then
IPTVON="0"
else
IPTVON="1"
fi
$logger "Starting up. Current speed limit is $TRENUTNO, Receiver: $IPTVON"
if [[ -s /tmp/cookie ]]
then
LOGIN="1"
else
LOGIN="0"
fi
while [ 1 ]; do
if [ "$LOGIN" == "0" ]; then
RESPONSE=$(curl -s -l -b /tmp/cookie -c /tmp/cookie http://192.168.5.1/login/login-page.cgi -d "AuthName=Administrator&Display=Administrator&AuthPassword=Administrator" | awk 'NR==4' | sed -e "s/\(.*'\)\(.*\)\('.*\)/\\2/")
if [[ $RESPONSE == "/index.html" ]]; then
LOGIN="1"
fi
fi

TRAFFIC=$(curl -s -b /tmp/cookie -c /tmp/cookie  http://192.168.5.1/pages/systemMonitoring/trafficStatus/wan.html | sed -nr 's/.*VDSL_IPTV\|ptm0\.3\|(.*)@1\|VDSL_Management.*/\1/p' | cut -d, -f4)
if [ $TRAFFIC != "" ]; then
sleep 10
TRAFFIC2=$(curl -s -b /tmp/cookie -c /tmp/cookie  http://192.168.5.1/pages/systemMonitoring/trafficStatus/wan.html | sed -nr 's/.*VDSL_IPTV\|ptm0\.3\|(.*)@1\|VDSL_Management.*/\1/p' | cut -d, -f4)
RAZLIKA=`expr $TRAFFIC2 - $TRAFFIC`
if [ "$RAZLIKA" -gt "50" ]; then
if [ "$IPTVON" == "0" ]; then
IPTVON="1"
$logger "IPTV Receiver on. Lowering QOS maximum speed to $LOWER."
uci set qos.wan.download=$LOWER
uci commit qos
/etc/init.d/qos reload
fi
else
if [ "$IPTVON" == "1" ]; then
$logger "IPTV Receiver is off. QOS maximum speed set to $HIGHER."
uci set qos.wan.download=$HIGHER
uci commit qos
IPTVON="0"
/etc/init.d/qos reload
fi
fi
else
LOGIN="0"
rm /tmp/cookie
fi
sleep $WAIT
done

Uz to, trebat ćemo i startup skriptu (/etc/init.d/qostuner)

#!/bin/sh /etc/rc.common
START=90
start() {
/etc/qostuner.sh &
}

stop() {
killall -9 qostuner.sh
}

Naravno, u skripti trebate podesiti vrijednosti više i niže brzine ovisno o svojoj liniji, te omogućiti da se skripta pokreće automatski kod pokretanja routera.

Praćenje stanja i regulacija u sustavu centralnog grijanja

Kao nastavak serije članaka o sustavu centralnog grijanja opisanom ovdje, sljedeći je korak bio složiti nekakav način praćenja temperatura u cijelome sustavu na daljinu, da ne moram svako malo trčati u podrum i gledati što se događa. Kako sam se u to vrijeme počeo baviti Arduinom, odabir je pao na Atmelove mikrokontrolere zbog popularnosti i činjenice da vrlo lako možete naći pomoć s bilo kojom idejom. Cijeli sustav ću uglavnom opisati tekstualno i pustiti vas da sami istražite detaljnije sheme spajanja, ne samo zato što sam prelijen crtati sheme.

1. Praćenje i snimanje temperatura

Kako mi je trebalo više od 6 temperaturnih senzora u sustavu, odabir je pao na jeftine Dallasove DS18B20 digitalne One-wire senzore koji omogućuju spajanje “velikog broja” senzora na samo jednu (1) ulazno-izlaznu nožicu mikrokontrolera, te podržavaju temperature do +125 stupnjeva. Za te senzore, naravno, postoji i kvalitetna podrška za Arduino. Postavio sam 8 senzora – 4 komada na spremnik na četiri razine, jedan na odlaz u radijatore, dva na povrat iz radijatora (ispred i iza miš-ventila), te jedan na mjesto za temperaturni osjetnik u kotlu. Podatke sam odlučio logirati na server u LAN-u i za to mi je trebao ethernet modul. Prvih godinu dana, dok je cijeli sklop bio na pravoj Arduino pločici, koristio sam skupi Arduino Ethernet Shield s Wiznet 5100 čipom, ali za trajniju primjenu preradio sam kod i prešao na mnogo jeftinije ethernet module bazirane na Microchipovom ENC28J60 čipu (trenutno gotovi moduli koštaju ispod 4 dolara). Potonji su također izvrsno neslužbeno podržani kroz EtherCard library. Program je svakih desetak sekundi očitavao temperature sa svih osam senzora i serveru slao HTTP GET zahtjev u obliku:

 http://192.168.1.10/tlog/post.php?t0=57.56&t1=43.13&t2=34.31&t3=30.69&t4=56.13&t5=26.31&6=60.13&t7=34.31

PHP skripta post.php te podatke potom sprema u MySQL bazu. Za prikaz podataka koristim linijske grafove pomoću Google Charts , što izgleda ovako: glinechart

2. Upravljanje optočnom crpkom

 Kad već u svakom trenutku znam kolika je temperatura na kojem mjestu u sustavu, zaključio sam da bi bilo zgodno uključiti optočnu crpku čim je spremnik zadovoljavajuće pun (npr. na četvrtinu), te isključiti je čim se dogodi da se vatra u kotlu ne može održavati minimalnu razinu temperature. Iako mi je za to trebao samo jedan relej, kupio sam shield s 4 releja odvojena optokaplerima. Taj detalj s optokaplerima je prilično važan jer releji prekidaju izmjenične motore i nakon što je napravljena finalna tiskana pločica za gotovi sklop bez električkog odvajanja, cijela stvar je misteriozno prestajala raditi kod uključivanja i isključivanja motora i nijedna količina TVS dioda, filtera i koječega nije uspjela potpuno elimitirati sve probleme.

relay-shield-4

Vratimo se na releje. Za crpku je dovoljan jedan, dva sam planirao za regulaciju, jedan je ostao neiskorišten. Kada bi crpku postavio u stanje “uključeno”, pumpa bi se uključila samo ako je temperatura na senzoru na vrhu spremnika preko 60 stupnjeva, te isključila ako bi temperatura pala ispod te vrijednosti (da očuvam uslojenost vruće vode u spremniku i usporim pražnjenje koje je stabilnije prirodnim optokom bez crpke).

3. Regulacija

Ovaj dio je bio nešto složeniji, kako s električke i elektroničke strane, tako i s programerske. Odlučio sam upravljati miješajućim ventilom kako bih održavao stalnu temperaturu odlaza, a samim time i stalnu temperaturu povrata. Iskreno, u ovome dijelu nisam imao pojma što i kako trebam napraviti, ali namjeravao sam eksperimentirati. Nabavio sam “glupi” servo-motor prikladan za moj miješajući ventil.

actuator_label actuator

Kao što sama etiketa kaže, motor nema mogućnost automatskog upravljanja u koracima ili slanja na određeni položaj, već radi na 230V i ima samo tri voda, dvije faze za dva smjera vrtnje, te jednu nulu. Poznato je jedino da put od jednog do drugog krajnjeg položaja traje cca 140 sekundi.

Izmjerio sam preciznije koliki je hod servo motora, to podijelio s 10 i dobio 10 koraka u koji motor mogu postaviti. Naravno, bez načina dobivanja povratne informacije je li motor doista u određenom položaju ovo bilo iznimno netočno i neprecizno, ali upotrebljivo ako se oslonite na granične prekidače koji se nalaze u servu. Pretpostavljeni položaj servo motora upisivao sam u eeprom kako bih i nakon reseta mikrokontrolera znao gdje se nalazi.

Regulacija je aktivirala svakih nekoliko minuta, uspoređivala je temperature i po potrebi otvarala i zatvarala ventil.

4. Impulsno upravljanje optočnom crpkom

Prije svega, moram napomenuti da je moja optočna crpka kupljena 1986. godine i svojoj originalnoj ambalaži je stajala do 2010. kada je montirana, što znači da nije baš najfunkcionalnija. I ona je, naravno, “glupa” jer ima samo tri brzine rada koje se biraju sklopkom i nema regulaciju brzine. Regulacija brzine vrtnje bi mi bila korisna jer se većina problema opisana u prethodnim člancima događala zbog prebrzog protoka. Problem je postao još gori nakon godinu dana kada mi je crpka jednostavno prestala raditi na najnižoj brzini, pa sam je morao prebaciti na srednju brzinu.

Tada sam odlučio uvesti neku vrstu modulacije širinom impulsa za optočnu crpku, ali u jako sporoj varijanti – konkretno, crpka trenutno radi 30 sekundi, što je dovoljno da napuni radijatore vrućom vodom, i nakon toga miruje 60 sekundi, što radijatorima daje priliku da ohlade vodu prije no što je vrate u spremnik. Graf sustava u tom slučaju izgleda ovako:

pulse2

Miješajući ventil je otvoren na 80-ak posto što objašnjava razliku između temperature povrata (tamnoplava) i povrata u spremnik iza ventila (svjetloplava). U radijatore odlazi voda temperature oko 60 stupnjeva, a vraća se znatno hladnija.  Ovaj sustav koristim već drugu sezonu i do sada mi ni jednom nije zatrebalo stalno uključiti crpku.

5. Kôd i shema

Kao što sam već napomenuo, finalni proizvod u obliku tiskane pločice s napajanjem, relejima, OneWire sabirnicom, serijskim LCD-om, Ethernet modulom, pa čak i RTC čipom (DS1307) pokazao se nepouzdanijim od prototipa pobockanom na Arduino pločici, tako da vam shemu ne mogu dati. Nemojte napraviti istu pogrešku kao i ja – releje OBAVEZNO optički odvojite od MCU-a, a ako u blizini imate četiri izmjenična motora kao u mom slučaju (ventilator u kotlu, optočna crpka za radijatore, optočna crpka u punjaču spremnika, te servo-motor za mišventil), računajte da će sve otići dovraga ako ih zaboravite.

Izvorni kôd u Arduinu, iskomentiran na engleskom jeziku, naći ćete na Githubu. Autor se odriče bilo kakve odgovornosti za korištenje tog koda, niti daje ikakva jamstva o njegovoj ispravnosti ili prikladnosti za bilo kakvu namjenu. Lako moguće da se i neće dati kompilirati, ali možda u njemu nađete nešto što će vam pomoći u radu.

Muke po ventilima (Centralno grijanje, 2. dio)

U prvome članku ukratko sam pojasnio montažu centralnog grijanja kotlom na drva, spremnikom topline i punjačem. Montaža je bila dovršena, sustav napunjen vodom i nabijen na 1.5 bara, zapalili smo prvu vatricu i pratili što se događa. Sve je išlo po planu, kada je temperatura u kotlu dosegla 30°C, termostat u kotlu uključio je optočnu crpku u krugu spremnika topline i nastavilo se zagrijavanje kotla (Laddomat je tada svu toplu vodu iz odlaznog voda kotla vraćao natrag u povratni vod kotla). Na 60°C, na koliko je baždaren termostat u punjaču, otvorila se i klapna i punjač je u povrat kotla počeo dodavati hladnu vodu s dna spremnika topline (počelo je punjenje spremnika od vrha, topla voda istiskuje hladnu s dna ili obratno). Nakon toga pričekali smo da se se napuni vrh spremnika na 60°C, uključili smo optočnu crpku kruga grijanja i tada smo nakon prvih par minuta grijanja završili s hladnim radijatorima.

Problem je bio što su instalateri po čistoj inerciji (ili pravilima montaže ‘normalnih’ sustava grijanja) između optočne crpke, odlaznog i povratnog voda kruga grijanja montirali četveroputi ventil, kakav se obično montira na izlazu iz kotla u sustavima koji nemaju spremnik i punjač spremnika. Tamo takav ventil služi balansiranju između temperatura odlaza i povrata dvaju krugova, odnosno omogućuje da se dio vruće vode koja izlazi iz kotla pomiješa s hladnom vodom koja se vraća iz radijatora jer bi bilo prilično štetno za zagrijani kotao oplahnuti ga hladnom vodom.

Ovako to otprilike izgleda na nabrzaka sklepanoj ne-tehničkoj črčkariji koja prikazuje četveroputi ventil otvoren na trećinu.

4WV-13

Kada je taj ventil poluotvoren, vidimo da se vruća i hladna voda miješaju u oba kruga, i prema radijatorima i prema kotlu/spremniku. Ventil također može biti potpuno otvoren, kada su i odlaz i povrat spremnika/kotla izravno povezani prema krugu radijatora, ili zatvoren, kada su krugovi potpuno odvojeni. Samo u ta dva slučaja nema miješanja, u svim ostalima dogrijavamo vodu koja se vraća u kotao/spremnik.

Da bih vam objasnio zašto nam to nije poželjno kod spremnika topline, pozabavit ćemo se načinom njihovog djelovanja. Oni se potpuno razlikuju od kotla po pitanju povratne temperature i kod njih je za pravilno uslojavanje potrebna što veća razlika temperature (slijedi gruba skica spremnika topline).

tank

S lijeve strane na crtežu priključuje se dovod topline (kotao), a s desne na ovome crtežu odlaz su i povrat radijatora. I punjenje i pražnjenje trebaju ići po istome principu – s lijeve strane oduzimamo hladnu vodu s dna spremnika, a na vrh vraćamo vruću. S desne strane uzimamo vruću vodu, a vraćamo vodu ohlađenu u radijatorima i drugim trošilima. U slučaju prirodne cirkulacije u sustavu ovo savršeno funkcionira, vruća voda odlazi u radijatore, tamo se hladi i vraća se u spremnik.

Ovo je graf punjenja spremnika u idealnim uvjetima, optočna crpka kruga grijanja je isključena, radi samo ona između kotla i spremnika. Temperaturni su osjetnici postavljeni na četiri mjesta na spremniku (broj 1 na vrhu, broj 4 na dnu, ostali nazivi su sami po sebi jasni). Vruća voda prirodno cirkulira sustavom, a hladna se voda vraća u spremnik. Šiljci u temperaturi povrata događaju se u trenutku otvaranja dodatnih radijatora.

heating-punjenje

Kao što vidimo, uslojavanje je uredno i dok je vrh spremnika na 60 stupnjeva, već tridesetak centimetara niže voda je ispod 40 stupnjeva, a samo dno na nešto više od 20.

Dijagram pražnjenja istog sustava prirodnom cirkulacijom, s isključenom optočnom crpkom, izgleda ovako.

discharging-praznjenje

Iako je loženje prestalo oko 23 sata, punjač je nastavio prirodnom cirkulacijom predavati zaostalu toplinu iz kotla (siva linija) spremniku, a spremnik se slojevito prazni, hladna voda s dna potiskuje vruću prema gore, linija razgraničenja se podiže, tj. sloj hladne vode na dnu raste. Slojevitost je očuvana. (Nota bene: u ovome slučaju radilo se o toplome danu i malom broju otvorenih radijatora, 500 litara vruće vode nije dovoljno za održavanje moga sustava toplim 12 sati u hladnijim uvjetima).

U ne-idealnim uvjetima uz uključenu optočnu crpku voda puno brže kruži sustavom, ne stigne se ohladiti u radijatorima (čak i na najsporijoj brzini crpke) i povrat je znatno topliji. Dodavanjem tople vode u dno spremnika gubi se uslojenost i nakon nekoliko minuta voda će se u cijelome spremniku izmiješati i izjednačiti. Time umjesto 60 stupnjeva na vrhu i 20 stupnjeva na dnu dobijemo cijeli spremnik s mlakom vodom temperature četrdesetak stupnjeva, što je nije dovoljno za grijanje radijatora na njihovu radnu temperaturu.

I upravo se ovo dogodilo kada sam prvi puta upalio optočnu crpku. Za samo pet minuta dobio sam pun spremnik neupotrebljivo mlake vode. Utjecaj četveroputog ventila na ovakav sustav može se gradirati od lošeg (krugovi direktno spojeni), preko goreg (bilo koja varijanta miješanja odlaza i povrata) do najgoreg (odvojeni krugovi, odnosno ‘kratki spoj’ kada je odlaz spremnika spojen na povrat spremnika, a krug radijatora spojen u krug bez dotoka tople vode).

Četveroputi ventil se, dakle, pokazao glavnim krivcem i morao je letjeti van. Zamijenili smo ga troputim ventilom, jer je njegovo djelovanje potpuno drugačije.

U jednome položaju ventila sustav djeluje kao da ventila uopće i nema, što se moglo postići i četveroputim – to je slučaj prikazan na donjem crtežu i to ovo nam je neprihvatljivo ako je uključena optočna crpka.

3wv-closed

Međutim, kada je ventil napola zatvoren (ili napola otvoren, ovisno o njegovu pogledu na život), možemo postići to da većinu vode povrata pošaljemo natrag u sustav grijanja i uzmemo tek malo vruće vode iz spremnika. Na taj način u dno spremnika ćemo poslati znatno manje tople vode i slojevitost će se bolje održati. Ovo je primjer kada bi miješajući troputi ventil bio otvoren (ili zatvoren) na pola.

3WV-50

A ovako izgleda graf sustava s ugrađenim troputim ventilom.

heating-3WV

Na početku grafa optočna je crpka i dalje isključena kao na gornjim primjerima, a troputi je ventil otvoren do kraja, odlaz i povrat spremnika spojeni su direktno prema krugu grijanja.

U 17:52 uključena je crpka i vidimo da temperatura povrata strelovito raste, a temperatura odlaza pada. Razlika temperatura odlaza i povrata smanjila se s gotovo 35 stupnjeva na jedva 5. Dno spremnika se počinje zagrijavati.

U 17:58 troputi ventil zatvoren je na trećinu, što znači da se 2/3 vode povrata iz radijatora vraća u sustav, a 1/3 vruće vode uzima iz spremnika. Iako to ne vidimo u iz ovoga grafa, pala je temperatura u cijelom sustavu trošila jer je crpka izmiješala vodu u svim radijatorima (koji su bili uslojeni, vrući na gornjem dijelu, potpuno hladni u dnu) i dogodilo se isto što se dogodi u spremniku – radijatori su sada od vrha do dna mlaki.

U 18:22 troputi je ventil malo jače otvoren, na otprilike 50% (pola vode povrata se vraća u sustav i miješa se s vrućom, pola vode ide na dno spremnika). Vidimo da je razlika između odlaza i povrata sada nešto veća i da polagano raste kako se radijatori i prostorije zagrijavaju. Sustav se stabilizira.

Posljednji graf prikazuje završetak punjenja spremnika uz uključenu optočnu crpku i troputi miješajući ventil na 50% (pola povratne vode vraća se natrag u spremnik, a pola se miješa s vrućom vodom iz spremnika i vraća u radijatore).

heating-3WVat50

Razlika temperatura odlaza i povrata ustalila se na oko 10°C, a spremnik se puni do kraja, iako graf punjenja više nije onako pravilan kao što je bio s isključenom crpkom. Također vidimo da je sustav znatno tromiji, jer je potrebno znatno više vremena da se radijatori zagriju (vidljivo iz temperature odlaza).

Ukratko, za ispravno funkcioniranje spremnika topline na izlazu je neophodan troputi miješajući ventil, a štetan četveroputi. Ovi grafovi također ukazuju na potrebu za određenim sustavom kontrole koji bi pratio temperature u sustavu, po potrebi uključivao optočnu crpku i upravljao miješajućim ventilom kako bi se očuvala slojevitost u spremniku temperature, ali istovremeno zadržala zadovoljavajuća odlazna temperatura potrebna za zagrijavanje radijatora.

To je nastavak ovoga projekta, a u sljedećem članku pozabavit ćemo se prvom kockicom slagalice – ulaznim podacima, odnosno načinima snimanja temperatura u sustavu. U njemu ćete dobiti konkretne ideje kako mjeriti temperature, zapisivati ih na računalo, pratiti s bilo kojeg drugog računala spojenog na lokalnu mrežu ili internet, te izrađivati šarene linijske grafikone.

Nastavit će se…

Centralno grijanje – 1. dio

U ovome tekstu opisat ću vam probleme s kojima sam se susreo kod ugradnje centralnog grijanja na drva biomasu na nešto moderniji način (u usporedbi sa starim sustavima koji su se postavljali na ovom području do šireg uvođenja plina devedesetih godina). Upravo sam plin kod odabira vrste energenta za centralno grijanje vrlo brzo diskvalificirao, unatoč neusporedivom komforu kojega pruža, jer sam propustio njegove jeftine dane.

Odluka je pala na kruto gorivo jer su cijene drva za ogrjev uglavnom stabilne, nisu podložne redukcijama plina, za razliku od peleta drva se mogu nabaviti u “samogradnji” i ekološki je prihvatljiv, provjeren način grijanja. S negativne strane, s grijanjem na drva nikada vam nije dosadno, ne možete ga odvrnuti i zaboraviti, ali i taj problem se može umanjiti akumulacijom topline.

Od tehnike, odabrao sam dakle kotao na drva s tehnologijom pirolize, koji u usporedbi s klasičnim kotlovima ima veću iskoristivost drva i rjeđe se mora ložiti. Radi se o mom slučaju o kotlu Buderus Logano S121 koji među svim ostalim pirolitičkim kotlovima na tržištu ima tu prednost da se može unijeti u moj podrum preko dvije prostorije i stepenica, a opet ima dubinu ložišta preko 50 cm, što je zgodno jer se drva mogu rezati na pola.

Da si olakšam posao s loženjem, nabavio sam i Centrometalov akumulacijski spremnik topline od 500 litara (također uvjetovano njegovom veličinom i mojim stubištem, uz namjeru dokupa još jednoga, što bi trebao biti idealni kapacitet za 24kW kotao) i punjač spremnika ESBE LTC 141 (u prijevodu, konkurentska i jeftinija verzija Laddomata) s temperaturom otvaranja od 60°C.

Polako se nabavio i ostatak materijala za montažu i nakon samo nekoliko mjeseci iščekivanja montera, kotao od preko 300 kilograma uz teške muke i četvero ljudi unesen je u podrum i radovi su mogli početi.

PB241465

Veći dio montaže prošao je uobičajeno, ali kako je monterima ovo bio prvi slučaj da montiraju kombinaciju kotla na drva – punjača – spremnika, bez obzira na iskustvo, trebalo je detaljno konzultirati upute i dokumentaciju. I tu su se dogodile prve pogreške koje smo naknadno uočili, ali konačna pojednostavljena shema spoja izgleda ovako:

 

B je kotao, L je punjač akumulacijskog spremnika, AT je akumulacijski spremnik, 3WV troputi ventil, CP je optočna crpka, a R su trošila (radijatori). Ovako to izgleda u stvarnosti.

PC111487

Drugi dio… 

Potpuno automatski offline backup za šezdesetak kuna

Što sam htio?

  1. raditi backup jednom dnevno na drugi HDD u računalu
  2. backup HDD ne smije biti uključen cijelo vrijeme zbog uštede energije
  3. uključivanje HDD-a i cijeli backup moraju biti potpuno automatski preko shell skripte

1. Samo po sebi razumljivo.

2. Kod razrade sustava, drugi problem bio je malo teži za riješiti jer iako svi operativni sustavi podržavaju hotswap SATA diskova, to u pravilu ne funkcionira ako je ako je disk spojen cijelo vrijeme SATA kabelom i isključujemo mu napajanje. Izrada sklopa koji bi od sustava isključivao i SATA kabel i napajanje bila bi preskupa zbog broja releja koji su potrebni (samo za napajanje dovoljan je jedan).

Na kraju sam se odlučio za spajanje SATA hard diska putem SATA-to-USB adaptera, dok sklop isključuje napajanje. Kod uključenja napajanja ti adapteri prijavljuju sustavu novi disk i on ga uredno prepozna, kao što se vidi u dmesgu:

kernel: [261005.130086] usb 1-8: new high speed USB device using ehci_hcd and address 13
kernel: [261005.282437] usb 1-8: configuration #1 chosen from 1 choice
kernel: [261005.285433] scsi11 : SCSI emulation for USB Mass Storage devices
kernel: [261010.281628] scsi 11:0:0:0: Direct-Access     ST325082 4AS              L    PQ: 0 ANSI: 2 CCS
kernel: [261010.285138] sd 11:0:0:0: Attached scsi generic sg1 type 0
kernel: [261010.287471] sd 11:0:0:0: [sdb] 488397168 512-byte logical blocks: (250 GB/232 GiB)
kernel: [261010.288412] sd 11:0:0:0: [sdb] Write Protect is off
kernel: [261010.296302]  sdb: sdb1
kernel: [261010.317085] sd 11:0:0:0: [sdb] Attached SCSI disk

Kad isključimo napajanje, USB prepoznaje prazan adapter, koji će se opet refreshati kad uključimo napajanje, a to nam odgovara. USB-to-SATA adapteri mogu se za nekoliko dolara naći na eBayu.

3. Rješavanje trećeg zahtjeva bilo je relativno jednostavno uz malo znanja elektronike. Paralelni port na računalu vrlo je pogodan za upravljanje relejima jer se lako postavlja u stanje 1 ili 0 i u njemu ostaje do sljedeće naredbe (serijskom portu potrebno je neprekidno slati stanje 1 da bi u njemu ostao). Srećom, na Linuxu bez većih problema možemo pisati direktno na portove i imamo osam podatkovnih linija/bitova na raspolaganju.

Shemu porta možete naći ovdje, a tablicu konverzije iz dekadskog u binarni sustav ovdje (za slučaj da želite upravljati s više releja putem paralelnog porta) .

Shema elektroničkog sklopa koji se priključuje na paralelni port i prekida napajanje na SATA power konektoru preuzmite ovdje. Gotovi sklop priključit ćemo na bilo koji data pin paralelnog konektora i onda sve bitove postaviti u stanje 0 ili 1.

Ovime smo riješili hardverski dio sustava i možemo prijeći na softverski.

Upravljanje paralelnim portom

Za ovo ćemo iskoristiti jednostavan program pisan u C-u koji kao argument uzima dekadsku vrijednost i postavlja paralelni port u pravo stanje. Izvorni kod toga programa nalazi se ovdje. Da bi se program mogao kompilirati na novijim verzijama Ubuntua, potrebno je promijeniti zadnji include iz #include <asm/io.h>#include <sys/io.h>
Ispravljenu inačicu preuzmite sa sljedećeg linka: lptout.c
Skinite i kompajlirajte program.

wget http://sh.com.hr/wp-content/uploads/2010/07/lptout.c
gcc lptout.c

i dobit ćete izvršni program a.out.
Preimenovat ćemo ga i postaviti dozvole.

mv a.out lpt
chmod +x lpt

Ako vam je sklop priključen na računalo, možete provjeriti radi li relej slanjem sljedećih naredbi za uključenje, odnosno isključenje (u istom ste direktoriju kao i izvršni lpt).

sudo ./lpt 255 
sudo ./lpt 0

Shell skripta

Donja skripta će:
1. Uključiti napajanje diska, sve linije stavljamo u stanje 1
/home/uprava/backup/lpt 255
2. Pričekat ćemo 60 sekundi sustav prepozna priključeni disk.
3. Pokrenut ćemo fsck jer je obavezan svaki određeni broj montiranja diska ($dev je varijabla s nazivom uređaja, recimo /dev/sdb1)
/sbin/e2fsck -p $dev
4. Montirat ćemo pogon
mount /mnt/backup
5. Pripremit ćemo dodatne datoteke za backup, popis instaliranih paketa i backup svih MySQL baza.

dpkg --get-selections > /home/uprava/instalirani-paketi.txt
DBS="$(mysql -u root -h localhost -pPASSWORD -Bse 'show databases')"
for db in $DBS do
mysqldump -u root -h localhost -pPASSWORD $db | gzip -9 > /home/uprava/mysql-$db.gz
done

6. Izvršiti sam backup, u ovome slučaju rsync koji radi identičnu kopiju direktorija na drugome disku.
rsync -ahv –delete –ignore-errors –exclude-from ‘exclude’ /home /mnt/backup/
7. Ispisati u log iskorištenost prostora na backup disku, skriptu za to možete naći ovdje. U mom slučaju, glavna  backup skripta pokretala je ovu.
8. Demontirati pogon
umount /mnt/backup
9. Isključiti napajanje
/home/uprava/backup/lpt 0

cron job

Treba dodati i cron zadatak koji će tu backup skriptu pokretati svakoga dana, obavezno pod root userom. Otvorite crontab datoteku korisnika…
sudo crontab -e
I dodajte liniju sličnu ovoj, koja ima punu putanju do vaše backup skripte. Ja sam odabrao pokretanje svakoga jutra u 4:18h.
18 4 * * * /home/uprava/backup/backup.sh

 Cijela skripta

U ovoj skripti idemo s pretpostavkom da u datoteci /etc/fstab imate unaprijed ispravno definirane parametre backup diska. Trudio sam se iskomentirati sve važnije detalje. Skripta u log ili na stdout ispisuje sve što radi, pa nije problem pronaći uzroke eventualnih problema.

#!/bin/bash
# skripta za backup
# Autor: Ivan Biuklija
# v. 1.4
# Konfiguracija

mnt="/mnt/backup" # Direktorij u koji treba montirati disk
dev="/dev/sdb1" # putanja do diska/particije koju treba montirati
lptout="/home/uprava/pport/lptout" # putanja do lptout programa

# kraj konfiguracije

$lptout 255 # Uključujemo disk
echo -e "Disk uključen \n"
sleep 60 # čekamo 60 sek da sustav prepozna USB disk.

# FSCK i mount

if [ -e $dev ]; then
echo -e "FSCK it up! \n"
/sbin/e2fsck -p $dev
echo -e "Disk pronađen, montiram... \n"
mount $mnt
else
echo -e "Disk nije pronadjen! Prekidam skriptu."
exit 1
fi

# Provjeravamo je li disk montiran

if [ -d $mnt/lost+found ]; then
echo -e "Disk montiran."
else
echo -e "Pogreška: disk nije montiran. Prekidam skriptu!"
exit 1
fi

# ažuriramo popis instaliranih paketa

apt-cache pkgnames > /home/uprava/pkgnames.txt
dpkg --get-selections > /home/uprava/instalirani-paketi.txt

# dumpamo sve SQL baze
DBS="$(mysql -u root -h localhost -pPASSWORD -Bse 'show databases')"
for db in $DBS
do
mysqldump -u root -h localhost -pPASSWORD $db | gzip -9 > /home/uprava/mysql-$db.gz
done

# Backupiramo direktorije koje želimo, ovo je samo primjer.

rsync -ahv --delete --ignore-errors --exclude-from '/home/uprava/backup/exclude' /home /mnt/backup/system
rsync -avh --delete --ignore-errors --exclude-from '/home/uprava/backup/exclude' /etc /mnt/backup/system
rsync -ahv --delete --ignore-errors --exclude-from '/home/uprava/backup/exclude' /root /mnt/backup/system
rsync -avh --delete --ignore-errors '/mnt/media/music' /mnt/backup/media

# Gotov backup. Pokrenimo skriptu za provjeru prostora na disku.

echo -e "\nBackup dovršen. Iskorištenost diskova: \n"
/home/uprava/backup/space.sh

# Demontiramo disk

echo -e "\nDemontiram disk... \n"
umount $mnt

# čekamo da demontiranje završi

sleep 2

# Provjeravamo je li disk demontiran i isključujemo napajanje

if [ -d $mnt/lost+found ]; then
echo -e "\nDisk nije demontiran! Prekidam skriptu. PANIC!"
exit 1
else
echo -e "Disk je uspješno demontiran, isključujem disk.\n"
$lptout 0
fi

# čekamo da se USB port oporavi

sleep 30

# provjeravamo je li disk isključen

if [ -e $dev ]; then
echo -e "Pogreška: disk nije ugašen! \n"
exit 1
else
echo -e "\nDisk je ugašen. Hev a najs dej!"
exit 0
fi
exit 0

Cijena materijala

Cijene su okvirne.

1 x relej 12V, 5A, dva prekidača 18.00 kn
1 x optocoupler 6.00 kn
2 x otpornik 22o R 0.60 kn
1 x dioda 1N4148 0.30 kn
1 x tranzistor 2N2222 2.80 kn
tiskana pločica 10.00 kn
SATA power adapter / molex 6.00 kn
USB – SATA adapter 18.00 kn
UKUPNO 61.70 kn