# Il Costruttore script

Le applicazioni KDE possono essere controllate esternamente da un altro programma, da un prompt di terminale o da uno script di shell, grazie al Protocollo di Comunicazione Desktop (Desktop COmmunication Protocol, DCOP). KStars sfrutta questa possibilità per permettere in ogni momento la registrazione e riproduzione di complesse sequenze di eventi. Ciò può essere utile, ad esempio, per creare una dimostrazione didattica che illustri un concetto astronomico.

Il problema con gli script DCOP è che scriverli è un po' come programmare, impresa che può apparire proibitiva a chi non ha esperienza in materia. Il Costruttore script fornisce un'interfaccia grafica (GUI) punta-e-clicca per realizzare gli script DCOP di KStars, rendendo molto facile crearne anche di complessi.

## Introduzione al Costruttore script

Prima di spiegare come si usa il Costruttore script, introdurremo brevemente tutti i componenti dell'interfaccia grafica; per maggiori informazioni, utilizza la funzione "Che cos'è questo?".

Il Costruttore Script Costruttore script

Il Costruttore script è mostrato nell'immagine qui sopra. A sinistra c'è il riquadro Script corrente che mostra la lista di comandi inclusi nello script corrente. Il riquadro a destra è il Browser funzioni, con la lista di tutte le funzioni disponibili. Sotto il Browser funzioni c'è un pannello dove compare una breve documentazione sulla funzione evidenziata nel riquadro sovrastante. Sotto il riquadro Script corrente c'è il pannello Argomenti funzione; quando si seleziona una funzione nel riquadro Script corrente, in questo pannello appare il necessario per specificare il valore degli argomenti eventualmente richiesti.

In cima alla finestra c'è una fila di pulsanti che operano sullo script nel suo insieme. Da sinistra a destra: Nuovo script, Apri script, Salva script, Salva script con nome... e Prova script. La funzione di questi pulsanti dovrebbe essere ovvia, fatta forse eccezione per l'ultimo. Premendo Prova script lo script corrente sarà eseguito nella finestra principale di KStars. Prima di farlo ti consigliamo di spostare la finestra del Costruttore script, in modo che tu possa vedere i risultati.

Al centro della finestra c'è una fila verticale di pulsanti che operano su singole funzioni dello script. Dall'alto in basso: Aggiungi funzione, Elimina funzione, Copia funzione, Sposta in alto e Sposta in basso. Il pulsante Aggiungi funzione aggiunge la funzione selezionata nel Browser all'interno del riquadro Script corrente (puoi anche aggiungere una funzione con un doppio clic su di essa). Gli altri pulsanti operano sulla funzione selezionata nel riquadro Script corrente, con l'effetto di eliminarla, duplicarla o modificarne la posizione all'interno dello script.

## Utilizzo del Costruttore script

Per illustrare l'utilizzo del Costruttore script presenteremo un piccolo esempio. Scriveremo uno script che insegue la Luna mentre il tempo scorre a velocità accelerata.

Se vogliamo inseguire la Luna dobbiamo per prima cosa puntarla. La funzione lookToward ha precisamente questo scopo. Selezionala nel Browser funzioni e consulta la documentazione visualizzata nel pannello sottostante. Quindi premi il pulsante Aggiungi funzione per aggiungere la funzione nel riquadro Script corrente. Il pannello Argomenti funzione conterrà ora una casella chiamata Dir, che sta per "Direzione". Si tratta della direzione verso cui si vuol puntare il display. La lista contiene solo i punti cardinali, non la Luna o altri oggetti. Puoi inserire Luna manualmente o utilizzare la finestra Trova oggetto per selezionarla dalla lista di oggetti con nome. Nota che, come sempre, centrare un oggetto attiva automaticamente l'inseguimento, così che non c'è bisogno di aggiungere la funzione setTracking dopo lookToward.

Ora che abbiamo puntato la Luna vogliamo che il tempo scorra a una velocità superiore al normale. Utilizza allo scopo la funzione setClockScale. Aggiungila allo script facendo doppio clic su di essa nel Browser funzioni. Il pannello Argomenti funzione contiene ora il necessario per modificare il passo dell'orologio della simulazione. Porta il passo a tre ore.

Bene, abbiamo puntato la Luna e accelerato lo scorrere del tempo. Ora vogliamo solo che lo script attenda un certo numero di secondi mentre il display insegue la Luna. Aggiungi allo script la funzione waitFor, e utilizza il pannello Argomenti funzione per impostare a venti secondi il tempo di attesa.

Per finire, riportiamo il passo dell'orologio al valore normale di un secondo. Aggiungi un'altra istanza di setClockScale, e impostane il valore a un secondo.

