# Datové elementy a výrazy

Niclaus Wirth (autor programovacího jazyka Pascal) v předmluvě své knihy "Algoritmy a struktury údajů" (v originále "Algorithms + Data Structures = Programs") píše: "Prvním důvodem vzniku knihy je jakýsi intuitivní pocit prioritnějšího postavení údajů vůči algoritmům; nejdříve musíme mít nějaké objekty a až potom na ně můžeme aplikovat určité operace."

Každý algoritmus musí mít k dispozici oblast (obyčejně v paměti počítače), ve které jsou uloženy jeho výpočetní stavy. I velmi jednoduché programy musí uložit svá vstupní data, mezivýsledky výpočtů a nakonec (případně) výsledek — bez dat programy zkrátka nemohou pracovat. Musí tudíž existovat způsob, jak data za chodu aplikace (programu) jednoduše schovávat a opět používat.

## O datových elementech

Systém Control Web nabízí hned několik druhů dat. Obecnou strukturní i funkční jednotkou všech těchto druhů dat je datový element. Jednotlivé druhy elementů se od sebe navzájem liší významem i použitím — jejich společnou vlastností zůstává pouze to, že slouží k zaznamenání údajů.

Pojem datového elementu je dosti široký a různá místa vysvětlující různé vlastnosti systému Control Web na něj nahlížejí z několika mírně odlišných úhlů. Jednotlivé úhly pohledu vždy vyzdvihují (na úkor ostatních) některý z typických rysů elementu, což významně zjednodušuje a zpřehledňuje popis. Zároveň tak nenásilně vznikla kategorizace datových elementů podle jejich vlastností:

- V prvé řadě je datový element paměťové místo, které (fyzicky) umožňuje úschovu hodnoty. Tento pohled je důležitý hlavně v situaci, kdy vás přednostně zajímá paměťová náročnost datových elementů — například při síťových komunikacích systému Control Web nebo při komunikacích s ovladači. Jinými slovy, datový element v tomto pohledu obsazuje část paměti počítače a tato paměť je zaplněna jeho hodnotou — nějakou abstrakcí reálné veličiny.
- Každý datový element může být součástí výrazu nebo vstupem přístroje — přístroj jej čte. Některé elementy mohou přijímat výstupy přístrojů — přístroje do nich zapisují. Datový element tudíž vytváří pojítko, prostředek, pomocí nějž si mezi sebou přístroje (a jiné objekty) vyměňují informace. Stejně dobře také můžete datové elementy použít pouze pro předávání mezivýsledků během výpočtů uvnitř jednoho přístroje — datový element opět slouží jako pojítko, tentokrát ale jako pojítko vnitřní. Všimněte si, že z obou příkladů vyplývá, že konkrétní datové elementy mohou být použity na různých úrovních (třeba jen ve výrazech, nebo jen jako datové spoje — jako médium pro výměnu informace mezi objekty). Různé úrovně použití automaticky dělí datové elementy podle přístupnosti pro jiné objekty — podle viditelnosti. Tento úhel pohledu ukazuje datový element jako prvek nějaké vyšší struktury — například globální elementy patří aplikaci a jsou dostupné ze všech objektů, naopak lokální elementy patří například proceduře a jsou dostupné jen uvnitř ní samé.
- Datový element může obsahovat data okamžitě dosažitelná, nebo data, která musejí být nejprve nějakým mechanizmem dopravena z místa jejich prvotního výskytu. Z toho vyplývá, že datový element může být v různých okamžicích různě platný. Dále vyplývá, že každý datový element, který není přímo k dispozici, musí být uvnitř aplikace uchováván až do okamžiku získání nové hodnoty. K tomu slouží datové struktury — caches, vnitřní datové oblasti — které každý datový element po úspěšném přenosu uloží, a kdykoli v případě potřeby poskytnou. Tento pohled na datový element je primární pro pochopení závislostí aplikace a komunikací.
- Ne každý element musí být schopen data přijmout i poskytnout. Některé z nich slouží pouze k získávání dat — nelze do nich zapisovat, jiné pouze k zápisu hodnot — nemělo by být možné z nich číst (v systému Control Web z takových elementů můžete číst díky vnitřním datovým oblastem). Datový element tedy může být směrový, jiné známé (ekvivalentní) označení je potom read-only (jen pro čtení) a read-write (pro čtení i zápis).

Pokud uvedené čtyři body (pohledy) shrnete, vznikne datový element, který uchovává obraz nějaké veličiny, patří nějakému objektu (mimo něj není element dostupný), nemusí být ve všech časových okamžicích stejně kvalitní a navíc může být pouze jednosměrný (určený jen pro vstup nebo výstup).

### Identifikátory

Každý datový element v aplikaci musí mít své jednoznačné pojmenování, které umožní jeho přesnou identifikaci. Sytém Control Web používá pro jména datových elementů (a také pro jména modulů, přístrojů a procedur) identifikátory. Identifikátor je skupina znaků která:

- nesmí začínat číslicí
- nesmí začínat separátorem
- končí separátorem
- je dlouhá maximálně 64 znaků

Mezi separátory Control Web počítá následující znaky:

`<Tabulátor> <LF> <CR> <EOF> <Mezera> + - * / : \ , : ( ) [ ] { } ^ = #`

Identifikátor tudíž může obsahovat všechny ostatní znaky, včetně znaků s diakritickými znaménky. Identifikátory používané v nejrůznějších programovacích jazycích bývají zpravidla omezenější — například identifikátory v jazycích Pascal a C mohou obsahovat pouze písmena, číslice (ovšem ne na začátku identifikátoru) a podtržítko. Control Web je benevolentnější, avšak množina všech v současnosti povolených znaků (kromě písmen, číslic a podtržítka) může být v některé z pokročilejších verzí zúžena.

### Datové typy

Datový element slouží k uchování dat, přičemž význam těmto datům vždy přisuzujete vy — tvůrci aplikace (s malou výjimkou systémových datových elementů). Význam veličiny obyčejně přesně ukazuje na datový typ elementu, neboli na strukturu a podobu dat v něm uchovávaných. Control Web rozeznává čtyři hlavní skupiny typů dat:

- logické hodnoty, které obsahují binární hodnotu, tedy hodnotu vyjadřující stav zapnuto/vypnuto (true/false).
- číselné hodnoty, které se (jako jediná skupina typů) dělí podle druhu čísel na samostatné rozlišené datové typy. Čísla v systému Control Web jsou buď desetinná, nebo celá, a to buď se znaménkem, nebo bez znaménka. Pro operace s čísly platí určitá pravidla, která přesně určují jejich chování. Číslům je věnován samostatný oddíl této kapitoly — Číselné datové typy.
- řetezce znaků, které obsahují skupiny písmen (libovolné kromě znaku s hodnotou 0) až do souhrnné délky 256 znaků. Pokud řetězec zcela nevyplňuje prostor 256 znaků, je za posledním platným znakem znak s hodnotou 0 (nikoliv znak "0", jehož ordinální číslo je 48, ale nezobrazitelný znak s ordinálním číslem 0). Pokud tento znak na první pozici, řetězec je prázdný.
- datový typ buffer obsahuje blok paměti, který je nějak vnitřně strukturován. Jádro systému Control Web definuje pouze základní parametry (například délku bufferu), zbytek, čili vlastní organizace bufferu vyplývá z konkrétního použití. Například, použijete-li knihovnu objektů pro DSP — digitální zpracování signálu, bude Control Web automaticky pracovat s buffery, které mají organizaci dat odpovídající knihovně DSP. Samozřejmě, data se do systému Control Web musejí nějak dostat, a ovladač proto musí patřičné struktuře bufferu rozumět, aby ji mohl správně naplnit. Datový typ buffer je velmi flexibilní a je zcela otevřen pro případné speciální použití. Na druhou stranu, ostatní prostředky a datové typy systému Control Web jsou tak mocné, že potřeba vytvořit nový typ bufferu pro nějaká speciální data nejspíše nikdy nevyvstane.

