This is UltimateRPA Documentation
Obrazové informace

Některé aplikace nepodporují vrstvu, která se nám zobrazí v Inspectoru a pomocí které GUI elementy identifikujeme. V těchto případech pracujeme s elementy GUI jako s obrázky. Při vývoji robotizace si vytvoříme obrázky, které pak při běhu robotizace porovnáváme s aktuálním stavem aplikace.

Tento postup si vyzkoušíme na aplikaci RpaTableTest. Nejdříve si připravíme kód pro spuštění aplikace.

import urpa
def main():
app = urpa.exec_app("TutorialApps/RpaTableTest.exe")
app.set_auto_close(False)

Cesta k aplikaci "TutorialApps/RpaTableTest.exe" je relativní od umístění spouštěného skriptu a předpokládá, že skript je uložený v hlavní složce s nástroji UltimateRPA. Pokud je váš skript uložený jinde, nezapomeňte cestu upravit.

RpaTableTest.png
Obrázek 1 Okno aplikace RpaTableTest

Vytvoření obrázku

Metoda visual_data ze třídy AppElement vytvoří obrázek GUI elementu na který je zavolána. My si v našem příkladu uložíme do souboru simply.png obrázek Simply with UltimateRPA z aplikace RpaTableTest. V Inspectoru připravíme výraz app.find_first(cf.image()) který přiřadíme do proměnné image. Na proměnou image pak zavoláme metodu visual_data, které nastavíme argument format na hodnotu png. Pozor, ne všechny metody nástroje UltimateRPA podporují klíčové argumenty (keyword arguments), metoda visual_data, ale tento způsob volání dokáže, tak toho využijeme. Výstup z metody visual_data uložíme v binárním módu do souboru s názvem simply.png.

import urpa
def main():
app = urpa.exec_app("TutorialApps/RpaTableTest.exe")
app.set_auto_close(False)
image = app.find_first(cf.image())
visual_data = image.visual_data(format="png")
with open("simply.png", "wb") as png_file:
png_file.write(visual_data)
Visual_simply_with_URPA.png
Obrázek 2 Obrázek uložený robotem

Pokud se po spuštění skriptu podíváme do adresáře, kde máme skript uložený, najdeme tam obrázek s názvem simply.png.

Metoda visual_data má ještě jeden nepovinný argument s názvem rect. Ten očekává tuple obsahující čtyři hodnoty integer, kterými lze definovat výřez obrázku jako souřadnice od levého vrchního rohu GUI elementu, na který metodu voláme, v pořadí levý, vrchní roh a pravý, spodní roh. Například to může vypadat takto: gui_element.visual_data(rect=(0, 0, 10, 10)). Není nutné aby výřez byl jen z vybraného GUI elementu, ale může ho přesahovat nebo dokonce být úplně mimo něj.

Vyhledání obrázku v aplikaci

K tomu abychom obrázek v aplikaci našli, použijeme metodu find_first_visual. My použijeme obrázek simply.png, který jsme vytvořili v předchozím příkladu. Nejprve aktivujeme režim debuggování funkci set_debug_mode. Potom s pomocí nástroje Inspector vytvoříme výraz pro nalezení celého okna aplikace a ten přiřadíme do proměnné window. Nakonec na window zavoláme metodu find_first_visual s jedním argumentem a to cestou na obrázek simply.png.

import urpa
def main():
app = urpa.exec_app("TutorialApps/RpaTableTest.exe")
app.set_auto_close(False)
window = app.find_first(cf.window().name("RpaTableTest"))
window.find_first_visual("simply.png")
Visual_rainbow1.gif
Obrázek 3 Různé barvy debuggovacího rámečku

Spustíme robotizační skript a spustí se aplikace RpaTableTest. Protože máme aktivní debuggovací režim, zobrazí se zelený rámeček znázorňující nalezené okno aplikace. Následně se změní rámeček na červený, čímž se označuje oblast, ve které se obrázek bude hledat (region). V případě, že tento argument neuvedeme, vyhledávání se provede v celém GUI elementu na který metodu find_first_visual zavoláme. V našem případě tedy obrázek hledáme v celém okně aplikace. Nakonec se nalezený obrázek Simply with UltimateRPA zvýrazní oranžovým rámečkem.

