|
Pro učení nových věcí jsem použil
starý
program, ve kterém jsem tenkrát komunikaci vymazal, protože
jsme se v té lekci učili jiné věci.
Ani tato verze není finální. Má několik chyb, o kterých vím a na které
ještě taky dojde někdy příště. Verze však obsahuje nové věci, které
potřebujeme teď umět: - zapisovat a číst data
do/z konfiguračního souboru
- ukázat si, co to je globální proměnná
- doplnit náš program o procedury, které pošlou povel na server (a ten
ho vykoná). Pokud máme naprogramovaný TCP
Socket server např. v Linuxu na Raspberry Pi nebo Asus Tinker Boardu
(tedy na malých Single Board Computerech, SBC velikosti kreditky),
můžeme těmito spínačkami v daný čas z desktopu zapínat nebo vypínat
relé přes počítačovou síť. Pokud máme alespoň druhý noťas s Linuxem a
Gambasem (a tzv. TCP ControlServerem, který naslouchá), můžeme si
místo spínání relé
obarvovat obdélníčky - viz tato lekce.
A pokud nemáme nic, můžeme si alespoň ve Windows pustit
demoverzi, která je ke stažení zde, která se dá jednoduše upravit, aby
komunikovala a u které si prohlédneme několik nových věcí v kódu.
Poznámky:
1. Stáhnout
spustitelný exáč lze zde.
2. Stáhnout
zazipovaný projekt Visual Basic lze zde. |
 |