Per la verità non abbiamo finito del tutto. Dovremmo assicurarci che il programma stia utilizzando le coordinate equatoriali prima che lo script inizi a inseguire la Luna con passo temporale accelerato. Altrimenti, se il display utilizza coordinate orizzontali, ruoterà assai rapidamente di grandi angoli mentre la Luna sorge e tramonta. Ciò può provocare parecchia confusione, ma lo si può evitare impostando l'opzione di visualizzazione UseAltAz a false. Per modificare una qualsiasi opzione di visualizzazione, utilizza la funzione changeViewOption. Aggiungila allo script ed esamina il pannello Argomenti funzione. C'è un pulsante che apre una lista di tutte le opzioni modificabili tramite changeViewOption. Dato che sappiamo di dover utilizzare l'opzione UseAltAz, potremmo semplicemente selezionarla dalla lista. Si tratta tuttavia di una lista piuttosto lunga, e non ci sono spiegazioni per le varie voci. Potrebbe quindi essere più semplice premere il pulsante Esamina albero, che aprirà una finestra con una vista ad albero delle opzioni di visualizzazione, divise per argomento. Inoltre ogni voce dispone di una breve spiegazione, ed è indicato il tipo di dati dell'argomento. Possiamo trovare UseAltAz nella categoria Opzioni mappa celeste. Selezionala e premi OK, ed essa comparirà all'interno del pannello Argomenti funzione. Infine, imposta il suo valore a false o 0.

Un'altra cosa: cambiare UseAltAz alla fine dello script non serve a granché; dobbiamo modificarlo prima di ogni altra cosa. Perciò assicurati che la funzione sia selezionata nel riquadro Script corrente, e premi il pulsante Sposta in alto fino a farla diventare la prima funzione.

Ora che abbiamo terminato lo script dobbiamo salvarlo su disco. Premi il pulsante Salva script. Si aprirà una finestra in cui puoi inserire un nome per lo script e uno per il suo autore. Inserisci Inseguire la Luna come nome, metti il tuo nome come autore e premi OK. Apparirà la finestra di dialogo standard "Salva file" di &kde;. Specifica un nome file per lo script e premi OK per salvarlo. Nota che, se il nome file non finisce per .kstars, l'estensione sarà aggiunta automaticamente. Se sei curioso, puoi esaminare lo script con un qualunque editor di testi.

Ora che abbiamo uno script completo possiamo eseguirlo in due modi diversi. È possibile eseguirlo da un prompt di terminale, purché KStars sia in esecuzione. In alternativa, puoi eseguire lo script da KStars tramite la voce Esegui script... nel menu File.

## Automazione delle periferiche con INDI

La programmazione e l'automazione sono supportate per tutte le periferiche compatibili con INDI. Puoi coordinare un numero qualsiasi di periferiche per eseguire operazioni complesse tramite il Costruttore script di &kstars;. Tutto ciò è possibile grazie all'interfaccia DCOP INDI di &kstars;, che fornisce diverse classi di funzioni per soddisfare i tuoi bisogni. Le funzioni DCOP INDI si possono dividere in quattro classi. Segue un elenco delle funzioni e dei loro argomenti come supportati in KStars. Raccomandiamo viviamente di leggere la sezione Concetti di INDI, dato che utilizzeremo nel seguito quanto vi è spiegato.

1. Funzioni generiche di periferica: hanno lo scopo di accendere/spegnere periferiche, e così via...

   - `startINDI (QString nomePeriferica, bool usaLocale)`: avvia un servizio INDI in modalità locale o server.

   - `shutdownINDI (QString nomePeriferica)`: arresta un servizio INDI.

   - `switchINDI(QString nomePeriferica, bool accesoSpento)`: connette o disconnette una periferica INDI.

   - `setINDIPort(QString nomePeriferica, QString porta)`: imposta la porta di connessione della periferica.

   - `setINDIAction(QString nomePeriferica, QString azione)`: attiva un'azione INDI. L'azione può essere un elemento qualsiasi di una proprietà interruttore.

   - `waitForINDIAction(QString nomePeriferica, QString azione)`: arresta l'esecuzione dello script fino a quando la proprietà dell'azione specificata restituisce uno stato OK.