Pojďme si teď ukázat variantu, kdy definujeme oblast pro vyhledávaní pomocí argumentu region. Opět můžeme použít keyword argument na definovaní oblasti, kde chceme hledat. Funguje to stejně jako v případě výřezu u metody visual_data.

import urpa
def main():
app = urpa.exec_app("TutorialApps/RpaTableTest.exe")
app.set_auto_close(False)
window = app.find_first(cf.window().name("RpaTableTest"))
window.find_first_visual("simply.png", region=(400, 20, 600, 200))
Visual_rainbow2.gif
Obrázek 4 Hledání ve specifikované oblasti

Pokud takto upravený kód spustíme, uvidíme, že červený rámeček je menší než v předchozím případě.

V případě že bychom region definovali tak, že v něm hledaný obrázek nebude možné najít, skončí skript chybou ElemenetNotFoundError. Viz další přiklad.

import urpa
def main():
app = urpa.exec_app("TutorialApps/RpaTableTest.exe")
app.set_auto_close(False)
window = app.find_first(cf.window().name("RpaTableTest"))
window.find_first_visual("simply.png", region=(10, 10, 300, 200))

Visual Element

Metoda find_first_visual nám vrátí objekt třídy VisualElement, se kterým můžeme provádět interakce stejně jako s objekty třídy AppElement. Ukážeme si to v následujícím přikladu opět na aplikaci RpaTableTest, kdy pomocí třídy VisualElement označíme všechny checkboxy. Nejdříve si vytvoříme obrázek checkboxu, který budeme hledat. Ten si tentokrát neuložíme do souboru, ale použijeme rovnou bitové pole (bytearray), které nám vrátí metoda visual_data. Není nutné checkbox vybrat přesně, hodnota (0, 0, 17, 17) je dostačující. Jako další krok si výraz pro nalezení tabulky app.find_first(cf.list()) přiřadíme do proměnné table. Na proměnou table pak místo metody find_first_visual zavoláme find_all_visual, která nám vrátí seznam objektu třídy VisualElement odpovídajícím obrázku uloženému v proměnné visual_data. Nakonec si seznam v cyklu projdeme a na každou položku zavoláme metodu send_mouse_click, která na checkbox klikne myší.

import urpa
def main():
app = urpa.exec_app("TutorialApps/RpaTableTest.exe")
app.set_auto_close(False)
row = app.find_first(cf.list_item().name("1"))
visual_data = row.visual_data((0, 0, 17, 17), format="png")
table = app.find_first(cf.list())
checkboxes = table.find_all_visual(visual_data)
for checkbox in checkboxes:
checkbox.send_mouse_click()
Visual_mark_checkbox.gif
Obrázek 5 Zaškrtnutí checkboxů

Vytvoření obrázku pomocí Inspectoru

Nástroj Inspector byl vytvořen tak, aby nám co nejvíce usnadnil práci v případě, kdy v robotizaci nedokážeme identifikovat elementy GUI jinak než pomocí obrázků. V následujících kapitolách si ukážeme tři příklady vytvoření obrázku s pomocí Inspectoru. Pro ukázku použijeme opět aplikaci RpaTableTest v adresáři TutorialApps, kterou si bez pomoci robota spustíme.

Vytvoření nového obrázku

Pro vytvoření nového obrázku pomocí Inspectoru nejprve aktivujeme tlačítko Capture Visuals vedle zaměřovacího kříže Inspectoru. Potom si pomocí zaměřovacího kříže Inspectoru vybereme v aplikaci RpaTableTest nápis ID v levém horním rohu tabulky aplikace RpaTableTest.

VisualCaptureVisual.png
Obrázek 6 Tlačítko Capture Visuals

Tento element GUI nám bude sloužit jako referenční bod pro vyhledání obrázku. Pomocí checkboxu ve sloupci CF si element GUI identifikujeme například takto app.find_first(cf.name("ID")) a přepneme se na záložku VisualElement, kde uvidíme screenshot aplikace RpaTableTest a zelený rámeček označující element GUI. Orámování prvků je možné skrýt pomocí nástroje Show/Hide highlight, který najdete v panelu nástrojů nalevo od plátna.

VisualShowHide.gif
Obrázek 7 Nástroj Show/Hide highlight