|
Globální proměnné
Globální proměnné si udrží svůj obsah mimo proceduru, ve které
jsme je použili. Ve Visual Basicu i mimo třídu (Class). Globální
proměnné se deklarují jako Public, viz příklad kódu dole. Často se
deklarují v tzv. modulu (Module1.vb), tak to mám zde i já, ale není to
podmínkou, můžete je deklarovat i ve Form1 (vyzkoušejte si). Použil
jsem dvě globální proměnné: port a server (do jedné se píše číslo
portu, kde server naslouchá, do druhé se píše IP adresa, kde máme
server puštěný.

Takové informace se dobře zadávají z formuláře,
který vidíte na horním obrázku vlevo vedle puštěných spínaček. Zadávat
taková data je docela otrava, zejména, když máte jenom jeden
naslouchající server. A tak je dobré dělat to jen jednou a dopsat si
pár řádek, aby si tyhle informace uložil program spínaček do
konfiguráku.
Konfigurační soubor
S konfiguračním souborem musíme dělat několik věcí:
- vytvořit soubor po otevření Form1 spínaček, pokud neexistuje
- přečíst z něho informace dvou globálních proměnných ( port a server
)
- otestovat si, zda jsem informace vyčetli (pokud nikoliv, otevřít si
konfigurační dialog na jejich zadání)
- z dialog. wokna zadané informace zapsat do konfiguráku
Zdrojový kód ve Form1:
Private
Sub Form1_Load(ByVal
sender As
System.Object, ByVal
e As
System.EventArgs) Handles
MyBase.Load
Dim
soubor As
New
IO.StreamWriter("spinacky.cnf",
True)
'Vytvoří soubor, pokud
neexistuje, pokud existuje, tak ho NEPŘEPÍŠE !!! Důležitý je parametr
True v proceduře
soubor.Close( )
'po vytvoření můžeme soubor zavřít
Dim
cnf_soubor As
New
IO.StreamReader("spinacky.cnf")
'protože už soubor existuje,
vytvoříme tzv streamreader, pomocí kterého ze souboru čteme po řádcích
server = cnf_soubor.ReadLine
'vyčteme
dvě řádky, buď tam bude IP adresa serveru a číslo portu nebo tam
nebude nic
port = cnf_soubor.ReadLine
cnf_soubor.Close() 'soubor
zavřeme, protože ho nepotřebujemem
If
server = ""
Then
Dialog1.Show() 'kdyby soubor
neobsahoval informace o serveru a portu, otevřeme formulář Dialog1 a
informace tam zadáme (a taky do našeho souboru zapíšeme pro příště)
End
If
Label2.Text = server + "
port: " + Str(port)
'Zobrazˇ IP adresu a port v Label2.Text
End
Sub
Zdrojový kód v dialog. wokně:
Imports
System.Windows.Forms
Public
Class Dialog1
Private
Sub
OK_Button_Click(ByVal
sender As
System.Object, ByVal
e As
System.EventArgs) Handles
OK_Button.Click, Button1.Click
'Me.DialogResult =
System.Windows.Forms.DialogResult.OK
server = TextBox1.Text
'priradi se hodnota promenne server z TextBox1
port = Val(TextBox2.Text)
Dim cnf_soubor
As
New
IO.StreamWriter("spinacky.cnf")
'vytvoří nový soubor, použije
streamwriter a na dalších řádcích tam zapíše do dvou řádek naše
informace o serveru a portu
cnf_soubor.WriteLine(server)
cnf_soubor.WriteLine(port)
cnf_soubor.Close() 'zavře
soubor, už ho nepotřebujeme
Form1.Label2.Text = server +
" port: " +
Str(port) 'Zobrazí nám, co jsme
nastavili a uložili, tj. IP adresu a port ve Form1.Label2.Text
Me.Close(
) 'zavře dialog, co bychom v něm
dále dělali, že, máme nakonfigurováno a uloženo
End Sub
Komunikační příkazy
Komunikační
příkazy jsme si vysvětlili a odladili v minulé
lekci zde. Zde si jenom ověříme, zda je umíme do tohoto
programu aplikovat. Pokud máme TCP ControlServer s Linuxem nebo
Raspberry PI,
odstraníme tyto apostrofy a dovolíme programu komunikovat. Pokud máme
jenom toto PC s Windows, tak si o tom budeme jen povídat a zkoušet bez
komunikace.

Komunikační příkazy - kódy v procedurách
Private
Sub
Send_Zapni()
povel = System.Text.Encoding.ASCII.GetBytes("Zap1")
'priradi se hodnota promenne
povel
Dim
client As
New
TcpClient(server, port)
'deklaruje a otevře noveho TCP klienta
Dim
stream As
NetworkStream = client.GetStream()
'deklaruje nově stream a napojí klienta
stream.Write(povel, 0, povel.Length)
'zapíše byty streamu; pocet bytu je
precten z povel.Length
client.Close()
End
Sub
Private
Sub
Send_Vypni()
povel = System.Text.Encoding.ASCII.GetBytes("Vyp1")
'priradi se hodnota promenne
povel
Dim
client As
New
TcpClient(server, port)
'deklaruje a otevře noveho TCP klienta
Dim
stream As
NetworkStream = client.GetStream()
'deklaruje nově stream a napojí klienta
stream.Write(povel, 0, povel.Length)
'zapˇçe byty streamu; pocet bytu je
precten z povel.Length
client.Close()
End
Sub
Poznámka:
1. Kódy jsou vidlácké a obsahují celou řadu chyb a velice
"neprofesionálních" obratů. Ale fungují a jsou minimalizované právě
natolik, abychom pochopili principy globálních proměnných, zápisů do
souborů, zápisů do Socketů, principy streamreaderu a streamwriteru.
Detaily, které se mi do textu nevešly
1. Náhled na obsah konfiguračního souboru:

2. Náhled do adresáře, kde se konfigurák vytvoří.
Úmyslně jsem použil vidláckou kompilaci do jediného exe souboru, který
je spustitelný (jde o time_control.exe). Nic se neinstaluje. Až
nás exáč nebude bavit, tak ho smažeme a nebudeme mít počítač zasraný
nějakým poinstalačním sajrajtwarem. Konfiguráku jsem nezadal nikam
žádnou cestu. Je to vidlácké, ale vím, že ho najdu v adresáři hned
vedle toho exáče (spinacky.cnf), až mě nebude bavit, smažu ho. Tyhle
jednoduché vidlácké věci jde zatím stále dělat ve Windows a pokud se
někdy bavím o konkrétní počítačové svobodě, tak toto za svobodu
spouštět si své exáče já opravdu považuji. Proč instalovat, když to
není třeba, proč se jebat s repozitáři, když to není třeba ....

3. Spuštění více instancí programu
Spuštění více instancí je pro koncepci našich spínaček důležitá věc.
Což o to, spustíme (jako dole). Obdélníčky si obarvíme, ale to je asi
tak všechno. program, tak, jak je napsaný, má podstatnou koncepční
chybu. Měl jich více. Ale já chci teď zadat domácí úkoly - viz pod
obrázkem:

4. Jednu chybu jsem odstranil. Program odesílal na
server požadavek na spínání při každém testování spínacích časů. To už
není vidlácké, to je opravdový a neskutečný humus. Proto jsem v
programu udělal pomocnou proměnnou stav. Tu si při testech měním podle
jejich výsledků a nakonec si otestuji, zda je třeba poslat povel k
zapnutí nebo vypnutí.
5. Další chybu, která vznikla nedotaženou koncepcí, jsem nechal. A
sice, když si pustím tlačítkem "Start dalších hodin" další
instance, budou se mi tyto prát mezi sebou. Jedny budou chtít, aby
bylo zapnuto, jiné, aby bylo vypnuto. Tento úkol je na přemýšlení:
Vymyslete, jak to udělat, aby spínačky byly zapnuté, pokud alespoň
jedny hodiny posílají povel Zapnuto (svítí jim zelený pruh, na obrázku
jsou to ty vlevo). Řešit můžete na TCP Clientovi nebo na TCP
ControlServeru nebo v obou aplikacích.
A připomněli jste mi, že jsem zapomněl ještě na jednu věc, jak se
dělá. Když potřebujete z jedné aplikace pustit druhou, jde to příkazem
Shell a dělal jsem to např. takto:
Private
Sub
Button4_Click(ByVal
sender As
System.Object, ByVal
e As
System.EventArgs) Handles
Button4.Click
Shell("time_control.exe",
AppWinStyle.NormalFocus) ' po
kliknutí spouští naše aplikace sama sebe v další instanci
End
Sub
Zdravím, právě se vláček blíží k domovu, víc
toho dneska nenapíšu ... |