Mano Itead Ibox‘as jau daugiau nei puse metu tarnauja kaip namu failų ir media serveris ir štai dabar sugalvojau, kad reikia kažkaip pamatyti kas ten statistiškai vykta jo viduje. Dabar įrenginys nėra pajungtas prie televizoriaus ir vienintelis budas sužinoti jo statusą yra prisijungti prie jo per SHH ir užklausti kelias komandas. Tai nepatogu, tad pagalvojau prijungti tekstinį LCD ekraną ir ten išvesti smalsumą tenkinančią informacija. Bus puiki proga prisilieti prie I2C iš linuxo ir dar įdomiau bus parašyti pirmąją python programą 😀
Beja toliau aptariama programinė dalis nebutinai apsiriboja Itead Ibox ARM kompiuteriu, bet gali būti laisvai pritaikoma ir visokiems kitiems ARM’ams su linuxais, įskaitant žymujį Raspberry Pi
Techninė dalis
Kad galėčiau prie Ibox prijungti SATA kietąjį diską naudoju Ibox Arduino Plug priedą. Jama šalia SATA ir USB debug jungčių yra su Arduino suderinama jungtis:
LCD pajungimui per I2C matote net kelias reikiamas SDA ir SCL linijas. Deja bet liūdna naujiena yra ta, kad I2C linija dirba 3,3V lygyje, o mano turimi LCD ekranai yra 5V. Vadinasi teks naudoti lygiu konverteri ir dar labiau gaila, kad negalėsiu LCD ekrano jungti tiesiogiai per baltą Groove stiliaus jungtį, nes man reikia dar ir 5V maitinimui.
Atkapsčiau archyve kažkada naudotą lygių konvertavimo schemą:
Schema buvo naudota Serial duomenims konvertuoti, bet skirtumo dabartiniu atveju nėra. Nuo senų laikų žinoma 2n7000 mosfetu užsipirkęs buvau daugiau, tad greitai ėmiau ir viska sujungiau:
Yra pasirodo galimybė perdaryti dauguma LCD ekranus, kad jie dirbtu nuo 3,3V, bet deja galutiniam variante esu numatęs 20×4 LCD ekraną, kuris papildomam 3,3V reguliatoriui vietos neturi. Pastangų jį konvertuoti nedėsiu, nes tiek pat galima darbo įdėti ir į signalų lygio adapterį,
Dabar laikas patikrinti ar ekranėlį mato I2C sąsajoje pats linuxas, o tai jau keliauja į kita skyrelį.
Programinė dalis
Pirmiausiai Iboxe reikia sutvarkyti I2C sąsajos reikalus. Pirmas dalykas ką aš dariau tai išbandžiau komandą “i2cdetect -y 1“:
root@Itead:/usr# i2cdetect -y 1
0 1 2 3 4 5 6 7 8 9 a b c d e f
00: — — — — — — — — — — — — —
10: — — — — — — — — — — — — — — — —
20: — — — — — — — 27 — — — — — — — —
30: — — — — — — — — — — — — — — — —
40: — — — — — — — — — — — — — — — —
50: — — — — — — — — — — — — — — — —
60: — — — — — — — — — — — — — — — —
70: — — — — — — — —
Man taip jau pasisekė, kad Itead savo linuxuose visus reikalus jau sutvarkiusi ir iškarto matome LCD adresu 0x27 🙂 Jei jum taip nepasisekė, gali tekti I2C sąsaja pakonfigūruoti, kaip tai darė DarauBlė čia.
Dabar metas paieškoti python bibliotekos LCD valdymui, nes mes juk nenorime sėdėti savaitę ir rašyti savo. Aš radau man tinkamą čia.
Kadangi aš noriu pavaizduoti statistine informacija, man reikia pirmiausia ją išsirinkti. Pirmiausia testuodamas ekraną pavaizdavau esamą sistemos laiką, kuri gavau python’e pasinaudojus “datetime.now()“ funkcija:
Žinodamas, kad viskas veikia susirinkau visa kita informacija, kurią duoda linuxo programos.
CPU užimtumą procentais išgausiu ir “sar“ programos, kuri man apskaičiuos CPU užimtumą per 1 sekundę:
root@Itead:/usr# sar 1 1
Linux 3.4.79+ (Itead) 02/19/15 _armv7l_ (2 CPU)10:57:30 CPU %user %nice %system %iowait %steal %idle
10:57:31 all 5.08 0.00 4.57 0.51 0.00 89.85
Average: all 5.08 0.00 4.57 0.51 0.00 89.85
Laisvos atminties kiekį sužinosime pasinaudoja programa “free“:
root@Itead:/usr# free
total used free shared buffers cached
Mem: 976656 955532 21124 0 19468 760728
-/+ buffers/cache: 175336 801320
Swap: 0 0 0
Laisvos vietos išoriniame diske ieškosime programos “df“ atsakyme:
root@Itead:/usr# df -h
Filesystem Size Used Avail Use% Mounted on
rootfs 3.5G 2.0G 1.4G 59% /
/dev/root 3.5G 2.0G 1.4G 59% /
devtmpfs 381M 0 381M 0% /dev
tmpfs 96M 492K 95M 1% /run
tmpfs 5.0M 0 5.0M 0% /run/lock
tmpfs 191M 0 191M 0% /run/shm
/dev/mmcblk0p1 64M 6.1M 58M 10% /boot
tmpfs 477M 0 477M 0% /tmp
/dev/sda1 294G 257G 23G 93% /media/drive
Dabar viska sumetus į python programą ir surikiavus LCD ekrane turime man reikiamus duomenis:
Kol programos dar neužbaigiau buvau paskolinęs 3,3V I2C ekraną ir šis veikė be jokio lygių konverterio:
Panašiu metu gavau savo 20×4 LCD ekraną:
Pritaikiau programa jam ir vaizdas tapo ne toks sugrūstas, o priedo dar ir su papildomais vizualiais stulpelių grafikais:
Kadangi su programa viskas gerai, o mes norime, kad ji dirbtu visada fone vos linux’ams užsikrovus. Mestas python programą paversti servisu. Nesu aš linuxu profas, bet internetui pagelbėjus ir pasekus šiais žingsniais pavyko viska atlikti kaip reikiant.
Galutinai programa gavosi štai tokia nedidelė:
#!/usr/bin/env python
import lcddriver
from time import *
from datetime import datetime
import subprocess
import os
from threading import Timerlcd = lcddriver.lcd()
def update():
mem = subprocess.check_output([‘free’,’-m’]).splitlines()
cpu = subprocess.check_output([“sar“,“1″,“1″]).splitlines()
hdd = subprocess.check_output([“df“]).splitlines()
dat = datetime.now().strftime(‘%Y-%m-%d %H:%M:%S’)lcd.lcd_display_string(dat+“ “,1)
line = list(“ “)
for x in range(0,19):
if int(float(cpu[3].split()[2]))*20/100>=x:
line[19-x]=chr(12)
x=0
for c in cpu[3].split()[2]:
line[x]=c;
x+=1
line[x]=’%’
lcd.lcd_display_string(““.join(line),2)
line = list(“ “)
for x in range(0,19):
if int(float(mem[2].split()[2]))*20/int(float(mem[1].split()[1]))>=x:
line[19-x]=chr(12)
x=0
for c in mem[2].split()[3]:
line[x]=c;
x+=1
line[x]=’M’
lcd.lcd_display_string(““.join(line),3)
line = list(“ “)
for x in range(0,19):
if int(float(hdd[9].split()[2]))*20/int(float(hdd[9].split()[1]))>=x:
line[19-x]=chr(12)
x=0
for c in str(round(float(hdd[9].split()[3])/1024/1024, 1)):
line[x]=c;
x+=1
line[x]=’G’
lcd.lcd_display_string(““.join(line),4)
t = Timer(1.0, update)
t.start()t = Timer(1.0, update)
t.start()
Tik nemuškite manęs jei kokiu klaidu matote, čia mano Hello World programa, kuri truputi daugiau raidžių parašo 😀 Programą ir LCD biblioteka gale įrašo prisegsiu.
Pabaiga
Dabar metas sutvarkyti visa netvarka.
Lygiu konverteri perkėliau į maketavimo plokštę ir prikabinau prie I2C adapterio:
PCB gaminti tokiam vienetiniam reikalui butu laiko gaišimas.
Ibox pusėje prie kontaktų juostos litavau laidus ir sukišau į reikiamas vietas (3 kontaktu jungtis maitinimui, o 2 kontaktu jungtis I2C linijoms):
Ir galiausiai liko tik pritvirtinti LCD ekraną, o to aš nedariau. Lygių adapterio specialiai nelenkiau arčiau ekrano kad jis tarnautu kaip atraminė koja:
Manau gražiai gavosi. Tobulintinu dalyku tikrai yra. Galvojau dar tinklo apkrova rodyti, bet tam reiktu perdaryti programą, kur ne tik imtu duomenis iš kitų programų, o dar ir pati skaičiuotu. Tokiam programavimui dabar dar nesu pasirengęs 😀 Gaila nėra tokio įrankio kaip “sar“, kurią naudojau CPU apkrovai skaičiuoti.
Pabaigai trumpas video, kaip kas 3 sekundes atnaujinami duomenys:
Na ir žadėtas kodas bus čia.
Šiaip daugumą informacijos galima nuskaityti iš įvairių kernelio /proc virtualių failų. Spawninant procesus iš Pythono ir nuskaitant jų outputą biškį be reikalo tavo serveris apkraunamas 🙂 O sar apskritai yra gan „sunki“ programulkė.
Va keli naudingi failai:
/proc/meminfo — viskas apie atmintį
/proc/loadavg — vidutinis procesoriaus apkrautumas per 5, 10 ir 15 min.
/proc/net/dev — viskas apie tinklo interfeisus
O šiaip tai rekomenduočiau Pythono „platform“ modulį, jame tikrai daug naudingos informacijos galima iškapstyti ir padaryti tai gan efektyviu būdu.
Čia iš skaitinėlių: http://amitsaha.github.io/site/notes/articles/python_linux/article.html
Tai ką, programos antra versija bus išleista ta pačia diena nori pasakyti? 😀 O jei rimtai tai pažiūrėsiu kas ten gero. Rimtas reikalas su CPU statistika, nes dabar reikia laukti ta viena sekunde kol “sar“ gražina atsakymą. Dėkui už pastebėjimus.
Kodėl gi ne. Atėjus nušvitimui arba apšvietimui kai ką esu net ir kelis kartus tą pačią dieną perrašinėjęs 😀 Toks mūsų, programuotojų, gyvenimas…