Nástrojem Select pattern vybereme první checkbox v tabulce a nástrojem Save pattern si pattern uložíme jako soubor checkbox.bmp. Pomocí kolečka myši a klávesy CTRL nebo slideru si můžete plátno přiblížit, aby se nám čtverec vybíral pohodlněji. Jak už bylo zmíněno výše, v případě, že metodě find_first_visual nepředáme parametr region, probíhá vyhledání v elementu GUI, na který metodu voláme. V našem případě by tedy vyhledání proběhlo v buňce tabulky s hodnotou ID, ve které se žádný checkbox nenachází a vyhledávání by tak skončilo výjimkou ElemenetNotFoundError.

VisualSelectSavePattern.png
Obrázek 8 Nástroje Select pattern a Save pattern

Proto si pomocí nástroje Select region definujeme oblast, ve které se pattern bude vyhledávat. Vybereme tedy přibližně první sloupec tabulky, který obsahuje checkboxy. Pro precizní výběr oblasti regionu upravíme hodnoty ve stavovém řádku, který je umístěn pod plátnem. Zde můžeme přesně nastavit hodnoty pixelů od levého vrchního rohu vybraného AppElementu a to v pořadí levý, horní, pravý, dolní.

InspectorStatusBar.png
Obrázek 9 Stavový řádek

Ve spodní časti aplikace Inspector označené Expression se nám vygeneruje výraz, který si můžeme zkopírovat do robotizačního skriptu. Důležité je nastavit správnou cestu k obrázku, aby ho robot dokázal najít. Cestu si můžeme upravit přímo v kódu nebo si cestu nastavíme v okně Expression settings, které otevřeme tlačítkem s ozubeným kolem, umístěným vpravo nad polem Expression. Ve výběrovém poli Type of action si vybereme, jakou metodu chceme zavolat na nalezený VisualElement. My vybereme metodu send_mouse_click. Že jsme vytvořili funkční výraz, si můžeme ověřit pomocí tlačítka Highlight expression, které nám v robotizované aplikaci ukáže, co výraz najde. Highlight expression neprovede přesně výraz, který jsme vygenerovali, ale slouží jen pro prvotní kontrolu, že jsme na správné cestě.

InspectorExpressionSettingsVisual.png
Obrázek 10 Dialog Expression settings

Vygenerovaný kód pro náš přiklad by měl vypadat přibližně takto. Nezapomeňte si nastavit cestu k obrázku checkbox.bmp na umístění, kde jste obrázek skutečně uložili.

element = app.find_first(cf.name("ID"))
element.find_first_visual("img/checkbox.bmp", (0, 25, 35, 230)).send_mouse_click()

Použití už vytvořeného patternu

V některých robotizacích nám nastane případ, že vyhledáváme stejný pattern na různých obrazovkách nebo dokonce v různých aplikacích. V takovém případě není nutné vybírat a ukládat pattern znovu, ale můžeme si nástrojem Load pattern obrázek nahrát. Opět si to vyzkoušíme na aplikaci RpaTableTest. Ze začátku postupujeme stejně jako při vytváření nového visuálu, ale místo nástroje Select Pattern zvolíme nástroj Load Pattern. V dialogu Otevřít si najdeme obrázek checkbox.bmp, který jsme si vytvořili v předchozím příkladu. Pokud se nahraný pattern na plátně najde, tak se označí. Inspector se pattern nejprve snaží vyhledat v regionu nebo v AppElementu, a pokud se mu to nepodaří, prohledá celý screenshot. Po nahrání patternu se nám vytvoří v poli Expression python výraz, který si můžeme zkopírovat do kódu nebo dále upravovat než dosáhneme požadovaného výsledku.

VisualLoadPattern.png
Obrázek 11 Nástroj Load pattern

Obrázek ze screenshotu aplikace

V případě, že v obsluhované aplikaci občas nastává stav, který nedokážeme při vývoji navodit, ale máme k dispozici screenshot aplikace s požadovaným stavem, například screenshot, který se ukládá při chybě zpracování robotizačního skriptu jako log, můžeme se pokusit vytvořit obrázek ze screenshotu. Tento postup doporučujeme používat jen v případě, že není k dispozici jiná možnost, protože takto vytvořený visuální test může být nepřesný.

VisualLoadScreen.png
Obrázek 12 Nástroj Load screenshot

Nástroj Inspector po spuštění přepneme na záložku VisualElement a na liště nástrojů aktivuje tlačítko Load Screenshot. V dialogu Otevřít si vybere screenshot, ze kterého chceme vytvořit obrázek.