Jednotlivé datové typy odpovídající popsaným skupinám jsou přesně definovány. Pro každý typ je předem znám jeho rozsah, způsob zápisu (konstruktor), binární vyjádření i konkrétní symbolický název (klíčové slovo) používaný v aplikaci. Všechny datové elementy jsou v paměti uspořádány shodně ve formátu "Little Endian", tedy v pořadí, kdy byte (slabika) s nižším významem obsazuje v paměti místo s nižší adresou. Desetinná čísla systém Control Web zapisuje ve formátu IEEE.754, což je formát používaný například v procesorech Intel. Možné datové typy i s jejich charakteristikami ukazuje následující tabulka:

Datové typy

Údaje o velikostech typů přesně odpovídají popsanému rozsahu hodnot, bohužel však neříkají nic o skutečné velikosti obsazené paměti. Systém Control Web uchovává veškeré datové elementy ve speciální datové struktuře TValue (pro zájemce je jeho definice uvedena v kapitole Komunikace, ovladače a kanály, která má délku 12 byte. Všechny elementy jsou proto dlouhé nejméně 12 byte. Navíc, každý datový element má své unikátní jméno, údaje o inicializačních hodnotách, poznámku, a mnoho dalších údajů nutných pro jeho správnou funkci. Dohromady proto každý datový element zabírá v paměti řádově desítky byte.

### Druhy datových elementů

Control Web rozeznává tři druhy datových elementů — konstanty, proměnné a kanály.

#### Konstanty

Konstanty jsou datové elementy určené pouze pro čtení. Mohou obsahovat data (s výjimkou datového typu buffer) jakéhokoli typu, jsou dostupné neustále a mají tudíž vždy platnou hodnotu. Konstanty mohou být globální (definované v aplikační sekci const, lokální v přístroji (definované v sekci const přístroje) a lokální v proceduře (definované v sekci const procedury).

Konstanty slouží hlavně člověku — umožňují symbolicky pojmenovat jinak nezřetelné číslo nebo umožňují vícekrát použít jednu hodnotu zadanou na jediném místě (v definici konstanty). Typickými konstantami jsou například Ludolfovo číslo (tato konstanta je dokonce systémová) nebo převodní koeficienty jednotek (například 0,017453292 pro převod ze stupňů na radiány). Konstanta určuje svůj typ automaticky ze své hodnoty, takže typ konstanty není nutné zadávat explicitně. Příklad zápisu konstant všech základních typů můžete použít na všech možných místech výskytu — v aplikaci, přístroji i proceduře (ukončení sekce end_const se v procedurách nepoužívá, je nutné ho uvádět pouze při definici globálních a přístrojových konstant):

    const
      Odmocnina2 = 1.4142;
      CelýNázev = 'Hlavní plynová kotelna v Horní-Dolní';
      Zapnuto = true;
    end_const;

Číselné konstanty dokáží automaticky přispůsobit svůj typ jiným číselným typům podle kontextu použití. Konstantu Odmocnina2 můžete použít ve výrazu (tehdy bude mít skutečně hodnotu 1,4142, neboť výpočty výrazů vždy probíhají v desetinných číslech) nebo v definici parametru access_level (a tehdy nabude hodnoty 1, neboť uvedený parametr přijímá pouze celá čísla). Je možné říci, že z konstanty se použije vždy maximum informace. Pokud není možné využít informaci celou (jako v našem případě), dojde k úpravě hodnoty tak, aby byla v daném místě přijatelná — je-li místo desetinného čísla vyžadováno číslo celé, je desetinná část čísla odřezána.

Konstanty je možné použít ve výrazech kdekoli místo literálu odpovídajícího typu. Stejně dobře je možné konstanty použít na většině míst, která jsou statickými parametry objektů aplikace. Konstantu proto využijete například v definici kanálů (jako parametr timeout nebo v definici přístroje (parametry timer, access_level, ...).

#### Proměnné

Proměnné jsou datové elementy obousměrné (pro zápis i čtení), jakéhokoli datového typu, dostupné okamžitě. Stejně jako konstanty mohou být proměnné globální, nebo lokální na různých úrovních. Proměnné slouží primárně k úschově vnitřních stavů aplikace. Obyčejně se proměnných používá také pro zpřehlednění výpočtů: nejprve se vypočítají mezivýsledky, které se uloží do pomocných proměnných, a teprve poté se provede hlavní výpočet již s hodnotami mezivýsledků uloženými v pomocných proměnných.

Proměnné musejí při startu aplikace získat počáteční hodnotu, která musí být do proměnné zapsána ještě před rozběhem — aby bylo zaručeno, že přístroje vždy vyčtou z proměnné definovanou hodnotu (místo hodnoty nedefinovné a tedy potenciálně velmi nevhodné). Zápis první hodnoty se nazývá inicializace, počáteční hodnota je potom inicializační hodnota. Veškeré proměnné jsou inicializovány alespoň jedenkrát. Podle příslušnosti proměnné k určitému objektu (aplikaci, přístroji nebo proceduře) může proměnná být za běhu aplikace inicializována i vícekrát. V prvém přiblížení je možné říci, že proměnné, které jsou inicializovány vícekrát jsou proměnné normální (variable), zatímco proměnné, které systém inicializuje jen jednou, jsou proměnné statické (static). Situaci znázorňuje obrázek:

Inicializace proměnných

Podrobný popis použití lokálních elementů včetně popisů inicializací a potenciálních problémů nabízí kapitola Programování a procedury — OCL. Je možné říci, že statické proměnné "přežívají" a vždy obsahují poslední hodnotu, kterou do nich aplikace zapsala, zatímco normální proměnné jsou vždy před použitím v definovaném místě (podle tabulky) inicializovány.

Obě dvě varianty proměnných — variable a static — mají shodnou syntaxi zápisu. Sekce var může být umístěna do aplikace, přístroje nebo procedury, sekce static pouze do přístroje nebo procedury, na globální úrovni její použití nemá význam, neboť globální proměnné jsou tak jako tak inicializovány jen jednou při startu aplikace. Příklad ukazuje zápis proměnných všech skupin typů:

    var
      TeplotaVody = real, 10;
      JménoUživatele = string, 'nikdo nezapsán';
      SvítíSe = boolean, true;
      Buffer1 = buffer, 10, cardinal;
    end_var;

Stejně jako v případě konstant je klíčové slovo end_var na globální a přístrojpvé úrovni vyžadováno a v procedurách odmítáno, end_static je přípustné jen na úrovni přístrojů. Jistě jste zaznamenali, že proměnná má explicitně zadán svůj datový typ. To je nutné, neboť proměnná (na rozdíl od konstanty) dokáže hodnotu i přijmout, přičemž je nutné rozlišit, jestli se někdo nepokouší do proměnné uschovat data nevhodného typu. Například, je nesmysl ukládat výsledek číselného výpočtu do řetězcové proměnné — nicméně bez udání typu proměnné by takovému chybnému přiřazení nebylo možné zabránit, protože by systém nemohl posoudit, že si typy dat navzájem neodpovídají.

Proměnné využijete nejspíše mnohem častěji než ostatní elementy, protože jsou nejméně omezeny dodatečnými pravidly. Většina údajů předávaných uvnitř aplikace mezi přístroji bude uschována právě v proměnných.

#### Kanály

Kanály jsou datové elementy s určeným směrem (mohou být vstupní — input, výstupní — output nebo obousměrné — bidirectional), libovolného datového typu, mohou být pouze globální (nemůže existovat kanál definovaný jen v určité proceduře) a nejsou kdykoli volně dosažitelné.

Naposled jmenovaná vlastnost kanálů je asi nejdůležitější, a také bohužel nejkomplikovanější. Asi nebude daleko od pravdy tvrzení, že celý problém průmyslové automatizace sestává ze dvou úloh (navzájem propojených) — první, jak efektivně a účinně sbírat data a posílat je zpět, a druhé, jak efektivně a účinně data zpracovat — vizualizace a archivace a výsledky aplikovat — řízení. Kanály spolu s ovladači v aplikaci systému Control Web řeší úlohu první — komunikační.

Každý kanál v aplikaci je projekcí nějakého fyzicky existujícího signálu nebo řídicího prvku. Obojí (signál i řídicí prvek) je přímo svázáno s fyzikální podstatou konkrétní veličiny a kanály tak uvnitř aplikace symbolizují a modelují reálný svět. Spojení kanálu s konkrétním snímačem obstarává ovladač, který nějakým způsobem dokáže ze snímačů přečíst(nebo do řídicích prvků zapsat) aktuální hodnotu veličiny. Ovladač nabízí podle své konfigurace množinu dostupných vstupů a výstupů a každý takový vstup nebo výstup může být v aplikaci použit jako kanál:

Signály a kanály

Povolené vstupy a výstupy ovladače definuje mapovací soubor ('*.dmf'). Údaje z toho souboru používá během překladu Control Web pro ověření správnosti definice kanálu. '*.dmf' soubor se tedy uplatňuje jen při překladu a není s ovladačem fyzicky svázán (jeden '*.dmf' můžete použít pro různé ovladače). Skutečný konfigurační soubor, který zpravidla obsahuje i přesné definice vstupů a výstupů ovladače, je soubor parametrický ('*.par'). Oba soubory, mapovací i parametrický, jsou součástí definice ovladače.

Kanál použitý v aplikaci je svázán s různými konfiguračními soubory takto (popsané schéma je ilustrační a nemusí vždy platit, přesto však v 95 % případů odpovídá skutečnosti):

- ovladač podle parametrického souboru vybuduje vnitřní struktury, které nabízí pod jednotlivými čísly jako své vstupy nebo výstupy.
- programátor definuje v aplikaci kanál určitého typu a přiřadí mu číslo vstupu nebo výstupu ovladače.
- překladač během načítání kanálů srovnává jejich definice s mapovacím souborem. Pokud směr nebo typ kanálu daného čísla neodpovídá, hlásí překladač chybu překladu.
- běžící aplikace může zapsat do kanálu (nebo číst z kanálu) zkontrolovaného překladačem (pomocí mapovacího souboru) hodnotu, která neodpovídá parametrickému souboru ovladače. Tehdy ovladač data nepřijme a hlásí chybu komunikace.

Z bodů 1, 3 a 4 bezprostředně vyplývá, že soubory '*.dmf' a '*.par' musí být ve vzájemném souladu. Dostupné ovladače většinou v mapovacím souboru nabízejí jakousi maximální množinu kanálů, která je potom v parametrickém souboru použita jen z části (jako podmnožina). Konkrétní zápisy konfigurací ovladačů jsou vždy součástí jeho dokumentace.

Kanály mají směr, mohou být vstupní (input), výstupní (output) nebo obousměrné (bidirectional). První varianty jsou přirozené — vstup slouží ke sběru dat a výstup k ovládání. Pokud kanály přímo reprezentují skutečné snímače a řídicí prvky, je zřejmé, že snímač bude vstupem a řídicí prvek výstupem. V určitých případech může být výhodné použít kanál, který je obousměrný. Dosti často se tento druh kanálů používá při komunikacích s průmyslovými automaty, kdy je kanál projekcí nějakého vnitřního registru automatu — přímá vazba na snímač nebo ovládací prvek je zde přetržena. Použití obousměrného kanálu může zjednodušit některé aplikační operace. Ale pozor. Z hlediska programátorské čistoty, přehlednosti aplikace a elegance návrhu je velmi dobré obousměrné kanály nepoužívat. Obousměrný kanál sice umožňuje zápis i čtení, nicméně tento fakt nijak neovlivňuje základní vlastnost kanálů — potenciální nedostupnost. Obousměrný kanál proto může současně čekat na výsledek měření i na potvrzení zápisu hodnoty do ovladače (a tím i do technologie). Tehdy se ve vnitřní datové oblasti a v technologii mohou vyskytnout různé hodnoty, přičemž analýza toho, která hodnota se kde ocitne je téměř neuskutečnitelná. Mechanizmus komunikace přístrojů, jádra systému Control Web a ovladačů je sice přesně definován a dodržován, ale při narůstajícím množství komunikací je kvantitativní složitost analyzovaných procesů tak velká, že se nevyplatí (finačně ani časově) o analýzu ani pokoušet. Použití obousměrných kanálů je proto třeba dobře promyslet, zejména v situacích, kdy mohou kriticky ovlivnit chování automatizační úlohy.

Vstupní kanály jsou systémem Control Web měřeny podle potřeb aplikace. V principu je schéma měřicí komunikace následující:

- aplikace požaduje (například pro výpočet) veličinu z technologie. Ta je reprezentovaná kanálem.
- jádro systému požadavek zpracuje a požádá patřičný ovladač o změření hodnoty veličiny.
- jádro systému podle definice prodlev (timeout) případně počká na dokončení komunikace.
- aplikace dále postupuje s nově změřenou hodnotou veličiny s možností zjistit skutečný výsledek komunikace.

Kanály výstupní nemusejí být měřeny, většinou stačí požadavek zapsat do ovladače, který již zajistí skutečný přenos až na konečné místo. Nicméně i na výsledek zápisu dat je možné počkat:

- aplikace potřebuje zapsat veličinu do technologie. Veličina je reprezentovaná kanálem.
- jádro systému požadavek zpracuje a požádá patřičný ovladač o zapsání hodnoty veličiny.
- jádro systému podle definice prodlev (timeout) případně počká na dokončení komunikace.
- aplikace dále pokračuje s možností zjistit skutečný výsledek komunikace.

Hlavní rozdíl mezi vstupy a výstupy je následující: vstupní kanál je správný v techologii a aplikace by na jeho změření měla počkat, aby také pracovala se správnou hodnotou; výstupní kanál je správný v aplikaci a do techologie se pouze přenáší — aplikace vlastní správnou hodnotu a nemusí proto čekat na dokončení komunikace.

V obou případech byla zmíněna prodleva komunikace, která ovlivňuje vzájemné chování ovladače a jádra systému. Prodleva může být nastavena v systému globálně — pro všechny kanály najednou, nebo pro každý kanál individuálně v jeho parametru timeout. Oba způsoby individuální i globální je možné kombinovat, takže můžete globálně ovlivnit všechny kanály najednou a jen u některých z nich komunikační parametry ovlivnit speciálně.

Obousměrné kanály se chovají jako vstupní kanály s možností zápisu, a přijímají proto veškerá nastavení vstupních kanálů.

O způsobech komunikace, časovém kroku, prodlevách a mechanizmu překryvů u obousměrných kanálů pojednává velmi podrobně kapitola Časování aplikací reálného času.

Ukázka zápisu kanálů může být například následující (připomínám, že kanály mohou být definovány pouze na globální úrovni — není možné vytvořit kanál pouze pro proceduru):

    channel
      TeplotaKotle1 = real, 1005, Simatic, input;
      OtevřeníKlapky = real, 2001, Simatic, output, 0.5;
      HořákHoří = boolean, 3010, Simatic, input;
      Buffer2 = buffer, 4000, cardinal, 10, LabCard, input;
    end_channel;

Parametry kanálů za sebou následují v pořadí: datový typ (real), číslo kanálu v ovladači (1005), symbolické jméno ovladače (Simatic) a směr (input). Výstupní kanály navíc potřebují (stejně jako proměnné) inicializační hodnotu (0.5). Výstupní kanály po inicializaci zapisují svou (inicializační) hodnotu do ovladače (a tím i do technologie), čímž se zaručí, že na obou místech (reálném i aplikačním) budou shodná data. Samozřejmě, chování systému při inicializaci můžete téměř libovolně ovlivnit, například popisovaný zápis inicializačních hodnot je možné ovlivnit pomocí parametru aplikace skip_init_outputs. Popis a chování parametrů časování a inicializace najdete v kapitole Časování aplikací reálného času.

Podobně jako proměnné můžete kanály použít kdekoli na vstupu přístroje, výstupu přístroje nebo ve výrazu. Překladač přitom hlídá (a odmítá) pokusy zapsat do vstupních kanálů.

V aplikaci kanály vždy představují živá data, která mění svou hodnotu nezavisle na aplikaci.

### Číselné datové typy

Čísla mohou být v principu desetinná, nebo celá. Člověk mezi nimi zase až takový rozdíl nedělá, ale pro počítač to jsou dvě zcela rozdílné oblasti problémů — desetinná čísla jsou komplikovanější, zato ale dokáží pokrýt mnohem větší rozsah hodnot.

Pozor na odlišné konvence zápisu desetinných čísel v našich a anglosaských zemích. Zatímco u nás je obvyklé oddělovat desetinnou část čísla čárkou, v anglosaských zemích se používá tečka. Control Web používá stejně jako všechny ostatní vývojové systémy a programovací jazyky desetinnou tečku. Pokud v přístroji použijete zápis expression = a * 1,9;, systém ohlásí chybu. Pokud ale stejné číslo zapíšete u klíčového slova timer, žádná chyba hlášena nebude, systém údaj akceptuje jako časování s periodou 1 a posunutím 9.

Jednotlivé číselné typy jsou v systému Control Web navzájem kompatibilní (zástupné) a můžete je používat bez obav z kolize typů. Číselné datové elementy se v aplikaci vyskytují na různých místech, přičemž jejich vzájemnou kompatibilitu je ve všech takových případech třeba zajistit (kompatibilita není samozřejmá věc). V systému Control Web přicházejí v úvahu následující způsoby použití číselných elementů:

- prvek výrazu — číselný výraz je v systému Control Web vždy typu real. To znamená, že výsledek jakéhokoli výpočtu, ať již použijete elementy jakýchkoli typů, vždy bude typu real. Speciální zmínku zasluhuje následující chování: většina přístrojů očekává na místech svých vstupů výraz. Zapíšete-li na takové místo vstupu samostatný datový element (například typu integer), bude i tento samostatný element vyhodnocen jako výraz (i když má takový výraz jen jeden prvek) — a výsledek proto bude typu real. Příklad — výsledek součtu dvou čísel shortcard, jednoho 160 a druhého 220, bude 380 (a ne 124, což by byl výsledek přijatelný v případě, že by se celý výpočet provedl v číslech shorcard).
- uložení a získání hodnoty — ukládání hodnot elementů je s popsanými výpočty výrazů úzce spjato. Veškeré číselné proměnné jsou uvnitř systému uchovávány jako real. Pokud nějaký objekt zapíše data do systému, jsou tato data převedena na typ real, pokud někdo požádá o číselný datový element, jsou data konvertována do vnějšího datového typu (třeba shortcard) (tak pracuje například monitor, který čte hodnotu elementu přímo bez výpočtu výrazu, a proto vždy zobrazuje hodnotu, která odpovídá datovému typu elementu). Výpočet výrazu předpokládá, že je číselný element uložen jako real a žádnou konverzi neprovádí. Stejně se chová i ukládání hodnoty — výsledek výrazu je vždy real (což odpovídá vnitřnímu formátu dat), a proto se při ukládání výsledku výrazu opět konverze neprovádí.

Uvažme tedy znovu uvedený příklad součtu čísel 160[shortcard] a 220[shortcard]. Výsledek bude 380[real] a zapíše se do vnitřních dat jako 380[real], neboť typ výsledku výrazu odpovídá typu vnitřních dat. Následné čtení tohoto datového elementu (například v přístroji monitor) zobrazí hodnotu 124[shortcard], zatímco následné použití tohoto elementu ve výraze (například na vstupu přístroje meter v parametru expression) bez konverze opět ukáže 380[real] (neboť výraz přímo použije uschovanou hodnotu). Vyzkoušejte si to.

- předávání parametrů do procedur — je velmi blízké ukládání hodnoty. Parametry předávané při volání do procedury se po dobu jejího běhu stávají její součástí jako lokální datové elementy. Jsou tedy součástí vnitřních datových struktur. Pro tyto struktury přitom platí již popsaná pravidla pro čtení a ukládání. Identicky se systém chová v případě navracení hodnot z procedury — výsledná data se opět ukládají do (jiných) datových struktur za použití stejných pravidel.
- zobrazení hodnoty — má-li se číslo objevit na obrazovce, musí být převedno do řetězcové podoby (neboť jediný možný způsob výpisu čísel je po znacích — číslicích). Počítač pracuje s čísly ve dvojkové podobě, člověk očekává podobu desítkovou. Bohužel, většinou platí, že "pěkné" desítkové číslo s malým počtem destinných míst není možné vyjádřit ve dvojkové podobě pomocí konečného počtu dvojkových číslic. Například, desetinné číslo 0,125 ve dvojkové podobě existuje v přesném zápise, číslo 0,1 má ve dvojkové podobě neukončený rozvoj. Oblast pro číslo je však omezená, a neukončené číslo proto bude zapsáno s největší možnou přesností, která odpovídá asi 18 desítkovým řádům. Pokud takové (již nepřesné) dvojkové číslo převedete zpět do desítkové soustavy, nepřesnost se projeví, a místo čísla 0,1 dostanete například 0,099999999999999998. Z matematického hlediska je to totéž, ale zápis není pěkný a tudíž je nevhodný. Popsané matematické chyby je možné rozeznávat a opravovat, nicméně korekční mechanizmus dokáže spolehlivě pracovat jen s určitou rezervou, která způsobí, že zaručená přesnost desetinných čísel klesne na 15 desítkových řádů. V celém systému proto neustále při zobrazování hodnot dochází ke korekcím, které s využitím 3 neviditelných řádů dokáží zkonstruovat správnou podobu zobrazovaného čísla. Problém nepřesných čísel se překvapivě neobjevuje ani tak při reálných výpočtech, jako spíše při běžných definicích jednoduchých čísel — v zápisech mezí, prodlev, časovačů a inicializačních hodnot.

Tam všude jsou čísla při zápisu upravována. Velmi pěkně je nepřesný zápis dvojkových čísel vidět například při vývoji ovladačů, kdy má programátor možnost nahlížet přímo na binární tvar čísla uložený v paměti.

Problém zápisu čísel je více než technický spíše estetický. Přirozená (a proto správná) podoba čísla pro počítač je dvojková, přirozená (a proto správná) podoba pro člověka je desítková. Takže je nutné čísla neustále přizpůsobovat.

Popsaná pravidla platí v celém systému Control Web univerzálně. Aplikování těchto pravidel vede k tomu, že při běžné práci není programátor nucen nad čísly nijak přemýšlet — výsledné chování systému je intuitivní. Uvedení přesného popisu pravidel však bylo nutné, neboť v určitých speciálních případech programátor potřebuje přesně vědět, jak se výpočet nebo datový element zachová.

Poslední zmínka v oddíle o číselných datových typech je věnována bitovým operacím, pro které jsou v systému Control Web definovány speciální funkce. Všechny takové bitové funkce nejprve převedou vstupní číselnou hodnotu na datový typ longcard (celé 32bitové bezznaménkové číslo), nad touto hodnotou posléze provedou patřičnou operaci a výsledek vrátí v datovém typu real. Konverze na celé bezznaménkové číslo probíhá automaticky uvnitř funkcí, a proto například volání funkce bitget( 128.21, 7 ) správně skončí výsledkem 1,0. Číslo 128,21 je nejprve převedeno na číslo 128 a teprve poté je v něm testován bit 7. Popis všech funkcí (nejen bitových) je součástí posledního oddílu této kapitoly.

### Pole

Všechny datové typy (kromě typu buffer) umožňují vytvoření souvislé oblasti dat, která najednou obsáhne řadu elementů stejného typu. Jednotlivé prvky takové struktury jsou přístupné pomocí indexu, jakéhosi pořadového čísla, celá struktura se nazývá pole. Počáteční a koncový index je u proměnných libovolně volitelný, u kanálů musí odpovídat mapovacímu souboru. Snadno tedy sestrojíte jak pole elementů s indexy 52..54 tak s indexy 0..2. Obě pole budou v paměti zabírat oblast o velikosti třech hodnot datových elementů. Pole jsou v paměti skladována efektivněji než samostatné datové elementy, neboť jedno pole s jedním typem a jedním jménem zahrnuje několik elementů (které již nemusejí být samostatně pojmenovávány ani typovány). Číselná pole jsou skladována v blocích po 8 byte (velikost typu real, který, jak již víte, slouží k vnitřní úschově čísel) a logická pole v blocích po 1 byte. Ilustrační obrázek ukazuje organizaci několika samostatných elementů a pole:

Pole a skaláry

Není dost dobře možné říci, kdy použít pole a kdy samostatnou proměnnou. Obyčejně se programátor intuitivně přikloní k variantě, která mu lépe vyhovuje.

Prvek pole je možné použít stejně jako jednoduchý datový element. Je lhostejné, napíšete-li místo elementu var1 element pole ar[1]. Navíc, zápis prvku pole může být velmi mocnou zbraní, protože index (v ukázce a) je také výrazem, a může za běhu aplikace nabývat různých hodnot. Proto lze zkonstruovat následující sekvenci výrazů:

    a = b + c;
    výsledek[a] = teplota[a];

Z obou polí (výsledek i teplota) bude vždy použit prvek s indexem odpovídajícím hodnotě datového elementu a.

Definice polí je velmi jednoduchá, do zápisu definic proměnných a kanálů musí pouze přibýt indexy a klíčové slovo array (pole):

    var
      výsledek = array [0..49] of real, 0;
    end_var;

    channel
      teplota = array [0..49] of real, Simatic, input;
    end_channel;

### Externí datové elementy

Control Web dokáže najednou provozovat více modulů (na více počítačích) v rámci jednoho projektu. Jednotlivé moduly navzájem mohou přistupovat na svá data, ať už se jedná o proměnné nebo kanály. Systém přitom standardně zajišťuje vzájemnou synchronizaci modulů — například kanály budou vždy korektně změřeny i ve vzdáleném modulu. Přenos dat po síti probíhá skrytě, v aplikaci samotné se použití externího datového elementu projevuje pouze zápisem jména modulu před jeho jméno:

    ...
    a = b + c; (* lokální elementy *)
    a = modul1.b + modul2.c; (* externí elementy *)
    ...

Prvý výraz používá elementů b a c přítomných přímo v modulu, druhý výraz potom element b vyčítá z modulu modul1 a element c z modulu modul2. Vyčítání a zápis vzdálených datových elementů probíhá (podobně jako komunikace u kanálů) s určitým časovým zpožděním. Proto jsou (stejně jako u kanálů) definovány prodlevy a nastavení, která mohou komunikaci ovlivnit nejrůznějším způsobem. Rozdíl mezi komunikací kanálů a externích elementů spočívá v okamžiku uskutečnění komunikace. Kanály se vždy měří před rozběhem přístrojů v časovém kroku, externí datové elementy se komunikují podle potřeby za chodu přístrojů. Obecně platí, že kanály jsou zpracovávány i komunikovány skupinově, zatímco externí elementy jsou zpracovávány sekvenčně a komunikovány skupinově. Nepromyšlená komunikace externích datových elementů proto může aplikaci zatížit více, než nepromyšlená komunikace kanálů.

Externí datové elementy primárně existují v cizím modulu, který nemusí být vždy dostupný. Systém Control Web zajišťuje jejich dostupnost automaticky při startu aplikace (například tak, že sám na jiných počítačích systémy Control Web spouští). Pokud však aplikace neběží, není možné se vzdáleným modulem navázat komunikaci, a není možné zjistit, jaké má požadovaný element vlastnosti — jestli to je pole, jakého je datového typu a případně jestli to je kanál, nebo proměnná.

Externí datové elementy jsou proto při vývoji aplikace ve výrazech a přístrojích akceptovány "tak jak jsou" a překladač nad nimi neprovádí žádné kontroly. Z toho vyplývá, že je možné při vývoji používat chybné nebo neexistující externí datové elementy, aniž by byla jakákoli možnost chybu odhalit. Vše se zkontroluje až při spouštění aplikace, neboť až tehdy dokáže Control Web získat všechny potřebné údaje.

Modulům, mezimodulárním komunikacím a externím elementům se samostatně věnuje kapitola Modulární a distribuované aplikace.

### Atributy

Kanály a externí datové elementy jsou natolik komplexní, že pro přesné sledování dějů mnohdy jejich samotná hodnota nestačí. Control Web proto u těchto elementů nabízí prostředek, s jehož pomocí můžete o každém kanálu nebo externím elementu zjistit mnoho podružných informací — například statistické údaje o komunikaci.

Atributy se chovají podobně jako proměnné a jsou kdykoli k dosažení (nevynucují žádnou komunikaci). Některé z atributů jsou navíc určeny pouze pro čtení, takže pokus o zápis způsobí chybu překladu. Syntaxe zápisu atributu ve zdrojovém textu vyžaduje připojení znaku : se jménem atributu za jméno datového elementu:

    ...
    kanál:fix = true;
    ...

Atributů je celá řada, některé jsou společné pro kanály i externí elementy, některé jsou jen pro čtení. Control Web podporuje následující atributy (v hranatých závorkách je zapsáno [K] či [E], je-li atribut platný pro kanály nebo externí element, a [R], je-li atribut určen pouze pro čtení):

- `[KER]`status — atribut, který obsahuje aktuální informace o komunikaci elementu. Komunikace v principu vždy probíhá podle schématu požadavek — čekání na odpověď — odpověď, přičemž informace atributu status těmto stavům přesně odpovídají. Možných stavů je několik, a proto jsou v atributu vyjádřeny pomocí bitů. Patřičný stav je možné z atributu vyčíst pomocí některé z bitových funkcí (například bitget). Přesný význam jednotlivých stavů, spolu s čísly jednotlivých bitů (v hranatých závorkách), uvádí přehled:

- stGetWaitACK[3], stSetWaitACK[1] — bit je nastaven v okamžiku vzniku požadavku na zápis nebo čtení a trvá až do přijetí odpovědi ze zařízení (z jiného modulu) nebo do okamžiku vypršení komunikační prodlevy. Tehdy je nahrazen některým z bitů stTimeout, stACKed, nebo stError.
- stGetTimeout[7], stSetTimeout[4] — bit systém nastaví v okamžiku uplynutí komunikační prodlevy. Prodlevu můžete zrušit — nastavit nulovou — a tehdy bude bit stTimeout nastaven současně s bitem stWaitACK.
- stGetACKed[8], stSetACKed[5] — bit systém nastaví, podaří-li se bezchybně získat z ovladače nebo modulu data. Bity stWaitACK a stTimeout jsou současně vynulovány.
- stGetError[9], stSetError[6] — bit systém nastaví, odpoví-li ovladač nebo modul na požadavek chybou. Stejně jako v případě pozitivní odpovědi jsou bity stWaitACK a stTimeout vynulovány.

Pokud ovladač nebo modul na požadavky neodpovídá (z jakéhokoli důvodu), nebude ani bit stACKed ani bit stError nastaven. Oba dva tyto bity může systém nastavit až v případě získání odpovědi — jak pozitivní tak negativní.

- `[K R]`error — atribut obsahující poslední chybu, která se během komunikace objevila. Hodnota popisující chybu je do atributu zapsána v okamžiku přechodu do stavu Error (viz atribut status) a zůstává beze změny až do výskytu další (jiné) chyby — pokud chybový stav odezní, není hodnota chyby z atributu vymazána. Systém Control Web definuje následující komunikační chyby (v hranatých závorkách jsou číselné hodnoty chyb):

- errorOK[0] — žádná chyba nenastala, komunikace běží bez potíží
- errorTimeout[1] — při komunikaci nastala časová chyba (například vypršel maximální povolený čas pro odpověď průmyslového automatu).
- errorValue[2] — při komunikaci nastala chyba přenosu dat nebo výpočtu (například po sériové lince přišla poškozená data, ze kterých se ovladači nepodařilo správně získat potřebné informace)
- errorUser[3–65535] — chybové kódy specifické pro ovladač. Význam těchto kódů je vždy popsán v dokumentaci ovladače.

Chyby přístupné v atributu error může hlásit pouze ovladač a tyto chyby vždy souvisejí s komunikací, případně ovladačem. Matoucí může být především chyba errorTimeout, neboť vypadá velmi podobně jako definice komunikačních prodlev (také timeout). Mezi chybou komunikace a prodlevami je velký rozdíl — komunikační prodlevy a jejich vypršení za chodu aplikace patří k její normální funkci, jsou správným chováním a nesignalizují zpravidla žádné potíže; zatímco errorTimeout vzniká v ovladači jako reakce na skutečnou komunikační chybu, kterou je třeba vysvětlit a odstranit.

- `[KE ]`value — atribut umožňující přečíst (nebo zapsat) hodnotu datového elementu bez komunikace přímo ze systémové vnitřní datové oblasti. Zápis

`a = vstupní_kanál:value;`

proto nezpůsobí žádnou komunikaci systému s ovladačem a datový element a bude naplněn momentálně přítomnou hodnotou kanálu vstupní_kanál

- `[KE ]` timeout — atribut obsahuje komunikační prodlevu datového elementu. V kapitolách o časování je význam všech prodlev (i veškerých mechanizmů komunikací) přesně popsán, atribut umožňuje prodlevu dynamicky za běhu aplikace přizpůsobovat aktuálnímu stavu. Hodnota prodlevy v atributu je vyjádřena v sekudách.
- `[K R]`time_stamp, time_stamp_year, time_stamp_month, time_stamp_day,
  time_stamp_jd — některé ovladače poskytují spolu s hodnotou datového elementu navíc i časovou značku okamžiku změření hodnoty (respektive časovou značku s významem, který je přesně určen ovladačem). Časová značka obsahuje úplné datum a čas s milisekundovým rozlišením. Ovladač nemusí nutně všechny údaje (například datum) poskytovat, a celá značka tudíž nemusí být kompletní. Atribut time_stamp obsahuje časový údaj v sekundách od půlnoci (včetně zlomků sekundy), další atributy poskytují po částech datum a nakonec atribut time_stamp_jd shrnuje všechny čtyři atributy do jedné hodnoty nesoucí časovou značku ve tvaru Juliánského data. Pokud použitý ovladač předávání časových značek nepodporuje, obsahují popsané atributy hodnotu 0.
- `[KER]`last_ack — atribut obsahuje čas, který uplynul od poslední úspěšně dokončené komunikace.
- `[KER]`requests — počet požadavků na komunikaci datového elementu
- `[KER]`hits — počet požadavků, které byly komunikujícím zařízením (nebo modulem) potvrzeny před uplynutím komunikační prodlevy. V případě, že bude komunikační prodleva dostatečně velká, bude hodnota tohoto atributu rovna hodnotě atributu requests. Poměr těchto dvou hodnot potom ukazuje, jaké poměrné množství komunikací skutečně poskytlo objektům aplikace nově změřenou hodnotu.
- `[KER]`rtt — round-trip-time, neboli čas, který uplyne od okamžiku vzniku požadavku na komunikaci do okamžiku jejího úspěšného dokončení (chcete-li, jedná se o čas mezi vznikem stavu stWaitACK a přechodem do stavu stACKed). Tento atribut velmi přesně ukazuje, jak dlouho průměrně trvá jedna komunikace datového elementu, což může zejména při vývoji aplikace pomoci vyladit komunikaci na optimální výkon.
- `[KE ]`qos — quality-of-service, další z atributů, který je svázán s ovladačem a který proto nemusí být vždy dostupný. Jeho význam plyne z názvu — ovladač má možnost poskytnout aplikaci informaci o platnosti, kvalitě aktuálních dat. Atribut je použitelný i opačně — aplikace může nastavením jeho hodnoty informovat ovladač, jak kvalitní data mu poskytuje. Control Web předdefinovává následující hodnoty kvality (v hranatých závorkách jsou uvedeny číselné hodnoty odpovídající jednotlivým kvalitám):

- qosLowest[0] — nejnižší kvalita
- qosLow[250] — snížená kvalita
- qosNormal[500] — normální kvalita
- qosHigh[750] — zvýšená kvalita
- qosHighest[1000] — vysoká kvalita
- qosUser[10000–65535] — uživatelsky (ovladačem) definované hodnoty kvality

- `[K ]`fix — nastavení hodnoty atributu na true zablokuje komunikaci (čtení i zápis) datového elementu. Jeho hodnotu je tak možné "zmrazit" a komunikaci vypnout. Zpětným zápisem hodnoty false se komunikace opět povolí a datový element bude normálně měřen a zapisován. Možnost zapnout a vypnout komunikaci kanálu například s výhodou použijete, pokud bude potřebovat za chodu aplikace vyměnit (nebo upravit) vadnou část technologie — snímač nebo celý automat. Zastavená komunikace nemůže vyvolávat žádné chyby a aplikace tak může pracovat bez chybového ovlivňování momentálně nepracující části techonologie. Veškeré komunikační kanály můžete v aplikaci nastavením atributu fix zablokovat, provést úpravy hardware, a potom opětovně kanály odblokovat. Aplikace po dobu blokování normálně poběží s naposledy změřenými (a zapsanými) hodnotami kanálů.
- `[K ]`value_set — systém nastavuje hodnotu atributu na true vždy, když dojde k zápisu hodnoty do datového elementu, přičemž je lhostejno, jestli hodnota byla nebo nebyla změněna. Atribut slouží jako pomocná informace o zápisech do elementu, přičemž jeho využití a řízení (nastavování na hodnotu false) je plně v moci aplikace.

## Výrazy

S daty uchovanými v datových elementech je nutné pracovat. Jakýkoli výpočet, konstrukce řetězce s příkazem nebo vyhodnocení několika vzájemně se ovlivňujících stavů vždy představují nějakou operaci nad vstupními datovými elementy, přičemž výsledek této operace je obyčejně uchováván pro další použití.

Výraz slouží k vyřešení všech nastíněných úloh. Výrazy se v aplikaci vyskytují na nejrůznějších místech, především na vstupech přístrojů, v podmínkách nebo v procedurách v přiřazovacím příkazu a při předávání parametrů do jiných procedur. Výraz obecně reprezentuje pouze výpočet, takže například v příkazu přiřazení je výrazem jen jeho pravá část — část za rovnítkem.

Prvky výrazu mohou být datové elementy, operátory a funkce. Výraz není v principu nijak omezen typy použitých datových elementů — jeden výraz může obsahovat současně řetězcové i číselné elementy. Nicméně, každý operátor i funkce přesně určují, s jakými typy elementů pracují, a těmto podmínkám samozřejmě musí výraz plně odpovídat. Můžete proto vytvořit následující správný výraz:

`length( Command ) + 1 = 50`

přičemž Command je řetězec, 1 a 50 jsou čísla a výsledkem operátoru = (a tedy i celého výrazu) je logická hodnota. Výraz je možné vytvořit, neboť:

- funkce length předepisuje ve svém parametru řetězec a má číselný výstup
- operátor = vyžaduje vlevo i vpravo čísla a jeho výsledkem je logická hodnota

Naopak chybný by byl výraz:

`Command + 1 = 'ahoj' (* toto je chybný výraz *)`

neboť operátor + vyžaduje na své levé straně číslo (není splněno) a operátor = na své pravé straně také vyžaduje číslo (opět není splněno).

Control Web podporuje následující operátory

- logické — operandy (výrazy po levé či pravé straně operátoru, s jejichž výsledky operátor pracuje) jsou logické, výsledek je logický

- and — logický součin, výsledek je true, jen mají-li oba operandy hodnotu true
- or — logický součet, výsledek je true, má-li nejméně jeden operand hodnotu true
- xor — výhradní logický součet, výsledek je true, mají-li operandy navzájem různou hodnotu
- not — negace, výsledkem je opačná hodnota operandu. Například výraz not( ... xor ... ) nabývá hodnoty true v případě, kdy mají oba operandy operátoru xor stejnou hodnotu.

- aritmetické — operandy jsou číselné, výsledek je číselný

- + — součet
- - — rozdíl
- * — součin
- / — podíl

- relační — operandy jsou číselné, výsledek je logický

- < — je menší
- <= — je menší nebo rovno
- > — je větší
- >= — je větší nebo rovno
- <> — nerovná se
- = — rovná se

a následující funkce (zápis funkcí je uveden včetně typů parametrů):

- aritmetické

- abs( x : real ): real — vrací absolutní hodnotu čísla x.
- sqrt( x : real ): real — vrací druhou odmocninu čísla x. Argument musí být nezáporný.
- trunc( x : real ): real — funkce odřezává desetinnou část čísla x, vrací tak jeho celočíselnou část.
- cos ( x : real ): real, acos( x : real ): real,
  sin ( x : real ): real, asin( x : real ): real,
  tan ( x : real ): real, atan( x : real ): real — goniometrické a cyklometrické funkce. Argumenty goniometrických funkcí jsou v radiánech, jejich výsledky v rozmezí -1..1 (jakákoli hodnota u funkce tangens); argumenty cyklometrických funkcí musí být v rozmezí -1..1 (libovolné u arcustangens) a jejich výsledky v rozmezí -¶/2..¶/2.
- atan2( x, y : real ): real — obdoba funkce atan( y/x ), výsledek je však podle znamének argumentů korektně umístěn v intervalu 0..2¶.
- cosh( x : real ): real, sinh( x : real ): real,
  tanh( x : real ): real — hyperbolické funkce
- exp( power : real ): real, pow( z, power : real ): real — mocninné funkce se základem e (Eulerovo číslo) (funkce exp) a se základem z (funkce pow).
- ln( x : real ): real, log( x : real ): real — logaritmické funkce se základem e (Eulerovo číslo) (ln) a 10 (log). Argumenty funkcí musí být kladné.
- min2( x, y : real ): real, max2( x, y : real ): real — funkce vracejí menší nebo větší ze dvou čísel x a y.

- bitové

- bitand( set1, set2 : real ): real — vrací logický součin čísel (množin bitů) set1 a set2.
- bitclr( set, x : real ): real — nastavuje bit x čísla (množiny bitů) set na 0.
- bitget( set, x : real ): real — testuje bit x čísla (množiny bitů) set. Je-li bit nastaven, vrací funkce hodnotu 1, jinak hodnotu 0.
- bitnot( set : real ): real — neguje bity čísla set.
- bitor( set1, set2 : real ): real — vrací logický součet čísel (množin bitů) set1 a set2.
- bitset( set, x : real ): real — nastavuje bit x čísla (množiny bitů) set na 1.
- bitshl( set, x : real ): real — posouvá bity čísla (množiny bitů) set o x bitů doleva. Uvolněné bity zprava plní 0.
- bitshr( set, x : real ): real — posouvá bity čísla (množiny bitů) set o x bitů doprava. Uvolněné bity zleva plní 0.
- bitxor( set1, set2 : real ): real — vrací logický výhradní součet čísel (množin bitů) set1 a set2.

- řetězcové

- caps( s : string ): string — funkce nahradí malá písmena v řetězci s velkými.
- concat( s1, s2 : string ): string — funkce připojí k řetězci s1 řetězec s2.
- delete( s : string; pos, len : real ): string — funkce odstraní z řetězce s len znaků počínaje znakem na pozici pos.
- insert( s1, s2 : string, pos : number ): string — funkce vloží řetězec s2 do řetězce s1 před znak na pozici pos.
- item( s1, s2 : string, n : number ): string — funkce vrací n-tý podřetězec z retězce s1, přičemž jako oddělovače podřetězců používá všechny znaky řetězce s2.
- length( s : string ): real — funkce vrací délku řetězce s (počet jeho znaků).
- lows( s : string ): string — funkce nahradí velká písmena v řetězci s malými.
- pos( s1, s2 : string ): real — vrací pozici prvního výskytu řetězce s2 v řetězci s1 (počítáno od 0). Pokud není s2 není s1 obsažen, vrací funkce -1.
- slice( s : string; pos, len : real ): string — funkce vrací podřetězec z retězce s o délce len počínaje znakem na pozici pos.

- převodní

- char( r : real ): string — funkce vytvoří řetězec obsahující jediný znak s ordinálním číslem r.
- ord( s : string ): real — funkce vrátí ordinální číslo prvního znaku řetězce s.
- str( x, base : real ): string — funkce vytvoří řetězec obsahující textový zápis čísla x v číslné soustavě s bází base (například base = 10 znamená desítkovou soustavu).
- val( s : string; base : real ): real — funkce převede textový zápis s čísla v soustavě base do číselné podoby.

Následující odstavec popisuje souhrnně výrazy systému Control Web pomocí gramatiky. Gramatika je zapsána jako sled přepisovacích pravidel, přičemž velkými písmeny jsou zapsány neterminální symboly EXPR, malými terminální symboly number, pomocí závorek [] je zapsán opakovaný výskyt 0..n-krát, pomocí závorek {} je zapsán opakovaný výskyt 1..n-krát a symbol | odděluje možné varianty:

      EXPR         -> SIMPLEEXPR [ RELOP SIMPLEEXPR ]
      RELOP        -> '=' | '#' | '<' | '>' | '<=' | '>=' | '<>'
      SIMPLEEXPR   -> TERM { ADDOP TERM }
      ADDOP        -> '+' | '-' | 'or' | 'xor'
      TERM         -> FACTOR { MULOP FACTOR }
      MULOP        -> '*' | '/' | 'and'
      FACTOR       -> '(' EXPR ')' | 'not' FACTOR | [ SIGNOP ] FACTOR |
                      REALFUNCTION '(' SIMPLEEXPR ')' |
                      REALFUNCTION2 '(' SIMPLEEXPR ',' SIMPLEEXPR ')' |
                      REALFUNCTION3 '(' FACTOR ',' SIMPLEEXPR ')' |
                      STRFUNCTION '(' FACTOR ')' |
                      STRFUNCTION2 '(' FACTOR ',' FACTOR ')' |
                      STRFUNCTION3 '(' FACTOR ',' FACTOR ',' SIMPLEEXPR ')' |
                      STRFUNCTION4 '(' FACTOR ',' SIMPLEEXPR ',' SIMPLEEXPR ')' |
                      STRFUNCTION5 '(' SIMPLEEXPR ',' SIMPLEEXPR ')' |
                      VALUE |
                      arrayelement '[' SIMPLEEXPR ']' |
                      channelarray '[' SIMPLEEXPR ']'
     SIGNOP        -> '+' | '-'
     VALUE         -> number | constant | variable | channel |
                      modulename '.' external
     REALFUNCTION  -> 'sqrt' | 'sin'  | 'cos'  | 'tan'   |
                      'asin' | 'acos' | 'atan' | 'sinh'  |
                      'cosh' | 'tanh' | 'log'  | 'ln'    |
                      'exp'  | 'abs'  | 'sgn'  | 'trunc' |
                      'bitnot'
     REALFUNCTION2 -> 'pow'    | 'atan2'  | 'min2'   | 'max2' |
                      'bitset' | 'bitclr' | 'bitget' |
                      'bitand' | 'bitor'  | 'bitxor' |
                      'bitshr' | 'bitshl'
     REALFUNCTION3 -> 'val'
     STRFUNCTION   -> 'length' | 'caps'   | 'lows'
     STRFUNCTION2  -> 'pos'    | 'concat'
     STRFUNCTION3  -> 'insert' | 'item'
     STRFUNCTION4  -> 'slice'  | 'delete'
     STRFUNCTION5  -> 'str'

## Shrnutí

- Systém Control Web používá pro uchovávání dat datové elementy — konstanty, proměnné a kanály.
- Každý datový element musí mít svůj datový typ, musí být předem známo, jaká data obsahuje. Control Web rozeznává datový typ logický, číselné typy, řetězcový typ a typ buffer.
- Pro zápis aplikace a úschovu vnitřních stavů aplikace slouží konstanty — elementy s pevnou hodnotou a proměnné — univerzálně použitelné elementy s libovolně upravitelnou hodnotou.
- Pro přenos reálných dat z techologie a do technologie slouží kanály. Každý kanál patří k nějakému ovladači; hlavní vlastností kanálů je nutnost jeho data komunikovat.
- Data z jiných (místních i vzdálených) modulů jsou dostupná jako externí datové elementy.
- Control Web poskytuje u kanálů a externích elementů rozličné rozšiřující informace, nazývané atributy. Atributy nesou především údaje o komunikaci elementu.
- Základní prostředek práce s daty v systému Control Web je obecný výraz. Výraz může obsahovat datové elementy, funkce a operátory.