2. Funzioni telescopio: servono a controllare il movimento e lo stato del telescopio.

   - `setINDIScopeAction(QString nomePeriferica, QString azione)`: imposta la modalità o l'azione del telescopio. Le opzioni disponibili sono SLEW, TRACK, SYNC, PARK e ABORT.

   - `setINDITargetCoord(QString nomePeriferica, double AR, double DEC)`: imposta le coordinate JNow del telescopio ai valori AR e DEC specificati.

   - `setINDITargetName(QString nomePeriferica, QString nomeOggetto)`: imposta le coordinate JNow del telescopio a quelle di nomeOggetto. KStars cercherà l'oggetto nel proprio database e ne utilizzerà le coordinate.

   - `setINDIGeoLocation(QString nomePeriferica, double longitudine, double latitudine)`: imposta la località geografica del telescopio alla latitudine e longitudine specificate. La longitudine è calcolata E di N. Per esempio, le coordinate di Calgary, Canada, in KStars sono longitudine -114 04 58 e latitudine 51 02 58. Soltanto le longitudini negative vanno convertite. Allo scopo consideriamo la longitudine positiva e aggiungiamo 180 gradi. Perciò nel nostro esempio la longitudine INDI diventa 114 04 08 + 180 00 00 = 294 04 08

   - `setINDIUTC(QString nomePeriferica, QString dataOraUTC)`: imposta la data e l'ora UTC del telescopio in formato ISO 8601. Il formato è AAAA-MM-GGTHH:MM:SS (per esempio 2004-07-12T22:05:32).

3. Funzioni focheggiatore: servono a controllare il movimento e lo stato del focheggiatore.

   - `setINDIFocusSpeed(QString nomePeriferica, QString azione)`: imposta la velocità del focheggiatore. Le opzioni disponibili sono FOCUS_HALT, FOCUS_SLOW, FOCUS_MEDIUM e FOCUS_FAST.

   - `setINDIFocusTimeout(QString nomePeriferica, int durata)`: imposta la durata in secondi di ogni operazione startINDIFocus successiva.

   - `startINDIFocus(QString nomePeriferica, int dirFuoco)`: sposta il focheggiatore verso l'interno (dirFuoco = 0) o l'esterno (dirFuoco = 1). La velocità e durata di questa operazione sono impostate tramite le funzioni `setINDIFocusSpeed()` e `setINDIFocusTimeout()`.

4. Funzioni videocamera/CCD: permettono di controllare le proprietà e lo stato della videocamera o del CCD.

   - `setINDICCDTemp(QString nomePeriferica, int temp)`: imposta la temperatura del chip CCD in gradi Celsius.

   - `setINDIFrameType(QString nomePeriferica, QString tipo)`: imposta il tipo di frame del CCD. Le opzioni disponibili sono FRAME_LIGHT, FRAME_BIAS, FRAME_DARK e FRAME_FLAT.

   - `startINDIExposure(QString nomePeriferica, int durata)`: avvia l'esposizione del CCD/videocamera per la durata specificata dal parametro omonimo, in secondi.

Nota che il nome della periferica è il primo argomento di tutte le funzioni INDI. Ciò permette di affiancare nello stesso script più comandi indirizzati a periferiche differenti. Il Costruttore script fornisce due opzioni per facilitare la creazione e la modifica di script INDI:

- `Aggiungi WaitForINDIAction dopo ogni azione INDI`: quando questa casella è marcata, il costruttore script aggiungerà automaticamente `waitForINDIAction()` dopo ogni azione che riconosce. Per esempio, se aggiungi la funzione `switchINDI()` e marchi la casella di cui sopra, il costruttore script aggiungerà "waitForINDIAction CONNECTION" nello script subito dopo `switchINDI()`. Ciò avrà l'effetto di arrestare l'esecuzione dello script dopo `switchINDI()`, fino a quando questa funzione non restituirà uno stato OK (il che significa che la connessione ha avuto successo). È molto importante sapere che il costruttore script non può aggiungere automaticamente `waitForINDIAction()` dopo azioni generiche aggiunte tramite la funzione `setINDIAction()`. La ragione è che KStars non può determinare la proprietà genitrice di azioni generiche. Perciò è necessario che tu aggiunga manualmente `waitForINDIAction()` dopo azioni generiche, quando lo desideri.

- `Riutilizza nome periferica INDI`: se marcato, il nome di periferica di tutte le funzioni seguenti è automaticamente impostato all'ultimo nome utilizzato. L'impostazione ha luogo ogni volta che la funzione `startINDI()` viene aggiunta allo script corrente. Si raccomanda di non utilizzare questa opzione lavorando con periferiche multiple.

Ora siamo pronti per creare uno script dimostratio che controlli un telescopio LX200 GPS e una camera CCD Finger Lakes. Il nostro obiettivo è semplice: chiederemo al telescopio di puntare e inseguire Marte, e al CCD di effettuare tre esposizioni di dieci secondi, distanziate di venti secondi l'una dall'altra.

Dato che l'interfaccia DCOP di INDI non dà alcuna informazione sull'avanzamento, valore o stato di operazioni e parametri relativi alle periferiche (fatta eccezione per `waitForINDIAction()`), l'automazione delle periferiche in KStars somiglia a un sistema di controllo a ciclo aperto. In tale sistema non c'è modo di conoscere lo stato di avanzamento del sistema e di correggere gli errori. Di conseguenza, occorre progettare gli script di automazione con molta accortezza. Tutti questi script devono essere sottoposti a una rigorosa fase di test prima di essere impiegati.