Screenshot se nám otevře na plátně a my si definujeme AppElement nástrojem Select AppElement. Pokud máme vybraný AppElement pomocí nástroje Select AppElement můžeme ve stavovém řádku editovat hodnoty pro AppElement. Protože všechny ostatní souřadnice se počítají od levého vrchního rohu vybraného AppElementu, tak na tom, jak přesně zvolíme tento roh, bude zásadním způsobem záviset i přesnost visuálního testu. V případě použití nástroje Load Screenshot není možné využít nástroj Highlight expression.

VisualSelectAppElement.png
Obrázek 13 Nástroj Select AppElement

Transformace

Transformace v nástroji UltimateRPA slouží k barevnému převedení patternu a obrazovky. To nám například umožní mít jednu sadu patternu pro různé barevné bitové hloubky. Pattern si uložíme tak, jak ho skutečně vidíme na monitoru a o provedení transformací se postará parametr transformations metod find_first_visual nebo find_all_visual, který při volání funkce provede transformaci patternu tak i aktuální obrazovky. Pro jednoduší definovaní transformací můžete použít nástroj Inspector, kde na záložce VisualElement najdeme nástroj Transformation.

InspectorTransformation.png
Obrázek 14 Dialog Transformation

UltimateRPA umí tři základní barevné transformace

InspectorAllTransformations.png
Obrázek 15 Ukázka transformací

Změna barev

K převodu několika barev na jednu slouží metoda change_colors. Metoda očekává dva parametry from_colors a to_color. Parametr from_colors je seznam barev ve formátu RGB například from_colors = [(255, 0, 0)], které chceme změnit. Parametr to_color pak definuje, na jakou barvu chceme barvy ze seznamu převést, například to_color = (0, 0, 0).

VisualChangeColor.gif
Obrázek 16 Ukázka změny barvy

V Inspectoru v nastavení transformací si v combo boxu vybereme change_colors a tlačítkem plus jí přidáme do seznamu. Objeví se nám formulář pro nastavení. Do tabulky From colors můžeme přidat barvy kapátkem (kapátko sbírá barvy jen z plátna Inspectoru) nebo vyplněním textových polí s hodnotou barvy a stisknutím tlačítka plus. Seznam barev sám hlídá, aby se v něm nevyskytovaly duplicitní barvy. V případě, že chceme barvu ze seznamu odstranit, označíme jí a stiskneme klávesu Delete. V části označené To color vyplníme barvu, na kterou chceme barvy převést. Dvě nejčastější možnosti bílá a černá jsou pro Vás předdefinované ve formě tlačítek. Pokud si chceme ověřit, jak změna barev vypadá, můžeme se podívat na náhled po aktivování tlačítka oka, které je umístěné vedle tabulky transformací.

Inverze

K provedení inverze barev použijeme metodu colors_inversion.

VisualColorInversion.gif
Obrázek 17 Ukázka inverze

Inverze barev neumožnuje žádné další nastavení.

Práh

Pokud bychom chtěli obrázek převést jen na černou a bílou barvu (bitová mapa) použijeme metodu threshold. Metoda má jeden parametr, který udává, v jakém poměru se barvy rozdělí na černou a bílou.

VisualThreshold.gif
Obrázek 18 Ukázka prahu

Nastavení pro práh obsahuje jen textbox pro nastavení parametru poměru rozdělení barev. Parametr je desetinné číslo od nuly do jedné.

Transformation factory

Transformation factory funguje podobně jako condition factory. V transformation factory záleží na pořadí, v jakém jsou metody transformací zřetězeny za sebou. V tomto pořadí se provádí a je rozdíl pokud se nejprve provede metoda threshold, a pak se mění barva metodou change_colors. Metoda change_colors je jediná, u které dává smysl, aby byla v Transformation factory uvedena několikrát.

Ukázka, jak může vypadat kód pro transformace.

from_colors = [(255, 0, 0), (0, 255, 0), (0, 0, 255)]
to_color = (255, 255, 255)
transformation = tf.change_colors(from_colors, to_color).color_inversion().threshold(0.5)

Výše uvedená transformace nejprve převede červenou, zelenou a modrou barvu na barvu bílou. Poté provede inverzi barev a nakonec převede obrázek metodou threshold na bitovou mapu (pouze bílá a černá barva).