Il Costruttore Script Costruttore script

Lo script dimostrativo è mostrato nell'immagine qui sopra. Nota che abbiamo marcato `"Aggiungi WaitForINDIAction dopo ogni azione INDI"` e smarcato `"Riutilizza nome periferica INDI"`. La prima funzione da aggiungere è `startINDI()`, come mostrato sopra. Vogliamo gestire le nostre periferiche come locali, quindi non cambieremo la modalità mostrata nella finestra degli argomenti. Digitiamo il nome della periferica, cominciando dal telescopio "LX200 GPS". Ripetiamo la stessa operazione per "FLI CCD". La funzione successiva è `waitFor()`. In generale si raccomanda di utilizzare `waitFor()` subito dopo `startINDI()` in modo da mettere lo script in pausa per 1-5 secondi. Ciò assicura che tutte le proprietà siano stabilite e pronte a ricevere comandi. È anche utile per controllare periferiche remote, dato che prelevare e stabilire le varie proprietà può richiedere un po' di tempo. Con la funzione successiva, `switchINDI()`, ci connettiamo a ciascuna periferica.

Dato che la casella relativa all'opzione `"Aggiungi WaitForINDIAction dopo ogni azione INDI"` è marcata, non dobbiamo aggiungere `waitForINDIAction()` dopo `switchINDI()` per assicurarci che l'esecuzione dello script continui solo dopo che la connessione è avvenuta con successo. Ci penserà automaticamente il costruttore script quando salveremo il programma. Ora impostiamo la modalità del telescopio a inseguimento: fai clic sulla funzione `setINDIScopeAction()` e seleziona TRACK. Nota che questo va fatto prima di fornire le coordinate per l'inseguimento. La funzione `setINDIScopeAction()` è fornita per comodità, dato che in questo esempio si limita a chiamare `setINDIAction()` con l'argomento TRACK. Comunque il vantaggio di utilizzare `setINDIScopeAction()` è che KStars può aggiungere automaticamente `waitForINDIAction()` quando richiesto. Questa possibilità non è disponibile per azioni generiche, come spiegato più sopra.

Il prossimo passo consiste nell'utilizzare la funzione `setINDITargetName()` e impostare il nome a Marte. I passi finali saranno catturare un'immagine con dieci secondi d'esposizione, tramite la funzione `startINDIExposure()`, e aspettare venti secondi, fornendo il valore 20 alla funzione `waitFor()`.

Possiamo ora salvare il nostro script ed eseguirlo in un altro momento. LO script salvato sarà simile a questo:

>     #!/bin/bash
>         #Script DCOP per KStars: script dimostrativo
>         #di Jasem Mutlaq
>         #ultima modifica: Gio 6 Gen 2005 09:58:26
>         #
>         KSTARS=`dcopfind -a 'kstars*'`
>         MAIN=KStarsInterface
>         CLOCK=clock#1
>         dcop $KSTARS $MAIN  startINDI "LX200 GPS" true
>         dcop $KSTARS $MAIN  startINDI "FLI CCD" true
>         dcop $KSTARS $MAIN  waitFor 3
>         dcop $KSTARS $MAIN  switchINDI "LX200 GPS" true
>         dcop $KSTARS $MAIN  waitForINDIAction "LX200 GPS" CONNECTION
>         dcop $KSTARS $MAIN  switchINDI "FLI CCD" true
>         dcop $KSTARS $MAIN  waitForINDIAction "FLI CCD" CONNECTION
>         dcop $KSTARS $MAIN  setINDIScopeAction "LX200 GPS" TRACK
>         dcop $KSTARS $MAIN  waitForINDIAction "LX200 GPS" ON_COORD_SET
>         dcop $KSTARS $MAIN  setINDITargetName "LX200 GPS" Mars
>         dcop $KSTARS $MAIN  waitForINDIAction "LX200 GPS" EQUATORIAL_EOD_COORD
>         dcop $KSTARS $MAIN  startINDIExposure "FLI CCD" 10
>         dcop $KSTARS $MAIN  waitForINDIAction "FLI CCD" EXPOSE_DURATION
>         dcop $KSTARS $MAIN  waitFor 20
>         dcop $KSTARS $MAIN  startINDIExposure "FLI CCD" 10
>         dcop $KSTARS $MAIN  waitForINDIAction "FLI CCD" EXPOSE_DURATION
>         dcop $KSTARS $MAIN  waitFor 20
>         dcop $KSTARS $MAIN  startINDIExposure "FLI CCD" 10
>         dcop $KSTARS $MAIN  waitForINDIAction "FLI CCD" EXPOSE_DURATION