TapHome
Ufficiale · TapHome Illuminazione

Resi DALI

Controllo dell'illuminazione DALI a runtime per il gateway Modbus-DALI RESI-DALI-SIO e RESI-DALI-ETH. Dimmerazione per gear fino a 64 dispositivi di controllo (gears), 16 gruppi broadcast, e stato DALI 1.0 per gear, diagnostica guasti lampada/alimentazione e min/max level su Modbus RTU.

ResiModbus RTU80 dispositiviRevisione 1.3 Ultimo aggiornamento: 15 novembre 2026
Resi DALI

Importa nell'app TapHomeHardware › Modbus › Aggiungi da modello

Scarica template
In questa pagina

Richiede gateway esterno

Resi RESI-DALI-PS — pagina prodotto

Guida all'integrazione

Il template Resi DALI è la controparte runtime operativa dello strumento di messa in servizio Resi Dali - Configurazione. Connette TapHome a un bus di illuminazione DALI completamente indirizzato tramite il gateway Modbus-DALI RESI-DALI-SIO o RESI-DALI-ETH ed espone il controllo quotidiano per fino a 64 dispositivi di controllo DALI (gears) indirizzati individualmente (indirizzi brevi 0–63) e 16 gruppi broadcast DALI (0–15), oltre allo stato DALI per gear e alla diagnostica di guasto del gear e di guasto lampada.

La comunicazione con il gateway utilizza Modbus RTU a 9600 baud 8N1. Le scritture di luminosità vanno a H:510 LAMP LEVEL (per gear) e H:520 GROUP LEVEL (per gruppo); i comandi di configurazione e le query per gear sono incanalati tramite H:511 LAMP COMMAND / H:512 LAMP COMMAND + REPEAT, mentre il registro H:550 DALI STATUS del gateway viene polled per la prontezza della risposta.

Questo template presuppone che gli indirizzi brevi DALI siano già programmati sul bus. Se i gear non sono ancora indirizzati, utilizza prima il template Resi Dali - Configurazione (o lo strumento gratuito del produttore MODBUSConfigurator / DCA) per eseguire la procedura guidata di indirizzamento casuale DALI 2.0 — vedi Relazione con il template di configurazione qui sotto.

Connessione hardware

I RESI-DALI-SIO (RS-485) e RESI-DALI-ETH (Ethernet) sono gateway master per guida DIN che si collocano tra un host seriale/Ethernet e un bus di illuminazione DALI. Il SIO è fornito in custodia CEM17 (17,5 × 90 × 56,4 mm) e l’ETH in una custodia CEM35 più larga (35,8 × 90 × 56,4 mm) per ospitare il connettore RJ45. Nessuno dei gateway alimenta da solo il bus DALI — è obbligatorio un alimentatore bus DALI di accompagnamento (RESI-DALI-PS o qualsiasi PSU DALI conforme da 200 mA).

Connessione del RESI-DALI-SIO (RS-485)

Schema di collegamento RESI-DALI-SIO — PSU DALI esterno (in alto) e combinato con RESI-DALI-PS (in basso)

I morsetti sul lato sinistro del RESI-DALI-SIO (dall’alto → al basso): GND, +12..48V=, RS485 DATA+ (A+), RS485 DATA- (B-), RS485 GND, RS232 TX, RS232 RX, RS232 GND. I morsetti del bus DALI sul lato opposto sono D+ / N/C / D- (blocco USLIM a 3 pin, il pin centrale N/C rimane non collegato).

Per un’installazione TapHome utilizza l’interfaccia RS-485:

  • RS485 DATA+ (A+) → A+/D+ sul bus RS-485 di TapHome
  • RS485 DATA- (B-) → B-/D- sul bus RS-485 di TapHome
  • RS485 GND → GND sull’alimentatore TapHome (consigliato per una comunicazione stabile)
  • +12..48V= / GND → alimentazione primaria 12–48 V DC

Connessione del RESI-DALI-ETH (Ethernet)

Schema di collegamento RESI-DALI-ETH — PSU DALI esterno (in alto) e combinato con RESI-DALI-PS (in basso)

La variante Ethernet ha gli stessi morsetti del bus DALI (D+ / N/C / D-) e gli stessi ingressi di alimentazione primaria (GND, +12..48V=), oltre a un singolo connettore RJ45 per Ethernet 10/100 Mbit. Le impostazioni IP di fabbrica sono 192.168.0.191 / 255.255.255.0 / 192.168.0.1 con Modbus Unit ID 255; l’UI web integrata utilizza le credenziali RESI / RESI.

Poiché si tratta di un template Modbus RTU, TapHome non comunica con il RESI-DALI-ETH tramite Modbus/TCP nativo. Utilizzalo invece in modalità RTU-over-Ethernet trasparente, oppure posiziona il SIO dietro un bridge seriale-IP (Moxa NPort, USR-TCP232) — vedi Configurazione → Setup RTU-over-TCP qui sotto.

Alimentatore bus DALI (RESI-DALI-PS)

RESI-DALI-PS — alimentazione del bus DALI da solo (in alto) e combinato con un gateway SIO/ETH (in basso)

Il RESI-DALI-PS eroga fino a 200 mA sul bus DALI (corrente di cortocircuito ~225 mA, tensione del bus tipicamente 14–18 V) e supporta fino a 64 ballast DALI 1.0 o dispositivi di controllo DALI 2.0 su una singola linea. Il lato primario accetta la stessa alimentazione 12–48 V DC dell’unità SIO/ETH. Il gateway e il PSU si collegano alla stessa coppia D+ / D- — il PSU energizza il bus mentre il gateway legge e scrive frame DALI.

Tre LED sul PSU aiutano nella diagnosi dei guasti: POWER (primario 12–48 V OK, sempre acceso in funzionamento normale), DALI (lampeggia brevemente durante il traffico del bus DALI), ERR (acceso fisso in caso di guasto del PSU, cortocircuito DALI o sovraccarico del bus — deve essere spento in funzionamento normale).

Topologia del bus DALI

Una linea DALI impone alcuni vincoli rigidi che influenzano direttamente la stabilità a runtime:

Sezione del conduttoreLunghezza max cavo DALI
1,5 mm²300 m
1,0 mm²238 m
0,75 mm²174 m
0,5 mm²116 m

Il limite deriva dalla caduta di tensione massima consentita di 2 V sul cavo DALI. Altre regole:

  • Massimo 64 ballast DALI 1.0 e fino a 64 dispositivi di controllo DALI 2.0 per bus (spazi di indirizzo brevi separati).
  • Solo topologia ad albero — niente anelli, niente loop.
  • Il numero effettivo di gear dipende anche dalla corrente nominale del PSU (tipicamente 200 mA sul RESI-DALI-PS; calcola ~2 mA per gear più riserva).

Il RESI-DALI-PS (o un PSU DALI equivalente) è obbligatorio. Senza di esso il gateway non può alimentare il bus e ogni lettura per gear darà timeout “Gear not responding!”. Se viene aggiunto un secondo PSU su una linea lunga, inserisci un’induttanza DALI o suddividi il bus in segmenti galvanicamente separati.

Configurazione

Abilitazione della comunicazione Modbus

I parametri seriali host sul RESI-DALI-SIO sono selezionati da un DIP switch a 4 posizioni sul modulo. Il template TapHome è fissato a 9600 baud 8N1, quindi i DIP switch devono corrispondere.

DIP1DIP2Baud rate
OFFOFF9600 bd (richiesto da TapHome)
ONOFF19200 bd
OFFON38400 bd
ONONUtilizza il baud rate programmato in FLASH (default di fabbrica 57600 bd)
DIP4Sorgente Modbus Unit ID
OFFIl registro FLASH H:65221 viene rispettato — necessario se è stato programmato uno Slave ID non predefinito durante la messa in servizio
ONFallback hardware — Unit ID forzato a 255, il valore FLASH viene ignorato

DIP3 è un bit riservato specifico del prodotto; lascialo nella posizione di fabbrica. La parità è fissata a None e i bit di stop a 1 (formato frame 8N1) per le combinazioni di baud rate DIP1/DIP2 selezionate sopra.

Terminazione RS-485: termina il bus con 120 Ω a entrambe le estremità. TapHome Core fornisce una terminazione sui suoi morsetti BUS; se il gateway RESI è l’ultimo dispositivo sulla linea, aggiungi una resistenza discreta da 120 Ω tra A+ / B- sui suoi morsetti RS-485.

Slave ID

L’Unit ID Modbus predefinito di fabbrica è 255 (il registro FLASH H:65221 legge 0xFFFF, che il gateway clampa a 255). Il template espone un attributo di servizio a livello di modulo Slave ID che rilegge questo registro, quindi l’indirizzo configurato può essere verificato dopo l’importazione.

La modifica dello Slave ID è una questione di messa in servizio gestita dal template gemello Resi Dali - Configurazione — questo template runtime intenzionalmente non scrive in H:65221 né attiva un reset software, in modo da poter rimanere attivo nel progetto senza rischio di riconfigurazione accidentale del gateway.

Setup RTU-over-TCP

Poiché il template utilizza una connessione Modbus RTU, viene offerto anche un parametro di importazione IpAddress per installazioni in cui TapHome raggiunge il gateway tramite un bridge seriale-IP (Moxa NPort, USR-TCP232) o tramite il RESI-DALI-ETH in modalità RTU-over-Ethernet trasparente. In tal caso punta IpAddress all’IP del bridge / unità ETH e mantieni tutte le altre impostazioni identiche alla variante RS-485. Per Modbus/TCP puro un template basato su TCP sarebbe più naturale — questo template Modbus RTU si aspetta specificamente traffico RTU framed.

Solo un master Modbus alla volta. Né DALI né Modbus RTU arbitrano tra master concorrenti. Se un PLC, BMS o strumento PC (ad esempio MODBUSConfigurator) sta anche pollando il gateway, le query dei gear si scontreranno e TapHome segnalerà errori sporadici “Gear not responding!”.

Relazione con il template di configurazione

La stessa definizione Dali.xml viene fornita con il gateway RESI come due template TapHome complementari che operano in diverse fasi del ciclo di vita dello stesso hardware:

TemplateFaseCosa faQuando utilizzare
Resi Dali - Configurazione (resi-dali-daliconfig)Messa in servizio una tantumProcedura guidata di indirizzamento casuale DALI 2.0, sondaggio device-type per indirizzo, test ON/OFF di sanità broadcast, Reimposta indirizzi brevi / Delete short address / Change short address, Set Slave ID, Reset GatewayNuova installazione: assegna indirizzi brevi 0–63 ai dispositivi di controllo, verifica quali indirizzi sono popolati
Resi DALI (resi-dali-dali, questo template)Controllo runtime quotidianoDimmerazione per gear (64 gear), dimmerazione di gruppo (16 gruppi), diagnostica DALI 1.0 per gear, gestione dell’appartenenza ai gruppiDopo la messa in servizio: controllo dell’illuminazione per l’utente finale

Flusso tipico del progetto:

  1. Cabla e alimenta il bus DALI (RESI-DALI-PS) e il gateway.
  2. Importa il template Resi Dali - Configurazione, esegui l’azione del modulo Reimposta indirizzi brevi (Confirm = Yes), poi seleziona Avvio nella procedura guidata Find New Devices — passa da sola per Scansiona indirizzo breve → Set SEARCHADDR → Verifica → PROGRAM SHORT ADDRESS finché non si ferma su Termina, poi chiudi la sessione con TERMINATE. Verifica con Gear 0..63 e Turn On / Off All Lamps.
  3. Rimuovi il modulo Resi Dali - Configurazione dal progetto.
  4. Importa il template Resi DALI (questo) per il controllo runtime. Mappa i dispositivi Gear N e Group N su scene, pianificazioni e regole TapHome.

Entrambi i template possono anche coesistere temporaneamente — ad esempio quando si aggiunge un nuovo gear a un’installazione attiva — ma solo uno dovrebbe inviare traffico Modbus alla volta. Il template runtime omette intenzionalmente le azioni di riconfigurazione del gateway (Reset Gateway, Set Slave ID, broadcast ALL LEVEL) in modo da poter rimanere nel progetto senza rischio di sovrascrivere le impostazioni di messa in servizio.

Lo strumento DCA gratuito del produttore MODBUSConfigurator (Windows, disponibile dal sito RESI) può anche essere utilizzato per la messa in servizio al posto del template TapHome Resi Dali - Configurazione. Il template runtime Resi DALI funziona allo stesso modo indipendentemente dallo strumento utilizzato per assegnare gli indirizzi brevi.

Funzionalità del dispositivo

Il template espone 80 dispositivi DALI in TapHome, organizzati in due gruppi paralleli: 64 dimmer Gear (uno per indirizzo breve DALI) e 16 dimmer Group (uno per gruppo DALI). Un attributo di servizio a livello di modulo completa il quadro.

Dimmerazione per gear — Gear 0 … Gear 63

Ognuno dei 64 dispositivi di servizio Gear 0, Gear 1, … Gear 63 è un dimmer TapHome che si rivolge a un singolo dispositivo di controllo DALI all’indirizzo breve corrispondente. Le scritture di luminosità vanno a H:510 LAMP LEVEL (TapHome 0–100 % è scalato linearmente nel range DALI arc power delimitato dai propri MIN LEVEL e MAX LEVEL del gear); il livello effettivo viene riletto da H:511 tramite il comando DALI QUERY ACTUAL LEVEL (0xA0) e riscalato in 0–100 %.

Quando il template importa un gear, uno script init prima sonda il gear con QUERY STATUS (0x90); qualsiasi byte di risposta dimostra che il gear è presente e viene memorizzato come suo stato. Una risposta 0x8000 “nessuna risposta” contrassegna il gear come non risponde (per un intervallo casuale di 1–60 s) ed emette “Gear not responding!” nel log TapHome. Se il gear risponde, lo script init quindi legge QUERY MIN LEVEL (0xA2) e QUERY MAX LEVEL (0xA1) e memorizza i risultati nello stato interno per il readscript periodico.

Ogni query è protetta da risposte obsolete e corrotte: prima di ogni query il template legge e scarta una risposta non letta rimasta in H:511, così che non venga presa per la risposta alla nuova query. Una risposta di livello che non è un livello valido (0xFF, 0x20FF collisione sul bus, 0x8000 nessuna risposta) o che è compresa tra 1 e il MIN LEVEL del gear viene scartata e resta l’ultimo livello, e un livello cambiato viene accettato solo dopo una seconda lettura uguale. Gli attributi di servizio del livello mostrano -- invece di un valore non valido.

Ogni gear espone 12 attributi di servizio che leggono i comandi di query DALI 1.0 / 2.0 su richiesta:

Attributo di servizioComando DALIRiporta
Short Address(interno)L’indirizzo breve (0–63) target di questo dispositivo — fissato al momento dell’importazione del template
Device TypeQUERY DEVICE TYPE (0x99)DT{n} (es. DT0 fluorescente, DT6 LED, DT8 colore / tunable white) o -- quando non c’è risposta. Un gear con più device type risponde 0xFF (MASK); il template li elenca allora con QUERY NEXT DEVICE TYPE (0xA7), es. DT6, DT8, oppure mostra MASK quando non viene restituito alcun tipo
Physical Min LevelQUERY PHYSICAL MIN LEVEL (0x9A)Livello minimo di dimmerazione imposto dall’hardware in %
Max LevelQUERY MAX LEVEL (0xA1)Limite superiore configurato utilizzato per scalare 0–100 % a DALI arc power
Min LevelQUERY MIN LEVEL (0xA2)Limite inferiore configurato utilizzato per scalare 0–100 % a DALI arc power
Power Up LevelQUERY POWER ON LEVEL (0xA3)Luminosità ripristinata dopo il ripristino dell’alimentazione del bus DALI
System Failure LevelQUERY SYSTEM FAILURE LEVEL (0xA4)Luminosità adottata quando il bus perde la comunicazione per >500 ms
GroupsQUERY GROUPS 0-7 (0xC0) + QUERY GROUPS 8-15 (0xC1)Elenco separato da virgole dei gruppi DALI a cui appartiene il gear (None o es. 0,3,7)
DALI StatusQUERY STATUS (0x90)Byte di stato decodificato con il suo valore grezzo: OK quando nessun bit è impostato, altrimenti i flag impostati — gear failure, lamp failure, lamp on, limit error, fade running, reset state, missing short address, power cycle — es. lamp on (0x04). Un guasto presente dalla prima risposta del gear è contrassegnato con not raised: … reported since start
FadeQUERY FADE TIME/FADE RATE (0xA5) + QUERY EXTENDED FADE TIME (0xA8)fade time {n} ({t} s), fade rate {n}; fade time off quando è 0, oppure extended 0x.. quando il gear usa invece un extended fade time
DALI VersionQUERY VERSION NUMBER (0x97)DALI-1 o DALI-2 {major}.{minor}, seguito dal valore grezzo tra parentesi
Bus statistics(contatori interni)Contatori dall’avvio: query, risposte obsolete scartate, nessuna risposta, collisioni, livelli rifiutati

Il readscript periodico su ogni gear legge il livello arc corrente (0xA0) e interroga QUERY STATUS (0x90) almeno una volta ogni 60 cicli di lettura. Il bit 0 del byte di stato segnala “Control gear failure!” e il bit 1 segnala “Lamp failure!” — esposti come avvisi/errori TapHome in modo che un tubo fluorescente guasto o un driver LED scattato compaia nel log delle attività senza polling manuale. Un bit di guasto cambiato viene accettato solo dopo una seconda lettura uguale, e una risposta persa viene richiesta ancora una volta prima che il gear venga segnalato come “Gear not responding!”. I bit di guasto che un gear riporta nella sua prima risposta sono trattati come il suo stato permanente: vengono mostrati in DALI Status ma non segnalati finché il bit non si azzera — un guasto successivo viene allora segnalato di nuovo. Il guasto di alimentazione non viene segnalato come errore; il bit di stato compare in DALI Status come power cycle.

Azioni di configurazione per gear

Cinque azioni di servizio su ogni dispositivo Gear N scrivono comandi di configurazione DALI (auto-ripetuti entro 100 ms tramite H:512 LAMP COMMAND + REPEAT come richiesto per i comandi DALI non volatili):

  • Add to Group (parametro Group ID 0–15) — invia ADD TO GROUP (0x60+grp) in modo che il gear si unisca al gruppo DALI scelto e obbedisca alle successive scritture broadcast del gruppo.
  • Remove from Group (parametro Group ID 0–15) — invia REMOVE FROM GROUP (0x70+grp).
  • Reset to Default Settings — invia DALI RESET (0x20); ripristina tutti i parametri NVM del gear (livelli max/min/power-on/system-failure, appartenenza al gruppo, scene) ai valori predefiniti del produttore.
  • Set Startup Levels — cattura l’arc power corrente e la memorizza come Power On Level e System Failure Level, in sequenza: STORE ACTUAL LEVEL IN DTR (0x21) → STORE DTR AS POWER ON LEVEL (0x2C) → STORE DTR AS SYSTEM FAILURE LEVEL (0x2D), ognuno con un intervallo di 10 ms.
  • Disable fading (nessun parametro) — carica 0 nel registro DALI di trasferimento dati (0xA300 scritto in H:541) e lo memorizza nel gear come fade time (0x2E) ed extended fade time (0x30), ognuno con un intervallo di 100 ms, così le variazioni di livello hanno effetto senza dissolvenza. I valori correnti sono mostrati nell’attributo Fade.

Dimmerazione di gruppo — Group 0 … Group 15

Ognuno dei 16 dispositivi di servizio Group 0, Group 1, … Group 15 è un dimmer TapHome write-only che broadcasta un singolo valore arc-power a ogni gear appartenente a quel gruppo DALI, utilizzando H:520 GROUP LEVEL (TapHome 0–100 % viene moltiplicato per 0xFE → DALI arc power 0–254). DALI non consente al gateway di rileggere un livello di gruppo — il bus trasporta solo la scrittura broadcast — quindi TapHome mantiene l’ultimo valore scritto come livello “corrente”. Non ci sono script init o read sui dispositivi di gruppo.

Ogni dispositivo Group N espone due azioni di servizio per la gestione di massa dell’appartenenza:

  • Add All Lamps to Group — broadcasta ADD TO GROUP (0x60+grp) tramite H:532 ALL COMMAND + REPEAT. Ogni gear sul bus si unisce al gruppo indipendentemente dal suo indirizzo breve corrente.
  • Remove All Lamps from Group — broadcasta REMOVE FROM GROUP (0x70+grp). Ogni gear lascia il gruppo.

Utilizza la dimmerazione di gruppo per “luci della cucina”, “downlight del soggiorno” o qualsiasi zona in cui più gear devono seguire un singolo dimmer. Le scritture di gruppo sono molto più efficienti rispetto al pilotaggio di gear individuali in parallelo — una singola transazione Modbus raggiunge fino a 64 gear contemporaneamente.

Diagnostica a livello di modulo

Il modulo espone un singolo attributo di servizio:

  • Slave ID — legge il Modbus Unit ID memorizzato nel registro FLASH H:65221. Attivo solo quando DIP4 = OFF; con DIP4 = ON il gateway forza l’indirizzo 255 indipendentemente dal valore FLASH. Utilizzalo per verificare l’indirizzo del gateway prima di aggiungere altri dispositivi, specialmente dopo un giro di messa in servizio che ha scritto un ID non predefinito.

Risoluzione dei problemi

“Gear not responding!” su un gear noto e indirizzato

  1. Conferma la tensione del bus DALI sul gear: 11,5–22,5 V (tipicamente 14–16 V). Letture inferiori indicano solitamente un cortocircuito o un bus troppo lungo per la sezione del cavo (vedi Topologia del bus DALI).
  2. Controlla il LED ERR sul RESI-DALI-PS — se acceso, il bus è in cortocircuito, sovraccarico o il PSU stesso è guasto.
  3. Riesegui il sondaggio Gear N nel template gemello Resi Dali - Configurazione — il template runtime riprova solo dopo una pausa casuale fino a 60 s, il template di configurazione fornisce un pass/fail immediato per indirizzo.
  4. Verifica che il gear abbia effettivamente un indirizzo breve. Se è stato sostituito o resettato di fabbrica sul bus, sarà non indirizzato e dovrà essere rimesso in servizio tramite Resi Dali - Configurazione.

La dimmerazione di gruppo non ha effetto

  1. Conferma che almeno un gear è membro del gruppo — apri Gear N → Groups su ogni membro sospetto e controlla che l’ID del gruppo appaia nell’elenco separato da virgole.
  2. Se l’appartenenza è mancante, attiva l’azione Add to Group su ogni gear individualmente, oppure usa Add All Lamps to Group sul dispositivo di gruppo per un broadcast su tutto il bus.
  3. Ricorda che Group N è write-only — lo slider del dimmer in TapHome memorizza l’ultimo valore scritto, ma non riflette lo stato effettivo del bus. Se i gear sono spenti, il comando di livello del gruppo non ha effetto su di essi.

Guasto lampada / guasto alimentazione non segnalati

  1. Apri l’attributo DALI Status del gear. Se termina con not raised: … reported since start, il guasto era già presente nella prima risposta del gear ed è trattato come il suo stato permanente — viene mostrato ma non segnalato finché il bit non si azzera una volta.
  2. Il guasto di alimentazione non viene affatto segnalato come errore; il bit di stato è mostrato in DALI Status come power cycle.
  3. Un nuovo guasto compare solo dopo che lo stato è stato interrogato (almeno una volta ogni 60 cicli di lettura) e letto due volte uguale, quindi un breve sfarfallio del bit di guasto non viene segnalato.

Errori Modbus sporadici dopo la messa in servizio

  1. Assicurati che nessun altro master Modbus (MODBUSConfigurator, PLC, BMS) stia pollando il gateway contemporaneamente. DALI e Modbus non arbitrano tra i master. L’attributo Bus statistics su ogni gear conta dall’avvio le risposte obsolete scartate, le risposte mancanti, le collisioni e i livelli rifiutati — conteggi in continuo aumento indicano traffico concorrente sul gateway o sul bus DALI.
  2. Verifica che RS485 GND sia collegato tra il gateway e il riferimento comune dell’alimentatore TapHome — la GND mancante è il guasto RS-485 più comune sulle linee lunghe.
  3. Per RTU-over-TCP tramite un bridge seriale, conferma che il bridge funzioni in modalità RTU framed (non socket TCP raw) e che il gap inter-carattere sul lato seriale rispetti la temporizzazione 9600 baud 8N1.
  4. Se i sintomi sono comparsi dopo aver modificato lo Slave ID con il template Resi Dali - Configurazione, reimporta questo template runtime con il nuovo parametro di importazione SlaveId — il modulo precedentemente importato sta ancora pollando al vecchio indirizzo.

Dispositivi disponibili 80

Questi dispositivi compaiono in TapHome dopo l'importazione.

Resi DALI Modulo
Attributi di servizio
Slave IDLegge il Modbus Unit ID memorizzato nel registro FLASH H:65221 — attivo solo quando DIP4=OFF (default di fabbrica 255). Utilizzalo per verificare l'indirizzo del gateway prima di aggiungere altri dispositivi.

Resi Dali

Attributi di servizio
${xml_slave_id}
modbusr(H,65221,uint16)
Gear 0 Dimmer Lettura e scrittura

Dispositivo di controllo DALI all'indirizzo breve 0 — dimmer TapHome mappato su DALI arc power 0–100 % tramite H:510 LAMP LEVEL (scrittura) e QUERY ACTUAL LEVEL tramite H:511 (lettura), delimitato dai propri MIN / MAX LEVEL del gear.

Registro: H:511 → H:510 UInt16 Unità: % numeric
Attributi di servizio
Indirizzo breveIndirizzo breve DALI (0–63) target di questo dispositivo — fissato al momento dell'importazione del template e utilizzato nel byte alto di ogni scrittura Modbus.
Device TypeByte device-type DALI restituito da QUERY DEVICE TYPE (0x99) — riporta DT0 (fluorescente), DT6 (driver LED), DT8 (colore / tunable white) ecc., o -- quando non c'è risposta.
Physical Min LevelLivello minimo di dimmerazione imposto dall'hardware riportato dal gear — letto da QUERY PHYSICAL MIN LEVEL (0x9A), in percentuale.
Max LevelDALI MAX LEVEL configurato — letto da QUERY MAX LEVEL (0xA1); utilizzato come limite superiore durante la scalatura di TapHome 0–100 % su DALI arc power.
Min LevelDALI MIN LEVEL configurato — letto da QUERY MIN LEVEL (0xA2); utilizzato come limite inferiore durante la scalatura di TapHome 0–100 % su DALI arc power.
Power Up LevelLuminosità ripristinata dopo il ripristino dell'alimentazione del bus DALI — letta da QUERY POWER ON LEVEL (0xA3).
System Failure LevelLuminosità adottata quando il bus DALI perde la comunicazione per più di 500 ms — letta da QUERY SYSTEM FAILURE LEVEL (0xA4).
GruppiElenco separato da virgole dei gruppi DALI (0–15) a cui appartiene il gear — decodificato da QUERY GROUPS 0-7 (0xC0) e QUERY GROUPS 8-15 (0xC1); mostra None o ad es. 0,3,7.
Support Lamp FailureSe la lampada / driver supporta il rilevamento dei guasti della lampada — Yes / No / --. Gestisce l'errore Lamp failure! nel readscript periodico.
Support Power FailureSe la lampada / driver supporta il rilevamento dei guasti di alimentazione — Yes / No / --. Gestisce l'errore Power failure! nel readscript periodico.
DALI Version
Bus statistics
Azioni di servizio
Add to GroupAggiunge questo gear a un gruppo DALI (0–15) tramite ADD TO GROUP (0x60+grp) — auto-ripetuto entro 100 ms come richiesto per i comandi di configurazione DALI.
Remove from GroupRimuove questo gear da un gruppo DALI (0–15) tramite REMOVE FROM GROUP (0x70+grp).
Reset to Default SettingsInvia DALI RESET (0x20) — ripristina ogni parametro NVM del gear (livelli max / min / power-on / system-failure, appartenenza al gruppo, scene) al valore predefinito del produttore.
Set Startup LevelsCattura l'arc power corrente e la memorizza come Power On Level e System Failure Level — sequenza STORE ACTUAL LEVEL IN DTR (0x21) → STORE DTR AS POWER ON LEVEL (0x2C) → STORE DTR AS SYSTEM FAILURE LEVEL (0x2D).
Disable fading

Gear 0

Lettura (modulo)
var x := 0; var rx := 0; var y := 0;
if Status > 0
    Status := Status - 1;
    adderror(3, "Gear not responding!");
    return(0);
end

# checkStatus: ReadLevel resets it while the gear answers; statusPoll: QUERY STATUS at least once per 60 runs
checkStatus := checkStatus - 1;
statusPoll := statusPoll - 1;
if checkStatus < 1 or statusPoll < 1
    # an unread answer left in the gateway would be taken for this query: read it away and count it
    x := modbusr(SH, 511, uint16); if (x != 0x8000, cntStale := cntStale + 1);
    modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x90);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    x := modbusr(SH, 511, uint16);
    cntQ := cntQ + 1; if (x = 0x8000, cntNone := cntNone + 1); if (x = 0x20FF, cntColl := cntColl + 1);
    # a single lost answer happens on DALI: ask once more before declaring the gear missing
    if x = 0x8000
        x := modbusr(SH, 511, uint16); if (x != 0x8000, cntStale := cntStale + 1);
        modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x90);
        sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
        x := modbusr(SH, 511, uint16);
        cntQ := cntQ + 1; if (x = 0x8000, cntNone := cntNone + 1); if (x = 0x20FF, cntColl := cntColl + 1);
    end
    if x <= 0xFF
        # a changed failure bit must be read twice the same before it is taken
        if statusSeen = 1 and getbits(x, 0, 2) != getbits(gearStatus, 0, 2)
            y := modbusr(SH, 511, uint16); if (y != 0x8000, cntStale := cntStale + 1);
            modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x90);
            sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
            y := modbusr(SH, 511, uint16);
            cntQ := cntQ + 1; if (y = 0x8000, cntNone := cntNone + 1); if (y = 0x20FF, cntColl := cntColl + 1);
            if y != x
                cntBad := cntBad + 1;
                x := gearStatus;
            end
        end
        if statusSeen = 0
            ignGear := getbit(x, 0);
            ignLamp := getbit(x, 1);
            statusSeen := 1;
        end
        # a bit that clears ends its ignore, so a later failure is raised
        if (getbit(x, 0) = 0, ignGear := 0);
        if (getbit(x, 1) = 0, ignLamp := 0);
        gearStatus := x;
        checkStatus := 60;
        statusPoll := 60;
    else
        if x = 0x8000
            Status := RANDINT(10, 60);
            adderror(3, "Gear not responding!");
            return(0);
        end
    end
end

# messages last one run only, so they are raised from the stored status on every run
if ((getbit(gearStatus, 0) = 1) and (ignGear = 0), adderror(1, "Control gear failure!"));
if ((getbit(gearStatus, 1) = 1) and (ignLamp = 0), adderror(2, "Lamp failure!"));
Inizializzazione
var x := 0; var rx := 0;
# QUERY STATUS 0x90: every reply byte proves the gear is present; 0x8000 = no answer, 0x20FF = bus collision
# an unread answer left in the gateway would be taken for this query: read it away and count it
x := modbusr(SH, 511, uint16); if (x != 0x8000, cntStale := cntStale + 1);
modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x90);
sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
x := modbusr(SH, 511, uint16);
cntQ := cntQ + 1; if (x = 0x8000, cntNone := cntNone + 1); if (x = 0x20FF, cntColl := cntColl + 1);
statusSeen := 0;
if x <= 0xFF
    # failure bits a gear reports from its first answer are its permanent state, not an event: shown, not raised
    gearStatus := x;
    ignGear := getbit(x, 0);
    ignLamp := getbit(x, 1);
    statusSeen := 1;
    Status := 0;
else
    Status := RANDINT(1, 60);
end

if Status = 0
    x := modbusr(SH, 511, uint16); if (x != 0x8000, cntStale := cntStale + 1);
    modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA2);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    x := modbusr(SH, 511, uint16);
    cntQ := cntQ + 1; if (x = 0x8000, cntNone := cntNone + 1); if (x = 0x20FF, cntColl := cntColl + 1);
    if (x <= 0xFE, minLevel := x);

    x := modbusr(SH, 511, uint16); if (x != 0x8000, cntStale := cntStale + 1);
    modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA1);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    x := modbusr(SH, 511, uint16);
    cntQ := cntQ + 1; if (x = 0x8000, cntNone := cntNone + 1); if (x = 0x20FF, cntColl := cntColl + 1);
    if (x <= 0xFE, maxLevel := x);
end
Lettura livello
var x := 0; var rx := 0; var y := 0;
if Status = 0
    if minLevel = 0
        # an unread answer left in the gateway would be taken for this query: read it away and count it
        x := modbusr(SH, 511, uint16); if (x != 0x8000, cntStale := cntStale + 1);
        modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA2);
        sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
        x := modbusr(SH, 511, uint16);
        cntQ := cntQ + 1; if (x = 0x8000, cntNone := cntNone + 1); if (x = 0x20FF, cntColl := cntColl + 1);
        if (x <= 0xFE, minLevel := x);
    end
    x := modbusr(SH, 511, uint16); if (x != 0x8000, cntStale := cntStale + 1);
    modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA0);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    x := modbusr(SH, 511, uint16);
    cntQ := cntQ + 1; if (x = 0x8000, cntNone := cntNone + 1); if (x = 0x20FF, cntColl := cntColl + 1);
    if (x != 0x8000 or rx, checkStatus := 60);
    # 0xFF = MASK, 0x20FF = collision, 0x8000 = no answer: keep the last level instead of a phantom value
    if x > 0xFE
        return(Le);
    end
    # an actual level is 0 or between the gear's min and max: anything else is not this gear's answer
    if x > 0 and x < minLevel
        cntBad := cntBad + 1;
        return(Le);
    end
    # a changed level must be read twice the same before it is taken
    if x != lastRaw
        y := modbusr(SH, 511, uint16); if (y != 0x8000, cntStale := cntStale + 1);
        modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA0);
        sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
        y := modbusr(SH, 511, uint16);
        cntQ := cntQ + 1; if (y = 0x8000, cntNone := cntNone + 1); if (y = 0x20FF, cntColl := cntColl + 1);
        if y != x
            cntBad := cntBad + 1;
            return(Le);
        end
        lastRaw := x;
    end
    return(if(x = 0, 0, linear(x, minLevel, 0.01, maxLevel, 1)));
else
    return(NaN);
end
Scrittura livello
var level := 0;
if(Le > 0, level := round(linear(Le, 0.01, minLevel, 1, maxLevel)));
modbusw(SH, 510, uint16, (ShortAddress << 8) + level );
Attributi di servizio
${xml_short_address}
ShortAddress
${xml_device_type}
var x := 0; var y := 0; var rx := 0; var s := ""; var i := 0;
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x99);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    x := modbusr(SH, 511, uint16);
    if (x < 0xFF, return("DT" + x));
    if x = 0xFF
        while i < 8
            modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA7);
            sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
            y := modbusr(SH, 511, uint16);
            if y < 0xFE
                s := if(s = "", "DT" + y, s + ", DT" + y);
                i := i + 1;
            else
                i := 8;
            end
        loop
        return(if(s = "", "MASK", s));
    end
end

return("--")
Physical Min Level
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x9A);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if (x <= 0xFE, return(round((x / 0xFE) * 100) + " %"));
end

return("--")
Max Level
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA1);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if (x <= 0xFE, return(round((x / 0xFE) * 100) + " %"));
end

return("--")
Min Level
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA2);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if (x <= 0xFE, return(round((x / 0xFE) * 100) + " %"));
end

return("--")
Power Up Level
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA3);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if (x <= 0xFE, return(round((x / 0xFE) * 100) + " %"));
end

return("--")
System Failure Level
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA4);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if (x <= 0xFE, return(round((x / 0xFE) * 100) + " %"));
end

return("--")
${xml_groups}
var x := 0; var rx := 0;
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xC0);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var g1 := modbusr(SH, 511, uint16);
    if (g1 > 0xFF, return("--")); 

    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xC1);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var g2 := modbusr(SH, 511, uint16);
    if (g2 > 0xFF, return("--")); 

    var ret := "";

    if (getbit(g1, 0), ret := ret + "0");
    if (getbit(g1, 1), if (ret = "", ret := "1", ret := ret + ",1"));
    if (getbit(g1, 2), if (ret = "", ret := "2", ret := ret + ",2"));
    if (getbit(g1, 3), if (ret = "", ret := "3", ret := ret + ",3"));
    if (getbit(g1, 4), if (ret = "", ret := "4", ret := ret + ",4"));
    if (getbit(g1, 5), if (ret = "", ret := "5", ret := ret + ",5"));
    if (getbit(g1, 6), if (ret = "", ret := "6", ret := ret + ",6"));
    if (getbit(g1, 7), if (ret = "", ret := "7", ret := ret + ",7"));
    if (getbit(g2, 0), if (ret = "", ret := "8", ret := ret + ",8"));
    if (getbit(g2, 1), if (ret = "", ret := "9", ret := ret + ",9"));
    if (getbit(g2, 2), if (ret = "", ret := "10", ret := ret + ",10"));
    if (getbit(g2, 3), if (ret = "", ret := "11", ret := ret + ",11"));
    if (getbit(g2, 4), if (ret = "", ret := "12", ret := ret + ",12"));
    if (getbit(g2, 5), if (ret = "", ret := "13", ret := ret + ",13"));
    if (getbit(g2, 6), if (ret = "", ret := "14", ret := ret + ",14"));
    if (getbit(g2, 7), if (ret = "", ret := "15", ret := ret + ",15"));

    if (ret = "", return("None"), return(ret));
else
    return("--");
end
DALI Status
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x90);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if x <= 0xFF
        var s := "";
        if (getbit(x, 0), s := if(s = "", "gear failure", s + ", gear failure"));
        if (getbit(x, 1), s := if(s = "", "lamp failure", s + ", lamp failure"));
        if (getbit(x, 2), s := if(s = "", "lamp on", s + ", lamp on"));
        if (getbit(x, 3), s := if(s = "", "limit error", s + ", limit error"));
        if (getbit(x, 4), s := if(s = "", "fade running", s + ", fade running"));
        if (getbit(x, 5), s := if(s = "", "reset state", s + ", reset state"));
        if (getbit(x, 6), s := if(s = "", "missing short address", s + ", missing short address"));
        if (getbit(x, 7), s := if(s = "", "power cycle", s + ", power cycle"));
        var ign := if((ignGear = 1) and (ignLamp = 1), "gear and lamp failure", if(ignGear = 1, "gear failure", if(ignLamp = 1, "lamp failure", "")));
        return(if(s = "", "OK", s) + " (0x" + tostring(x, "X2") + ")" + if(ign = "", "", "; not raised: " + ign + " reported since start"));
    end
end

return("--")
Fade
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA5);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if x <= 0xFF
        var t := getbits(x, 4, 4);
        var ret := if(t = 0, "off", t + " (" + round(sqrt(power(2, t)) * 5) / 10 + " s)");
        modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA8);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
        var e := modbusr(SH, 511, uint16);
        if (t = 0 and e <= 0xFF and e != 0, ret := "extended 0x" + tostring(e, "X2"));
        return("fade time " + ret + ", fade rate " + getbits(x, 0, 4));
    end
end

return("--")
DALI Version
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x97);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if x <= 0xFF
        return(if(x >= 8, "DALI-2 " + getbits(x, 2, 6) + "." + getbits(x, 0, 2), "DALI-1") + " (" + x + ")");
    end
end

return("--")
Bus statistics
return("since start: queries " + cntQ + ", stale answers read away " + cntStale + ", no answer " + cntNone + ", collisions " + cntColl + ", rejected levels " + cntBad)
Azioni di servizio
${xml_add_to_group}
Parametri: Group ID (0–15 grp)
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x60 + grp);
${xml_remove_from_group}
Parametri: Group ID (0–15 grp)
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x70 + grp);
${xml_reset_to_default_settings}
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x20);
${xml_set_startup_levels}
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x21);
sleep(10);
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x2c);
sleep(10);
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x2d);
Disable fading
modbusw(SH, 541, uint16, 0xA300);
sleep(100);
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x2E);
sleep(100);
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x30);
Gear 1 Dimmer Lettura e scrittura

Dispositivo di controllo DALI all'indirizzo breve 1 — dimmer TapHome mappato su DALI arc power 0–100 % tramite H:510 LAMP LEVEL (scrittura) e QUERY ACTUAL LEVEL tramite H:511 (lettura), delimitato dai propri MIN / MAX LEVEL del gear.

Registro: H:511 → H:510 UInt16 Unità: % numeric
Attributi di servizio
Indirizzo breveIndirizzo breve DALI (0–63) target di questo dispositivo — fissato al momento dell'importazione del template e utilizzato nel byte alto di ogni scrittura Modbus.
Device TypeByte device-type DALI restituito da QUERY DEVICE TYPE (0x99) — riporta DT0 (fluorescente), DT6 (driver LED), DT8 (colore / tunable white) ecc., o -- quando non c'è risposta.
Physical Min LevelLivello minimo di dimmerazione imposto dall'hardware riportato dal gear — letto da QUERY PHYSICAL MIN LEVEL (0x9A), in percentuale.
Max LevelDALI MAX LEVEL configurato — letto da QUERY MAX LEVEL (0xA1); utilizzato come limite superiore durante la scalatura di TapHome 0–100 % su DALI arc power.
Min LevelDALI MIN LEVEL configurato — letto da QUERY MIN LEVEL (0xA2); utilizzato come limite inferiore durante la scalatura di TapHome 0–100 % su DALI arc power.
Power Up LevelLuminosità ripristinata dopo il ripristino dell'alimentazione del bus DALI — letta da QUERY POWER ON LEVEL (0xA3).
System Failure LevelLuminosità adottata quando il bus DALI perde la comunicazione per più di 500 ms — letta da QUERY SYSTEM FAILURE LEVEL (0xA4).
GruppiElenco separato da virgole dei gruppi DALI (0–15) a cui appartiene il gear — decodificato da QUERY GROUPS 0-7 (0xC0) e QUERY GROUPS 8-15 (0xC1); mostra None o ad es. 0,3,7.
Support Lamp FailureSe la lampada / driver supporta il rilevamento dei guasti della lampada — Yes / No / --. Gestisce l'errore Lamp failure! nel readscript periodico.
Support Power FailureSe la lampada / driver supporta il rilevamento dei guasti di alimentazione — Yes / No / --. Gestisce l'errore Power failure! nel readscript periodico.
DALI Version
Bus statistics
Azioni di servizio
Add to GroupAggiunge questo gear a un gruppo DALI (0–15) tramite ADD TO GROUP (0x60+grp) — auto-ripetuto entro 100 ms come richiesto per i comandi di configurazione DALI.
Remove from GroupRimuove questo gear da un gruppo DALI (0–15) tramite REMOVE FROM GROUP (0x70+grp).
Reset to Default SettingsInvia DALI RESET (0x20) — ripristina ogni parametro NVM del gear (livelli max / min / power-on / system-failure, appartenenza al gruppo, scene) al valore predefinito del produttore.
Set Startup LevelsCattura l'arc power corrente e la memorizza come Power On Level e System Failure Level — sequenza STORE ACTUAL LEVEL IN DTR (0x21) → STORE DTR AS POWER ON LEVEL (0x2C) → STORE DTR AS SYSTEM FAILURE LEVEL (0x2D).
Disable fading

Gear 1

Lettura (modulo)
var x := 0; var rx := 0; var y := 0;
if Status > 0
    Status := Status - 1;
    adderror(3, "Gear not responding!");
    return(0);
end

# checkStatus: ReadLevel resets it while the gear answers; statusPoll: QUERY STATUS at least once per 60 runs
checkStatus := checkStatus - 1;
statusPoll := statusPoll - 1;
if checkStatus < 1 or statusPoll < 1
    # an unread answer left in the gateway would be taken for this query: read it away and count it
    x := modbusr(SH, 511, uint16); if (x != 0x8000, cntStale := cntStale + 1);
    modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x90);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    x := modbusr(SH, 511, uint16);
    cntQ := cntQ + 1; if (x = 0x8000, cntNone := cntNone + 1); if (x = 0x20FF, cntColl := cntColl + 1);
    # a single lost answer happens on DALI: ask once more before declaring the gear missing
    if x = 0x8000
        x := modbusr(SH, 511, uint16); if (x != 0x8000, cntStale := cntStale + 1);
        modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x90);
        sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
        x := modbusr(SH, 511, uint16);
        cntQ := cntQ + 1; if (x = 0x8000, cntNone := cntNone + 1); if (x = 0x20FF, cntColl := cntColl + 1);
    end
    if x <= 0xFF
        # a changed failure bit must be read twice the same before it is taken
        if statusSeen = 1 and getbits(x, 0, 2) != getbits(gearStatus, 0, 2)
            y := modbusr(SH, 511, uint16); if (y != 0x8000, cntStale := cntStale + 1);
            modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x90);
            sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
            y := modbusr(SH, 511, uint16);
            cntQ := cntQ + 1; if (y = 0x8000, cntNone := cntNone + 1); if (y = 0x20FF, cntColl := cntColl + 1);
            if y != x
                cntBad := cntBad + 1;
                x := gearStatus;
            end
        end
        if statusSeen = 0
            ignGear := getbit(x, 0);
            ignLamp := getbit(x, 1);
            statusSeen := 1;
        end
        # a bit that clears ends its ignore, so a later failure is raised
        if (getbit(x, 0) = 0, ignGear := 0);
        if (getbit(x, 1) = 0, ignLamp := 0);
        gearStatus := x;
        checkStatus := 60;
        statusPoll := 60;
    else
        if x = 0x8000
            Status := RANDINT(10, 60);
            adderror(3, "Gear not responding!");
            return(0);
        end
    end
end

# messages last one run only, so they are raised from the stored status on every run
if ((getbit(gearStatus, 0) = 1) and (ignGear = 0), adderror(1, "Control gear failure!"));
if ((getbit(gearStatus, 1) = 1) and (ignLamp = 0), adderror(2, "Lamp failure!"));
Inizializzazione
var x := 0; var rx := 0;
# QUERY STATUS 0x90: every reply byte proves the gear is present; 0x8000 = no answer, 0x20FF = bus collision
# an unread answer left in the gateway would be taken for this query: read it away and count it
x := modbusr(SH, 511, uint16); if (x != 0x8000, cntStale := cntStale + 1);
modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x90);
sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
x := modbusr(SH, 511, uint16);
cntQ := cntQ + 1; if (x = 0x8000, cntNone := cntNone + 1); if (x = 0x20FF, cntColl := cntColl + 1);
statusSeen := 0;
if x <= 0xFF
    # failure bits a gear reports from its first answer are its permanent state, not an event: shown, not raised
    gearStatus := x;
    ignGear := getbit(x, 0);
    ignLamp := getbit(x, 1);
    statusSeen := 1;
    Status := 0;
else
    Status := RANDINT(1, 60);
end

if Status = 0
    x := modbusr(SH, 511, uint16); if (x != 0x8000, cntStale := cntStale + 1);
    modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA2);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    x := modbusr(SH, 511, uint16);
    cntQ := cntQ + 1; if (x = 0x8000, cntNone := cntNone + 1); if (x = 0x20FF, cntColl := cntColl + 1);
    if (x <= 0xFE, minLevel := x);

    x := modbusr(SH, 511, uint16); if (x != 0x8000, cntStale := cntStale + 1);
    modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA1);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    x := modbusr(SH, 511, uint16);
    cntQ := cntQ + 1; if (x = 0x8000, cntNone := cntNone + 1); if (x = 0x20FF, cntColl := cntColl + 1);
    if (x <= 0xFE, maxLevel := x);
end
Lettura livello
var x := 0; var rx := 0; var y := 0;
if Status = 0
    if minLevel = 0
        # an unread answer left in the gateway would be taken for this query: read it away and count it
        x := modbusr(SH, 511, uint16); if (x != 0x8000, cntStale := cntStale + 1);
        modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA2);
        sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
        x := modbusr(SH, 511, uint16);
        cntQ := cntQ + 1; if (x = 0x8000, cntNone := cntNone + 1); if (x = 0x20FF, cntColl := cntColl + 1);
        if (x <= 0xFE, minLevel := x);
    end
    x := modbusr(SH, 511, uint16); if (x != 0x8000, cntStale := cntStale + 1);
    modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA0);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    x := modbusr(SH, 511, uint16);
    cntQ := cntQ + 1; if (x = 0x8000, cntNone := cntNone + 1); if (x = 0x20FF, cntColl := cntColl + 1);
    if (x != 0x8000 or rx, checkStatus := 60);
    # 0xFF = MASK, 0x20FF = collision, 0x8000 = no answer: keep the last level instead of a phantom value
    if x > 0xFE
        return(Le);
    end
    # an actual level is 0 or between the gear's min and max: anything else is not this gear's answer
    if x > 0 and x < minLevel
        cntBad := cntBad + 1;
        return(Le);
    end
    # a changed level must be read twice the same before it is taken
    if x != lastRaw
        y := modbusr(SH, 511, uint16); if (y != 0x8000, cntStale := cntStale + 1);
        modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA0);
        sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
        y := modbusr(SH, 511, uint16);
        cntQ := cntQ + 1; if (y = 0x8000, cntNone := cntNone + 1); if (y = 0x20FF, cntColl := cntColl + 1);
        if y != x
            cntBad := cntBad + 1;
            return(Le);
        end
        lastRaw := x;
    end
    return(if(x = 0, 0, linear(x, minLevel, 0.01, maxLevel, 1)));
else
    return(NaN);
end
Scrittura livello
var level := 0;
if(Le > 0, level := round(linear(Le, 0.01, minLevel, 1, maxLevel)));
modbusw(SH, 510, uint16, (ShortAddress << 8) + level );
Attributi di servizio
${xml_short_address}
ShortAddress
${xml_device_type}
var x := 0; var y := 0; var rx := 0; var s := ""; var i := 0;
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x99);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    x := modbusr(SH, 511, uint16);
    if (x < 0xFF, return("DT" + x));
    if x = 0xFF
        while i < 8
            modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA7);
            sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
            y := modbusr(SH, 511, uint16);
            if y < 0xFE
                s := if(s = "", "DT" + y, s + ", DT" + y);
                i := i + 1;
            else
                i := 8;
            end
        loop
        return(if(s = "", "MASK", s));
    end
end

return("--")
Physical Min Level
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x9A);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if (x <= 0xFE, return(round((x / 0xFE) * 100) + " %"));
end

return("--")
Max Level
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA1);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if (x <= 0xFE, return(round((x / 0xFE) * 100) + " %"));
end

return("--")
Min Level
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA2);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if (x <= 0xFE, return(round((x / 0xFE) * 100) + " %"));
end

return("--")
Power Up Level
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA3);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if (x <= 0xFE, return(round((x / 0xFE) * 100) + " %"));
end

return("--")
System Failure Level
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA4);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if (x <= 0xFE, return(round((x / 0xFE) * 100) + " %"));
end

return("--")
${xml_groups}
var x := 0; var rx := 0;
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xC0);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var g1 := modbusr(SH, 511, uint16);
    if (g1 > 0xFF, return("--")); 

    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xC1);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var g2 := modbusr(SH, 511, uint16);
    if (g2 > 0xFF, return("--")); 

    var ret := "";

    if (getbit(g1, 0), ret := ret + "0");
    if (getbit(g1, 1), if (ret = "", ret := "1", ret := ret + ",1"));
    if (getbit(g1, 2), if (ret = "", ret := "2", ret := ret + ",2"));
    if (getbit(g1, 3), if (ret = "", ret := "3", ret := ret + ",3"));
    if (getbit(g1, 4), if (ret = "", ret := "4", ret := ret + ",4"));
    if (getbit(g1, 5), if (ret = "", ret := "5", ret := ret + ",5"));
    if (getbit(g1, 6), if (ret = "", ret := "6", ret := ret + ",6"));
    if (getbit(g1, 7), if (ret = "", ret := "7", ret := ret + ",7"));
    if (getbit(g2, 0), if (ret = "", ret := "8", ret := ret + ",8"));
    if (getbit(g2, 1), if (ret = "", ret := "9", ret := ret + ",9"));
    if (getbit(g2, 2), if (ret = "", ret := "10", ret := ret + ",10"));
    if (getbit(g2, 3), if (ret = "", ret := "11", ret := ret + ",11"));
    if (getbit(g2, 4), if (ret = "", ret := "12", ret := ret + ",12"));
    if (getbit(g2, 5), if (ret = "", ret := "13", ret := ret + ",13"));
    if (getbit(g2, 6), if (ret = "", ret := "14", ret := ret + ",14"));
    if (getbit(g2, 7), if (ret = "", ret := "15", ret := ret + ",15"));

    if (ret = "", return("None"), return(ret));
else
    return("--");
end
DALI Status
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x90);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if x <= 0xFF
        var s := "";
        if (getbit(x, 0), s := if(s = "", "gear failure", s + ", gear failure"));
        if (getbit(x, 1), s := if(s = "", "lamp failure", s + ", lamp failure"));
        if (getbit(x, 2), s := if(s = "", "lamp on", s + ", lamp on"));
        if (getbit(x, 3), s := if(s = "", "limit error", s + ", limit error"));
        if (getbit(x, 4), s := if(s = "", "fade running", s + ", fade running"));
        if (getbit(x, 5), s := if(s = "", "reset state", s + ", reset state"));
        if (getbit(x, 6), s := if(s = "", "missing short address", s + ", missing short address"));
        if (getbit(x, 7), s := if(s = "", "power cycle", s + ", power cycle"));
        var ign := if((ignGear = 1) and (ignLamp = 1), "gear and lamp failure", if(ignGear = 1, "gear failure", if(ignLamp = 1, "lamp failure", "")));
        return(if(s = "", "OK", s) + " (0x" + tostring(x, "X2") + ")" + if(ign = "", "", "; not raised: " + ign + " reported since start"));
    end
end

return("--")
Fade
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA5);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if x <= 0xFF
        var t := getbits(x, 4, 4);
        var ret := if(t = 0, "off", t + " (" + round(sqrt(power(2, t)) * 5) / 10 + " s)");
        modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA8);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
        var e := modbusr(SH, 511, uint16);
        if (t = 0 and e <= 0xFF and e != 0, ret := "extended 0x" + tostring(e, "X2"));
        return("fade time " + ret + ", fade rate " + getbits(x, 0, 4));
    end
end

return("--")
DALI Version
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x97);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if x <= 0xFF
        return(if(x >= 8, "DALI-2 " + getbits(x, 2, 6) + "." + getbits(x, 0, 2), "DALI-1") + " (" + x + ")");
    end
end

return("--")
Bus statistics
return("since start: queries " + cntQ + ", stale answers read away " + cntStale + ", no answer " + cntNone + ", collisions " + cntColl + ", rejected levels " + cntBad)
Azioni di servizio
${xml_add_to_group}
Parametri: Group ID (0–15 grp)
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x60 + grp);
${xml_remove_from_group}
Parametri: Group ID (0–15 grp)
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x70 + grp);
${xml_reset_to_default_settings}
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x20);
${xml_set_startup_levels}
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x21);
sleep(10);
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x2c);
sleep(10);
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x2d);
Disable fading
modbusw(SH, 541, uint16, 0xA300);
sleep(100);
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x2E);
sleep(100);
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x30);
Gear 2 Dimmer Lettura e scrittura

Dispositivo di controllo DALI all'indirizzo breve 2 — dimmer TapHome mappato su DALI arc power 0–100 % tramite H:510 LAMP LEVEL (scrittura) e QUERY ACTUAL LEVEL tramite H:511 (lettura), delimitato dai propri MIN / MAX LEVEL del gear.

Registro: H:511 → H:510 UInt16 Unità: % numeric
Attributi di servizio
Indirizzo breveIndirizzo breve DALI (0–63) target di questo dispositivo — fissato al momento dell'importazione del template e utilizzato nel byte alto di ogni scrittura Modbus.
Device TypeByte device-type DALI restituito da QUERY DEVICE TYPE (0x99) — riporta DT0 (fluorescente), DT6 (driver LED), DT8 (colore / tunable white) ecc., o -- quando non c'è risposta.
Physical Min LevelLivello minimo di dimmerazione imposto dall'hardware riportato dal gear — letto da QUERY PHYSICAL MIN LEVEL (0x9A), in percentuale.
Max LevelDALI MAX LEVEL configurato — letto da QUERY MAX LEVEL (0xA1); utilizzato come limite superiore durante la scalatura di TapHome 0–100 % su DALI arc power.
Min LevelDALI MIN LEVEL configurato — letto da QUERY MIN LEVEL (0xA2); utilizzato come limite inferiore durante la scalatura di TapHome 0–100 % su DALI arc power.
Power Up LevelLuminosità ripristinata dopo il ripristino dell'alimentazione del bus DALI — letta da QUERY POWER ON LEVEL (0xA3).
System Failure LevelLuminosità adottata quando il bus DALI perde la comunicazione per più di 500 ms — letta da QUERY SYSTEM FAILURE LEVEL (0xA4).
GruppiElenco separato da virgole dei gruppi DALI (0–15) a cui appartiene il gear — decodificato da QUERY GROUPS 0-7 (0xC0) e QUERY GROUPS 8-15 (0xC1); mostra None o ad es. 0,3,7.
Support Lamp FailureSe la lampada / driver supporta il rilevamento dei guasti della lampada — Yes / No / --. Gestisce l'errore Lamp failure! nel readscript periodico.
Support Power FailureSe la lampada / driver supporta il rilevamento dei guasti di alimentazione — Yes / No / --. Gestisce l'errore Power failure! nel readscript periodico.
DALI Version
Bus statistics
Azioni di servizio
Add to GroupAggiunge questo gear a un gruppo DALI (0–15) tramite ADD TO GROUP (0x60+grp) — auto-ripetuto entro 100 ms come richiesto per i comandi di configurazione DALI.
Remove from GroupRimuove questo gear da un gruppo DALI (0–15) tramite REMOVE FROM GROUP (0x70+grp).
Reset to Default SettingsInvia DALI RESET (0x20) — ripristina ogni parametro NVM del gear (livelli max / min / power-on / system-failure, appartenenza al gruppo, scene) al valore predefinito del produttore.
Set Startup LevelsCattura l'arc power corrente e la memorizza come Power On Level e System Failure Level — sequenza STORE ACTUAL LEVEL IN DTR (0x21) → STORE DTR AS POWER ON LEVEL (0x2C) → STORE DTR AS SYSTEM FAILURE LEVEL (0x2D).
Disable fading

Gear 2

Lettura (modulo)
var x := 0; var rx := 0; var y := 0;
if Status > 0
    Status := Status - 1;
    adderror(3, "Gear not responding!");
    return(0);
end

# checkStatus: ReadLevel resets it while the gear answers; statusPoll: QUERY STATUS at least once per 60 runs
checkStatus := checkStatus - 1;
statusPoll := statusPoll - 1;
if checkStatus < 1 or statusPoll < 1
    # an unread answer left in the gateway would be taken for this query: read it away and count it
    x := modbusr(SH, 511, uint16); if (x != 0x8000, cntStale := cntStale + 1);
    modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x90);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    x := modbusr(SH, 511, uint16);
    cntQ := cntQ + 1; if (x = 0x8000, cntNone := cntNone + 1); if (x = 0x20FF, cntColl := cntColl + 1);
    # a single lost answer happens on DALI: ask once more before declaring the gear missing
    if x = 0x8000
        x := modbusr(SH, 511, uint16); if (x != 0x8000, cntStale := cntStale + 1);
        modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x90);
        sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
        x := modbusr(SH, 511, uint16);
        cntQ := cntQ + 1; if (x = 0x8000, cntNone := cntNone + 1); if (x = 0x20FF, cntColl := cntColl + 1);
    end
    if x <= 0xFF
        # a changed failure bit must be read twice the same before it is taken
        if statusSeen = 1 and getbits(x, 0, 2) != getbits(gearStatus, 0, 2)
            y := modbusr(SH, 511, uint16); if (y != 0x8000, cntStale := cntStale + 1);
            modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x90);
            sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
            y := modbusr(SH, 511, uint16);
            cntQ := cntQ + 1; if (y = 0x8000, cntNone := cntNone + 1); if (y = 0x20FF, cntColl := cntColl + 1);
            if y != x
                cntBad := cntBad + 1;
                x := gearStatus;
            end
        end
        if statusSeen = 0
            ignGear := getbit(x, 0);
            ignLamp := getbit(x, 1);
            statusSeen := 1;
        end
        # a bit that clears ends its ignore, so a later failure is raised
        if (getbit(x, 0) = 0, ignGear := 0);
        if (getbit(x, 1) = 0, ignLamp := 0);
        gearStatus := x;
        checkStatus := 60;
        statusPoll := 60;
    else
        if x = 0x8000
            Status := RANDINT(10, 60);
            adderror(3, "Gear not responding!");
            return(0);
        end
    end
end

# messages last one run only, so they are raised from the stored status on every run
if ((getbit(gearStatus, 0) = 1) and (ignGear = 0), adderror(1, "Control gear failure!"));
if ((getbit(gearStatus, 1) = 1) and (ignLamp = 0), adderror(2, "Lamp failure!"));
Inizializzazione
var x := 0; var rx := 0;
# QUERY STATUS 0x90: every reply byte proves the gear is present; 0x8000 = no answer, 0x20FF = bus collision
# an unread answer left in the gateway would be taken for this query: read it away and count it
x := modbusr(SH, 511, uint16); if (x != 0x8000, cntStale := cntStale + 1);
modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x90);
sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
x := modbusr(SH, 511, uint16);
cntQ := cntQ + 1; if (x = 0x8000, cntNone := cntNone + 1); if (x = 0x20FF, cntColl := cntColl + 1);
statusSeen := 0;
if x <= 0xFF
    # failure bits a gear reports from its first answer are its permanent state, not an event: shown, not raised
    gearStatus := x;
    ignGear := getbit(x, 0);
    ignLamp := getbit(x, 1);
    statusSeen := 1;
    Status := 0;
else
    Status := RANDINT(1, 60);
end

if Status = 0
    x := modbusr(SH, 511, uint16); if (x != 0x8000, cntStale := cntStale + 1);
    modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA2);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    x := modbusr(SH, 511, uint16);
    cntQ := cntQ + 1; if (x = 0x8000, cntNone := cntNone + 1); if (x = 0x20FF, cntColl := cntColl + 1);
    if (x <= 0xFE, minLevel := x);

    x := modbusr(SH, 511, uint16); if (x != 0x8000, cntStale := cntStale + 1);
    modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA1);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    x := modbusr(SH, 511, uint16);
    cntQ := cntQ + 1; if (x = 0x8000, cntNone := cntNone + 1); if (x = 0x20FF, cntColl := cntColl + 1);
    if (x <= 0xFE, maxLevel := x);
end
Lettura livello
var x := 0; var rx := 0; var y := 0;
if Status = 0
    if minLevel = 0
        # an unread answer left in the gateway would be taken for this query: read it away and count it
        x := modbusr(SH, 511, uint16); if (x != 0x8000, cntStale := cntStale + 1);
        modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA2);
        sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
        x := modbusr(SH, 511, uint16);
        cntQ := cntQ + 1; if (x = 0x8000, cntNone := cntNone + 1); if (x = 0x20FF, cntColl := cntColl + 1);
        if (x <= 0xFE, minLevel := x);
    end
    x := modbusr(SH, 511, uint16); if (x != 0x8000, cntStale := cntStale + 1);
    modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA0);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    x := modbusr(SH, 511, uint16);
    cntQ := cntQ + 1; if (x = 0x8000, cntNone := cntNone + 1); if (x = 0x20FF, cntColl := cntColl + 1);
    if (x != 0x8000 or rx, checkStatus := 60);
    # 0xFF = MASK, 0x20FF = collision, 0x8000 = no answer: keep the last level instead of a phantom value
    if x > 0xFE
        return(Le);
    end
    # an actual level is 0 or between the gear's min and max: anything else is not this gear's answer
    if x > 0 and x < minLevel
        cntBad := cntBad + 1;
        return(Le);
    end
    # a changed level must be read twice the same before it is taken
    if x != lastRaw
        y := modbusr(SH, 511, uint16); if (y != 0x8000, cntStale := cntStale + 1);
        modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA0);
        sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
        y := modbusr(SH, 511, uint16);
        cntQ := cntQ + 1; if (y = 0x8000, cntNone := cntNone + 1); if (y = 0x20FF, cntColl := cntColl + 1);
        if y != x
            cntBad := cntBad + 1;
            return(Le);
        end
        lastRaw := x;
    end
    return(if(x = 0, 0, linear(x, minLevel, 0.01, maxLevel, 1)));
else
    return(NaN);
end
Scrittura livello
var level := 0;
if(Le > 0, level := round(linear(Le, 0.01, minLevel, 1, maxLevel)));
modbusw(SH, 510, uint16, (ShortAddress << 8) + level );
Attributi di servizio
${xml_short_address}
ShortAddress
${xml_device_type}
var x := 0; var y := 0; var rx := 0; var s := ""; var i := 0;
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x99);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    x := modbusr(SH, 511, uint16);
    if (x < 0xFF, return("DT" + x));
    if x = 0xFF
        while i < 8
            modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA7);
            sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
            y := modbusr(SH, 511, uint16);
            if y < 0xFE
                s := if(s = "", "DT" + y, s + ", DT" + y);
                i := i + 1;
            else
                i := 8;
            end
        loop
        return(if(s = "", "MASK", s));
    end
end

return("--")
Physical Min Level
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x9A);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if (x <= 0xFE, return(round((x / 0xFE) * 100) + " %"));
end

return("--")
Max Level
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA1);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if (x <= 0xFE, return(round((x / 0xFE) * 100) + " %"));
end

return("--")
Min Level
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA2);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if (x <= 0xFE, return(round((x / 0xFE) * 100) + " %"));
end

return("--")
Power Up Level
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA3);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if (x <= 0xFE, return(round((x / 0xFE) * 100) + " %"));
end

return("--")
System Failure Level
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA4);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if (x <= 0xFE, return(round((x / 0xFE) * 100) + " %"));
end

return("--")
${xml_groups}
var x := 0; var rx := 0;
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xC0);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var g1 := modbusr(SH, 511, uint16);
    if (g1 > 0xFF, return("--")); 

    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xC1);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var g2 := modbusr(SH, 511, uint16);
    if (g2 > 0xFF, return("--")); 

    var ret := "";

    if (getbit(g1, 0), ret := ret + "0");
    if (getbit(g1, 1), if (ret = "", ret := "1", ret := ret + ",1"));
    if (getbit(g1, 2), if (ret = "", ret := "2", ret := ret + ",2"));
    if (getbit(g1, 3), if (ret = "", ret := "3", ret := ret + ",3"));
    if (getbit(g1, 4), if (ret = "", ret := "4", ret := ret + ",4"));
    if (getbit(g1, 5), if (ret = "", ret := "5", ret := ret + ",5"));
    if (getbit(g1, 6), if (ret = "", ret := "6", ret := ret + ",6"));
    if (getbit(g1, 7), if (ret = "", ret := "7", ret := ret + ",7"));
    if (getbit(g2, 0), if (ret = "", ret := "8", ret := ret + ",8"));
    if (getbit(g2, 1), if (ret = "", ret := "9", ret := ret + ",9"));
    if (getbit(g2, 2), if (ret = "", ret := "10", ret := ret + ",10"));
    if (getbit(g2, 3), if (ret = "", ret := "11", ret := ret + ",11"));
    if (getbit(g2, 4), if (ret = "", ret := "12", ret := ret + ",12"));
    if (getbit(g2, 5), if (ret = "", ret := "13", ret := ret + ",13"));
    if (getbit(g2, 6), if (ret = "", ret := "14", ret := ret + ",14"));
    if (getbit(g2, 7), if (ret = "", ret := "15", ret := ret + ",15"));

    if (ret = "", return("None"), return(ret));
else
    return("--");
end
DALI Status
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x90);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if x <= 0xFF
        var s := "";
        if (getbit(x, 0), s := if(s = "", "gear failure", s + ", gear failure"));
        if (getbit(x, 1), s := if(s = "", "lamp failure", s + ", lamp failure"));
        if (getbit(x, 2), s := if(s = "", "lamp on", s + ", lamp on"));
        if (getbit(x, 3), s := if(s = "", "limit error", s + ", limit error"));
        if (getbit(x, 4), s := if(s = "", "fade running", s + ", fade running"));
        if (getbit(x, 5), s := if(s = "", "reset state", s + ", reset state"));
        if (getbit(x, 6), s := if(s = "", "missing short address", s + ", missing short address"));
        if (getbit(x, 7), s := if(s = "", "power cycle", s + ", power cycle"));
        var ign := if((ignGear = 1) and (ignLamp = 1), "gear and lamp failure", if(ignGear = 1, "gear failure", if(ignLamp = 1, "lamp failure", "")));
        return(if(s = "", "OK", s) + " (0x" + tostring(x, "X2") + ")" + if(ign = "", "", "; not raised: " + ign + " reported since start"));
    end
end

return("--")
Fade
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA5);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if x <= 0xFF
        var t := getbits(x, 4, 4);
        var ret := if(t = 0, "off", t + " (" + round(sqrt(power(2, t)) * 5) / 10 + " s)");
        modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA8);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
        var e := modbusr(SH, 511, uint16);
        if (t = 0 and e <= 0xFF and e != 0, ret := "extended 0x" + tostring(e, "X2"));
        return("fade time " + ret + ", fade rate " + getbits(x, 0, 4));
    end
end

return("--")
DALI Version
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x97);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if x <= 0xFF
        return(if(x >= 8, "DALI-2 " + getbits(x, 2, 6) + "." + getbits(x, 0, 2), "DALI-1") + " (" + x + ")");
    end
end

return("--")
Bus statistics
return("since start: queries " + cntQ + ", stale answers read away " + cntStale + ", no answer " + cntNone + ", collisions " + cntColl + ", rejected levels " + cntBad)
Azioni di servizio
${xml_add_to_group}
Parametri: Group ID (0–15 grp)
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x60 + grp);
${xml_remove_from_group}
Parametri: Group ID (0–15 grp)
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x70 + grp);
${xml_reset_to_default_settings}
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x20);
${xml_set_startup_levels}
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x21);
sleep(10);
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x2c);
sleep(10);
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x2d);
Disable fading
modbusw(SH, 541, uint16, 0xA300);
sleep(100);
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x2E);
sleep(100);
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x30);
Gear 3 Dimmer Lettura e scrittura

Dispositivo di controllo DALI all'indirizzo breve 3 — dimmer TapHome mappato su DALI arc power 0–100 % tramite H:510 LAMP LEVEL (scrittura) e QUERY ACTUAL LEVEL tramite H:511 (lettura), delimitato dai propri MIN / MAX LEVEL del gear.

Registro: H:511 → H:510 UInt16 Unità: % numeric
Attributi di servizio
Indirizzo breveIndirizzo breve DALI (0–63) target di questo dispositivo — fissato al momento dell'importazione del template e utilizzato nel byte alto di ogni scrittura Modbus.
Device TypeByte device-type DALI restituito da QUERY DEVICE TYPE (0x99) — riporta DT0 (fluorescente), DT6 (driver LED), DT8 (colore / tunable white) ecc., o -- quando non c'è risposta.
Physical Min LevelLivello minimo di dimmerazione imposto dall'hardware riportato dal gear — letto da QUERY PHYSICAL MIN LEVEL (0x9A), in percentuale.
Max LevelDALI MAX LEVEL configurato — letto da QUERY MAX LEVEL (0xA1); utilizzato come limite superiore durante la scalatura di TapHome 0–100 % su DALI arc power.
Min LevelDALI MIN LEVEL configurato — letto da QUERY MIN LEVEL (0xA2); utilizzato come limite inferiore durante la scalatura di TapHome 0–100 % su DALI arc power.
Power Up LevelLuminosità ripristinata dopo il ripristino dell'alimentazione del bus DALI — letta da QUERY POWER ON LEVEL (0xA3).
System Failure LevelLuminosità adottata quando il bus DALI perde la comunicazione per più di 500 ms — letta da QUERY SYSTEM FAILURE LEVEL (0xA4).
GruppiElenco separato da virgole dei gruppi DALI (0–15) a cui appartiene il gear — decodificato da QUERY GROUPS 0-7 (0xC0) e QUERY GROUPS 8-15 (0xC1); mostra None o ad es. 0,3,7.
Support Lamp FailureSe la lampada / driver supporta il rilevamento dei guasti della lampada — Yes / No / --. Gestisce l'errore Lamp failure! nel readscript periodico.
Support Power FailureSe la lampada / driver supporta il rilevamento dei guasti di alimentazione — Yes / No / --. Gestisce l'errore Power failure! nel readscript periodico.
DALI Version
Bus statistics
Azioni di servizio
Add to GroupAggiunge questo gear a un gruppo DALI (0–15) tramite ADD TO GROUP (0x60+grp) — auto-ripetuto entro 100 ms come richiesto per i comandi di configurazione DALI.
Remove from GroupRimuove questo gear da un gruppo DALI (0–15) tramite REMOVE FROM GROUP (0x70+grp).
Reset to Default SettingsInvia DALI RESET (0x20) — ripristina ogni parametro NVM del gear (livelli max / min / power-on / system-failure, appartenenza al gruppo, scene) al valore predefinito del produttore.
Set Startup LevelsCattura l'arc power corrente e la memorizza come Power On Level e System Failure Level — sequenza STORE ACTUAL LEVEL IN DTR (0x21) → STORE DTR AS POWER ON LEVEL (0x2C) → STORE DTR AS SYSTEM FAILURE LEVEL (0x2D).
Disable fading

Gear 3

Lettura (modulo)
var x := 0; var rx := 0; var y := 0;
if Status > 0
    Status := Status - 1;
    adderror(3, "Gear not responding!");
    return(0);
end

# checkStatus: ReadLevel resets it while the gear answers; statusPoll: QUERY STATUS at least once per 60 runs
checkStatus := checkStatus - 1;
statusPoll := statusPoll - 1;
if checkStatus < 1 or statusPoll < 1
    # an unread answer left in the gateway would be taken for this query: read it away and count it
    x := modbusr(SH, 511, uint16); if (x != 0x8000, cntStale := cntStale + 1);
    modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x90);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    x := modbusr(SH, 511, uint16);
    cntQ := cntQ + 1; if (x = 0x8000, cntNone := cntNone + 1); if (x = 0x20FF, cntColl := cntColl + 1);
    # a single lost answer happens on DALI: ask once more before declaring the gear missing
    if x = 0x8000
        x := modbusr(SH, 511, uint16); if (x != 0x8000, cntStale := cntStale + 1);
        modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x90);
        sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
        x := modbusr(SH, 511, uint16);
        cntQ := cntQ + 1; if (x = 0x8000, cntNone := cntNone + 1); if (x = 0x20FF, cntColl := cntColl + 1);
    end
    if x <= 0xFF
        # a changed failure bit must be read twice the same before it is taken
        if statusSeen = 1 and getbits(x, 0, 2) != getbits(gearStatus, 0, 2)
            y := modbusr(SH, 511, uint16); if (y != 0x8000, cntStale := cntStale + 1);
            modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x90);
            sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
            y := modbusr(SH, 511, uint16);
            cntQ := cntQ + 1; if (y = 0x8000, cntNone := cntNone + 1); if (y = 0x20FF, cntColl := cntColl + 1);
            if y != x
                cntBad := cntBad + 1;
                x := gearStatus;
            end
        end
        if statusSeen = 0
            ignGear := getbit(x, 0);
            ignLamp := getbit(x, 1);
            statusSeen := 1;
        end
        # a bit that clears ends its ignore, so a later failure is raised
        if (getbit(x, 0) = 0, ignGear := 0);
        if (getbit(x, 1) = 0, ignLamp := 0);
        gearStatus := x;
        checkStatus := 60;
        statusPoll := 60;
    else
        if x = 0x8000
            Status := RANDINT(10, 60);
            adderror(3, "Gear not responding!");
            return(0);
        end
    end
end

# messages last one run only, so they are raised from the stored status on every run
if ((getbit(gearStatus, 0) = 1) and (ignGear = 0), adderror(1, "Control gear failure!"));
if ((getbit(gearStatus, 1) = 1) and (ignLamp = 0), adderror(2, "Lamp failure!"));
Inizializzazione
var x := 0; var rx := 0;
# QUERY STATUS 0x90: every reply byte proves the gear is present; 0x8000 = no answer, 0x20FF = bus collision
# an unread answer left in the gateway would be taken for this query: read it away and count it
x := modbusr(SH, 511, uint16); if (x != 0x8000, cntStale := cntStale + 1);
modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x90);
sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
x := modbusr(SH, 511, uint16);
cntQ := cntQ + 1; if (x = 0x8000, cntNone := cntNone + 1); if (x = 0x20FF, cntColl := cntColl + 1);
statusSeen := 0;
if x <= 0xFF
    # failure bits a gear reports from its first answer are its permanent state, not an event: shown, not raised
    gearStatus := x;
    ignGear := getbit(x, 0);
    ignLamp := getbit(x, 1);
    statusSeen := 1;
    Status := 0;
else
    Status := RANDINT(1, 60);
end

if Status = 0
    x := modbusr(SH, 511, uint16); if (x != 0x8000, cntStale := cntStale + 1);
    modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA2);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    x := modbusr(SH, 511, uint16);
    cntQ := cntQ + 1; if (x = 0x8000, cntNone := cntNone + 1); if (x = 0x20FF, cntColl := cntColl + 1);
    if (x <= 0xFE, minLevel := x);

    x := modbusr(SH, 511, uint16); if (x != 0x8000, cntStale := cntStale + 1);
    modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA1);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    x := modbusr(SH, 511, uint16);
    cntQ := cntQ + 1; if (x = 0x8000, cntNone := cntNone + 1); if (x = 0x20FF, cntColl := cntColl + 1);
    if (x <= 0xFE, maxLevel := x);
end
Lettura livello
var x := 0; var rx := 0; var y := 0;
if Status = 0
    if minLevel = 0
        # an unread answer left in the gateway would be taken for this query: read it away and count it
        x := modbusr(SH, 511, uint16); if (x != 0x8000, cntStale := cntStale + 1);
        modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA2);
        sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
        x := modbusr(SH, 511, uint16);
        cntQ := cntQ + 1; if (x = 0x8000, cntNone := cntNone + 1); if (x = 0x20FF, cntColl := cntColl + 1);
        if (x <= 0xFE, minLevel := x);
    end
    x := modbusr(SH, 511, uint16); if (x != 0x8000, cntStale := cntStale + 1);
    modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA0);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    x := modbusr(SH, 511, uint16);
    cntQ := cntQ + 1; if (x = 0x8000, cntNone := cntNone + 1); if (x = 0x20FF, cntColl := cntColl + 1);
    if (x != 0x8000 or rx, checkStatus := 60);
    # 0xFF = MASK, 0x20FF = collision, 0x8000 = no answer: keep the last level instead of a phantom value
    if x > 0xFE
        return(Le);
    end
    # an actual level is 0 or between the gear's min and max: anything else is not this gear's answer
    if x > 0 and x < minLevel
        cntBad := cntBad + 1;
        return(Le);
    end
    # a changed level must be read twice the same before it is taken
    if x != lastRaw
        y := modbusr(SH, 511, uint16); if (y != 0x8000, cntStale := cntStale + 1);
        modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA0);
        sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
        y := modbusr(SH, 511, uint16);
        cntQ := cntQ + 1; if (y = 0x8000, cntNone := cntNone + 1); if (y = 0x20FF, cntColl := cntColl + 1);
        if y != x
            cntBad := cntBad + 1;
            return(Le);
        end
        lastRaw := x;
    end
    return(if(x = 0, 0, linear(x, minLevel, 0.01, maxLevel, 1)));
else
    return(NaN);
end
Scrittura livello
var level := 0;
if(Le > 0, level := round(linear(Le, 0.01, minLevel, 1, maxLevel)));
modbusw(SH, 510, uint16, (ShortAddress << 8) + level );
Attributi di servizio
${xml_short_address}
ShortAddress
${xml_device_type}
var x := 0; var y := 0; var rx := 0; var s := ""; var i := 0;
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x99);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    x := modbusr(SH, 511, uint16);
    if (x < 0xFF, return("DT" + x));
    if x = 0xFF
        while i < 8
            modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA7);
            sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
            y := modbusr(SH, 511, uint16);
            if y < 0xFE
                s := if(s = "", "DT" + y, s + ", DT" + y);
                i := i + 1;
            else
                i := 8;
            end
        loop
        return(if(s = "", "MASK", s));
    end
end

return("--")
Physical Min Level
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x9A);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if (x <= 0xFE, return(round((x / 0xFE) * 100) + " %"));
end

return("--")
Max Level
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA1);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if (x <= 0xFE, return(round((x / 0xFE) * 100) + " %"));
end

return("--")
Min Level
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA2);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if (x <= 0xFE, return(round((x / 0xFE) * 100) + " %"));
end

return("--")
Power Up Level
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA3);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if (x <= 0xFE, return(round((x / 0xFE) * 100) + " %"));
end

return("--")
System Failure Level
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA4);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if (x <= 0xFE, return(round((x / 0xFE) * 100) + " %"));
end

return("--")
${xml_groups}
var x := 0; var rx := 0;
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xC0);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var g1 := modbusr(SH, 511, uint16);
    if (g1 > 0xFF, return("--")); 

    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xC1);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var g2 := modbusr(SH, 511, uint16);
    if (g2 > 0xFF, return("--")); 

    var ret := "";

    if (getbit(g1, 0), ret := ret + "0");
    if (getbit(g1, 1), if (ret = "", ret := "1", ret := ret + ",1"));
    if (getbit(g1, 2), if (ret = "", ret := "2", ret := ret + ",2"));
    if (getbit(g1, 3), if (ret = "", ret := "3", ret := ret + ",3"));
    if (getbit(g1, 4), if (ret = "", ret := "4", ret := ret + ",4"));
    if (getbit(g1, 5), if (ret = "", ret := "5", ret := ret + ",5"));
    if (getbit(g1, 6), if (ret = "", ret := "6", ret := ret + ",6"));
    if (getbit(g1, 7), if (ret = "", ret := "7", ret := ret + ",7"));
    if (getbit(g2, 0), if (ret = "", ret := "8", ret := ret + ",8"));
    if (getbit(g2, 1), if (ret = "", ret := "9", ret := ret + ",9"));
    if (getbit(g2, 2), if (ret = "", ret := "10", ret := ret + ",10"));
    if (getbit(g2, 3), if (ret = "", ret := "11", ret := ret + ",11"));
    if (getbit(g2, 4), if (ret = "", ret := "12", ret := ret + ",12"));
    if (getbit(g2, 5), if (ret = "", ret := "13", ret := ret + ",13"));
    if (getbit(g2, 6), if (ret = "", ret := "14", ret := ret + ",14"));
    if (getbit(g2, 7), if (ret = "", ret := "15", ret := ret + ",15"));

    if (ret = "", return("None"), return(ret));
else
    return("--");
end
DALI Status
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x90);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if x <= 0xFF
        var s := "";
        if (getbit(x, 0), s := if(s = "", "gear failure", s + ", gear failure"));
        if (getbit(x, 1), s := if(s = "", "lamp failure", s + ", lamp failure"));
        if (getbit(x, 2), s := if(s = "", "lamp on", s + ", lamp on"));
        if (getbit(x, 3), s := if(s = "", "limit error", s + ", limit error"));
        if (getbit(x, 4), s := if(s = "", "fade running", s + ", fade running"));
        if (getbit(x, 5), s := if(s = "", "reset state", s + ", reset state"));
        if (getbit(x, 6), s := if(s = "", "missing short address", s + ", missing short address"));
        if (getbit(x, 7), s := if(s = "", "power cycle", s + ", power cycle"));
        var ign := if((ignGear = 1) and (ignLamp = 1), "gear and lamp failure", if(ignGear = 1, "gear failure", if(ignLamp = 1, "lamp failure", "")));
        return(if(s = "", "OK", s) + " (0x" + tostring(x, "X2") + ")" + if(ign = "", "", "; not raised: " + ign + " reported since start"));
    end
end

return("--")
Fade
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA5);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if x <= 0xFF
        var t := getbits(x, 4, 4);
        var ret := if(t = 0, "off", t + " (" + round(sqrt(power(2, t)) * 5) / 10 + " s)");
        modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA8);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
        var e := modbusr(SH, 511, uint16);
        if (t = 0 and e <= 0xFF and e != 0, ret := "extended 0x" + tostring(e, "X2"));
        return("fade time " + ret + ", fade rate " + getbits(x, 0, 4));
    end
end

return("--")
DALI Version
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x97);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if x <= 0xFF
        return(if(x >= 8, "DALI-2 " + getbits(x, 2, 6) + "." + getbits(x, 0, 2), "DALI-1") + " (" + x + ")");
    end
end

return("--")
Bus statistics
return("since start: queries " + cntQ + ", stale answers read away " + cntStale + ", no answer " + cntNone + ", collisions " + cntColl + ", rejected levels " + cntBad)
Azioni di servizio
${xml_add_to_group}
Parametri: Group ID (0–15 grp)
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x60 + grp);
${xml_remove_from_group}
Parametri: Group ID (0–15 grp)
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x70 + grp);
${xml_reset_to_default_settings}
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x20);
${xml_set_startup_levels}
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x21);
sleep(10);
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x2c);
sleep(10);
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x2d);
Disable fading
modbusw(SH, 541, uint16, 0xA300);
sleep(100);
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x2E);
sleep(100);
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x30);
Gear 4 Dimmer Lettura e scrittura

Dispositivo di controllo DALI all'indirizzo breve 4 — dimmer TapHome mappato su DALI arc power 0–100 % tramite H:510 LAMP LEVEL (scrittura) e QUERY ACTUAL LEVEL tramite H:511 (lettura), delimitato dai propri MIN / MAX LEVEL del gear.

Registro: H:511 → H:510 UInt16 Unità: % numeric
Attributi di servizio
Indirizzo breveIndirizzo breve DALI (0–63) target di questo dispositivo — fissato al momento dell'importazione del template e utilizzato nel byte alto di ogni scrittura Modbus.
Device TypeByte device-type DALI restituito da QUERY DEVICE TYPE (0x99) — riporta DT0 (fluorescente), DT6 (driver LED), DT8 (colore / tunable white) ecc., o -- quando non c'è risposta.
Physical Min LevelLivello minimo di dimmerazione imposto dall'hardware riportato dal gear — letto da QUERY PHYSICAL MIN LEVEL (0x9A), in percentuale.
Max LevelDALI MAX LEVEL configurato — letto da QUERY MAX LEVEL (0xA1); utilizzato come limite superiore durante la scalatura di TapHome 0–100 % su DALI arc power.
Min LevelDALI MIN LEVEL configurato — letto da QUERY MIN LEVEL (0xA2); utilizzato come limite inferiore durante la scalatura di TapHome 0–100 % su DALI arc power.
Power Up LevelLuminosità ripristinata dopo il ripristino dell'alimentazione del bus DALI — letta da QUERY POWER ON LEVEL (0xA3).
System Failure LevelLuminosità adottata quando il bus DALI perde la comunicazione per più di 500 ms — letta da QUERY SYSTEM FAILURE LEVEL (0xA4).
GruppiElenco separato da virgole dei gruppi DALI (0–15) a cui appartiene il gear — decodificato da QUERY GROUPS 0-7 (0xC0) e QUERY GROUPS 8-15 (0xC1); mostra None o ad es. 0,3,7.
Support Lamp FailureSe la lampada / driver supporta il rilevamento dei guasti della lampada — Yes / No / --. Gestisce l'errore Lamp failure! nel readscript periodico.
Support Power FailureSe la lampada / driver supporta il rilevamento dei guasti di alimentazione — Yes / No / --. Gestisce l'errore Power failure! nel readscript periodico.
DALI Version
Bus statistics
Azioni di servizio
Add to GroupAggiunge questo gear a un gruppo DALI (0–15) tramite ADD TO GROUP (0x60+grp) — auto-ripetuto entro 100 ms come richiesto per i comandi di configurazione DALI.
Remove from GroupRimuove questo gear da un gruppo DALI (0–15) tramite REMOVE FROM GROUP (0x70+grp).
Reset to Default SettingsInvia DALI RESET (0x20) — ripristina ogni parametro NVM del gear (livelli max / min / power-on / system-failure, appartenenza al gruppo, scene) al valore predefinito del produttore.
Set Startup LevelsCattura l'arc power corrente e la memorizza come Power On Level e System Failure Level — sequenza STORE ACTUAL LEVEL IN DTR (0x21) → STORE DTR AS POWER ON LEVEL (0x2C) → STORE DTR AS SYSTEM FAILURE LEVEL (0x2D).
Disable fading

Gear 4

Lettura (modulo)
var x := 0; var rx := 0; var y := 0;
if Status > 0
    Status := Status - 1;
    adderror(3, "Gear not responding!");
    return(0);
end

# checkStatus: ReadLevel resets it while the gear answers; statusPoll: QUERY STATUS at least once per 60 runs
checkStatus := checkStatus - 1;
statusPoll := statusPoll - 1;
if checkStatus < 1 or statusPoll < 1
    # an unread answer left in the gateway would be taken for this query: read it away and count it
    x := modbusr(SH, 511, uint16); if (x != 0x8000, cntStale := cntStale + 1);
    modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x90);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    x := modbusr(SH, 511, uint16);
    cntQ := cntQ + 1; if (x = 0x8000, cntNone := cntNone + 1); if (x = 0x20FF, cntColl := cntColl + 1);
    # a single lost answer happens on DALI: ask once more before declaring the gear missing
    if x = 0x8000
        x := modbusr(SH, 511, uint16); if (x != 0x8000, cntStale := cntStale + 1);
        modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x90);
        sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
        x := modbusr(SH, 511, uint16);
        cntQ := cntQ + 1; if (x = 0x8000, cntNone := cntNone + 1); if (x = 0x20FF, cntColl := cntColl + 1);
    end
    if x <= 0xFF
        # a changed failure bit must be read twice the same before it is taken
        if statusSeen = 1 and getbits(x, 0, 2) != getbits(gearStatus, 0, 2)
            y := modbusr(SH, 511, uint16); if (y != 0x8000, cntStale := cntStale + 1);
            modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x90);
            sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
            y := modbusr(SH, 511, uint16);
            cntQ := cntQ + 1; if (y = 0x8000, cntNone := cntNone + 1); if (y = 0x20FF, cntColl := cntColl + 1);
            if y != x
                cntBad := cntBad + 1;
                x := gearStatus;
            end
        end
        if statusSeen = 0
            ignGear := getbit(x, 0);
            ignLamp := getbit(x, 1);
            statusSeen := 1;
        end
        # a bit that clears ends its ignore, so a later failure is raised
        if (getbit(x, 0) = 0, ignGear := 0);
        if (getbit(x, 1) = 0, ignLamp := 0);
        gearStatus := x;
        checkStatus := 60;
        statusPoll := 60;
    else
        if x = 0x8000
            Status := RANDINT(10, 60);
            adderror(3, "Gear not responding!");
            return(0);
        end
    end
end

# messages last one run only, so they are raised from the stored status on every run
if ((getbit(gearStatus, 0) = 1) and (ignGear = 0), adderror(1, "Control gear failure!"));
if ((getbit(gearStatus, 1) = 1) and (ignLamp = 0), adderror(2, "Lamp failure!"));
Inizializzazione
var x := 0; var rx := 0;
# QUERY STATUS 0x90: every reply byte proves the gear is present; 0x8000 = no answer, 0x20FF = bus collision
# an unread answer left in the gateway would be taken for this query: read it away and count it
x := modbusr(SH, 511, uint16); if (x != 0x8000, cntStale := cntStale + 1);
modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x90);
sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
x := modbusr(SH, 511, uint16);
cntQ := cntQ + 1; if (x = 0x8000, cntNone := cntNone + 1); if (x = 0x20FF, cntColl := cntColl + 1);
statusSeen := 0;
if x <= 0xFF
    # failure bits a gear reports from its first answer are its permanent state, not an event: shown, not raised
    gearStatus := x;
    ignGear := getbit(x, 0);
    ignLamp := getbit(x, 1);
    statusSeen := 1;
    Status := 0;
else
    Status := RANDINT(1, 60);
end

if Status = 0
    x := modbusr(SH, 511, uint16); if (x != 0x8000, cntStale := cntStale + 1);
    modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA2);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    x := modbusr(SH, 511, uint16);
    cntQ := cntQ + 1; if (x = 0x8000, cntNone := cntNone + 1); if (x = 0x20FF, cntColl := cntColl + 1);
    if (x <= 0xFE, minLevel := x);

    x := modbusr(SH, 511, uint16); if (x != 0x8000, cntStale := cntStale + 1);
    modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA1);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    x := modbusr(SH, 511, uint16);
    cntQ := cntQ + 1; if (x = 0x8000, cntNone := cntNone + 1); if (x = 0x20FF, cntColl := cntColl + 1);
    if (x <= 0xFE, maxLevel := x);
end
Lettura livello
var x := 0; var rx := 0; var y := 0;
if Status = 0
    if minLevel = 0
        # an unread answer left in the gateway would be taken for this query: read it away and count it
        x := modbusr(SH, 511, uint16); if (x != 0x8000, cntStale := cntStale + 1);
        modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA2);
        sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
        x := modbusr(SH, 511, uint16);
        cntQ := cntQ + 1; if (x = 0x8000, cntNone := cntNone + 1); if (x = 0x20FF, cntColl := cntColl + 1);
        if (x <= 0xFE, minLevel := x);
    end
    x := modbusr(SH, 511, uint16); if (x != 0x8000, cntStale := cntStale + 1);
    modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA0);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    x := modbusr(SH, 511, uint16);
    cntQ := cntQ + 1; if (x = 0x8000, cntNone := cntNone + 1); if (x = 0x20FF, cntColl := cntColl + 1);
    if (x != 0x8000 or rx, checkStatus := 60);
    # 0xFF = MASK, 0x20FF = collision, 0x8000 = no answer: keep the last level instead of a phantom value
    if x > 0xFE
        return(Le);
    end
    # an actual level is 0 or between the gear's min and max: anything else is not this gear's answer
    if x > 0 and x < minLevel
        cntBad := cntBad + 1;
        return(Le);
    end
    # a changed level must be read twice the same before it is taken
    if x != lastRaw
        y := modbusr(SH, 511, uint16); if (y != 0x8000, cntStale := cntStale + 1);
        modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA0);
        sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
        y := modbusr(SH, 511, uint16);
        cntQ := cntQ + 1; if (y = 0x8000, cntNone := cntNone + 1); if (y = 0x20FF, cntColl := cntColl + 1);
        if y != x
            cntBad := cntBad + 1;
            return(Le);
        end
        lastRaw := x;
    end
    return(if(x = 0, 0, linear(x, minLevel, 0.01, maxLevel, 1)));
else
    return(NaN);
end
Scrittura livello
var level := 0;
if(Le > 0, level := round(linear(Le, 0.01, minLevel, 1, maxLevel)));
modbusw(SH, 510, uint16, (ShortAddress << 8) + level );
Attributi di servizio
${xml_short_address}
ShortAddress
${xml_device_type}
var x := 0; var y := 0; var rx := 0; var s := ""; var i := 0;
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x99);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    x := modbusr(SH, 511, uint16);
    if (x < 0xFF, return("DT" + x));
    if x = 0xFF
        while i < 8
            modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA7);
            sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
            y := modbusr(SH, 511, uint16);
            if y < 0xFE
                s := if(s = "", "DT" + y, s + ", DT" + y);
                i := i + 1;
            else
                i := 8;
            end
        loop
        return(if(s = "", "MASK", s));
    end
end

return("--")
Physical Min Level
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x9A);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if (x <= 0xFE, return(round((x / 0xFE) * 100) + " %"));
end

return("--")
Max Level
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA1);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if (x <= 0xFE, return(round((x / 0xFE) * 100) + " %"));
end

return("--")
Min Level
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA2);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if (x <= 0xFE, return(round((x / 0xFE) * 100) + " %"));
end

return("--")
Power Up Level
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA3);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if (x <= 0xFE, return(round((x / 0xFE) * 100) + " %"));
end

return("--")
System Failure Level
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA4);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if (x <= 0xFE, return(round((x / 0xFE) * 100) + " %"));
end

return("--")
${xml_groups}
var x := 0; var rx := 0;
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xC0);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var g1 := modbusr(SH, 511, uint16);
    if (g1 > 0xFF, return("--")); 

    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xC1);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var g2 := modbusr(SH, 511, uint16);
    if (g2 > 0xFF, return("--")); 

    var ret := "";

    if (getbit(g1, 0), ret := ret + "0");
    if (getbit(g1, 1), if (ret = "", ret := "1", ret := ret + ",1"));
    if (getbit(g1, 2), if (ret = "", ret := "2", ret := ret + ",2"));
    if (getbit(g1, 3), if (ret = "", ret := "3", ret := ret + ",3"));
    if (getbit(g1, 4), if (ret = "", ret := "4", ret := ret + ",4"));
    if (getbit(g1, 5), if (ret = "", ret := "5", ret := ret + ",5"));
    if (getbit(g1, 6), if (ret = "", ret := "6", ret := ret + ",6"));
    if (getbit(g1, 7), if (ret = "", ret := "7", ret := ret + ",7"));
    if (getbit(g2, 0), if (ret = "", ret := "8", ret := ret + ",8"));
    if (getbit(g2, 1), if (ret = "", ret := "9", ret := ret + ",9"));
    if (getbit(g2, 2), if (ret = "", ret := "10", ret := ret + ",10"));
    if (getbit(g2, 3), if (ret = "", ret := "11", ret := ret + ",11"));
    if (getbit(g2, 4), if (ret = "", ret := "12", ret := ret + ",12"));
    if (getbit(g2, 5), if (ret = "", ret := "13", ret := ret + ",13"));
    if (getbit(g2, 6), if (ret = "", ret := "14", ret := ret + ",14"));
    if (getbit(g2, 7), if (ret = "", ret := "15", ret := ret + ",15"));

    if (ret = "", return("None"), return(ret));
else
    return("--");
end
DALI Status
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x90);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if x <= 0xFF
        var s := "";
        if (getbit(x, 0), s := if(s = "", "gear failure", s + ", gear failure"));
        if (getbit(x, 1), s := if(s = "", "lamp failure", s + ", lamp failure"));
        if (getbit(x, 2), s := if(s = "", "lamp on", s + ", lamp on"));
        if (getbit(x, 3), s := if(s = "", "limit error", s + ", limit error"));
        if (getbit(x, 4), s := if(s = "", "fade running", s + ", fade running"));
        if (getbit(x, 5), s := if(s = "", "reset state", s + ", reset state"));
        if (getbit(x, 6), s := if(s = "", "missing short address", s + ", missing short address"));
        if (getbit(x, 7), s := if(s = "", "power cycle", s + ", power cycle"));
        var ign := if((ignGear = 1) and (ignLamp = 1), "gear and lamp failure", if(ignGear = 1, "gear failure", if(ignLamp = 1, "lamp failure", "")));
        return(if(s = "", "OK", s) + " (0x" + tostring(x, "X2") + ")" + if(ign = "", "", "; not raised: " + ign + " reported since start"));
    end
end

return("--")
Fade
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA5);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if x <= 0xFF
        var t := getbits(x, 4, 4);
        var ret := if(t = 0, "off", t + " (" + round(sqrt(power(2, t)) * 5) / 10 + " s)");
        modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA8);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
        var e := modbusr(SH, 511, uint16);
        if (t = 0 and e <= 0xFF and e != 0, ret := "extended 0x" + tostring(e, "X2"));
        return("fade time " + ret + ", fade rate " + getbits(x, 0, 4));
    end
end

return("--")
DALI Version
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x97);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if x <= 0xFF
        return(if(x >= 8, "DALI-2 " + getbits(x, 2, 6) + "." + getbits(x, 0, 2), "DALI-1") + " (" + x + ")");
    end
end

return("--")
Bus statistics
return("since start: queries " + cntQ + ", stale answers read away " + cntStale + ", no answer " + cntNone + ", collisions " + cntColl + ", rejected levels " + cntBad)
Azioni di servizio
${xml_add_to_group}
Parametri: Group ID (0–15 grp)
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x60 + grp);
${xml_remove_from_group}
Parametri: Group ID (0–15 grp)
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x70 + grp);
${xml_reset_to_default_settings}
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x20);
${xml_set_startup_levels}
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x21);
sleep(10);
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x2c);
sleep(10);
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x2d);
Disable fading
modbusw(SH, 541, uint16, 0xA300);
sleep(100);
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x2E);
sleep(100);
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x30);
Gear 5 Dimmer Lettura e scrittura

Dispositivo di controllo DALI all'indirizzo breve 5 — dimmer TapHome mappato su DALI arc power 0–100 % tramite H:510 LAMP LEVEL (scrittura) e QUERY ACTUAL LEVEL tramite H:511 (lettura), delimitato dai propri MIN / MAX LEVEL del gear.

Registro: H:511 → H:510 UInt16 Unità: % numeric
Attributi di servizio
Indirizzo breveIndirizzo breve DALI (0–63) target di questo dispositivo — fissato al momento dell'importazione del template e utilizzato nel byte alto di ogni scrittura Modbus.
Device TypeByte device-type DALI restituito da QUERY DEVICE TYPE (0x99) — riporta DT0 (fluorescente), DT6 (driver LED), DT8 (colore / tunable white) ecc., o -- quando non c'è risposta.
Physical Min LevelLivello minimo di dimmerazione imposto dall'hardware riportato dal gear — letto da QUERY PHYSICAL MIN LEVEL (0x9A), in percentuale.
Max LevelDALI MAX LEVEL configurato — letto da QUERY MAX LEVEL (0xA1); utilizzato come limite superiore durante la scalatura di TapHome 0–100 % su DALI arc power.
Min LevelDALI MIN LEVEL configurato — letto da QUERY MIN LEVEL (0xA2); utilizzato come limite inferiore durante la scalatura di TapHome 0–100 % su DALI arc power.
Power Up LevelLuminosità ripristinata dopo il ripristino dell'alimentazione del bus DALI — letta da QUERY POWER ON LEVEL (0xA3).
System Failure LevelLuminosità adottata quando il bus DALI perde la comunicazione per più di 500 ms — letta da QUERY SYSTEM FAILURE LEVEL (0xA4).
GruppiElenco separato da virgole dei gruppi DALI (0–15) a cui appartiene il gear — decodificato da QUERY GROUPS 0-7 (0xC0) e QUERY GROUPS 8-15 (0xC1); mostra None o ad es. 0,3,7.
Support Lamp FailureSe la lampada / driver supporta il rilevamento dei guasti della lampada — Yes / No / --. Gestisce l'errore Lamp failure! nel readscript periodico.
Support Power FailureSe la lampada / driver supporta il rilevamento dei guasti di alimentazione — Yes / No / --. Gestisce l'errore Power failure! nel readscript periodico.
DALI Version
Bus statistics
Azioni di servizio
Add to GroupAggiunge questo gear a un gruppo DALI (0–15) tramite ADD TO GROUP (0x60+grp) — auto-ripetuto entro 100 ms come richiesto per i comandi di configurazione DALI.
Remove from GroupRimuove questo gear da un gruppo DALI (0–15) tramite REMOVE FROM GROUP (0x70+grp).
Reset to Default SettingsInvia DALI RESET (0x20) — ripristina ogni parametro NVM del gear (livelli max / min / power-on / system-failure, appartenenza al gruppo, scene) al valore predefinito del produttore.
Set Startup LevelsCattura l'arc power corrente e la memorizza come Power On Level e System Failure Level — sequenza STORE ACTUAL LEVEL IN DTR (0x21) → STORE DTR AS POWER ON LEVEL (0x2C) → STORE DTR AS SYSTEM FAILURE LEVEL (0x2D).
Disable fading

Gear 5

Lettura (modulo)
var x := 0; var rx := 0; var y := 0;
if Status > 0
    Status := Status - 1;
    adderror(3, "Gear not responding!");
    return(0);
end

# checkStatus: ReadLevel resets it while the gear answers; statusPoll: QUERY STATUS at least once per 60 runs
checkStatus := checkStatus - 1;
statusPoll := statusPoll - 1;
if checkStatus < 1 or statusPoll < 1
    # an unread answer left in the gateway would be taken for this query: read it away and count it
    x := modbusr(SH, 511, uint16); if (x != 0x8000, cntStale := cntStale + 1);
    modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x90);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    x := modbusr(SH, 511, uint16);
    cntQ := cntQ + 1; if (x = 0x8000, cntNone := cntNone + 1); if (x = 0x20FF, cntColl := cntColl + 1);
    # a single lost answer happens on DALI: ask once more before declaring the gear missing
    if x = 0x8000
        x := modbusr(SH, 511, uint16); if (x != 0x8000, cntStale := cntStale + 1);
        modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x90);
        sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
        x := modbusr(SH, 511, uint16);
        cntQ := cntQ + 1; if (x = 0x8000, cntNone := cntNone + 1); if (x = 0x20FF, cntColl := cntColl + 1);
    end
    if x <= 0xFF
        # a changed failure bit must be read twice the same before it is taken
        if statusSeen = 1 and getbits(x, 0, 2) != getbits(gearStatus, 0, 2)
            y := modbusr(SH, 511, uint16); if (y != 0x8000, cntStale := cntStale + 1);
            modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x90);
            sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
            y := modbusr(SH, 511, uint16);
            cntQ := cntQ + 1; if (y = 0x8000, cntNone := cntNone + 1); if (y = 0x20FF, cntColl := cntColl + 1);
            if y != x
                cntBad := cntBad + 1;
                x := gearStatus;
            end
        end
        if statusSeen = 0
            ignGear := getbit(x, 0);
            ignLamp := getbit(x, 1);
            statusSeen := 1;
        end
        # a bit that clears ends its ignore, so a later failure is raised
        if (getbit(x, 0) = 0, ignGear := 0);
        if (getbit(x, 1) = 0, ignLamp := 0);
        gearStatus := x;
        checkStatus := 60;
        statusPoll := 60;
    else
        if x = 0x8000
            Status := RANDINT(10, 60);
            adderror(3, "Gear not responding!");
            return(0);
        end
    end
end

# messages last one run only, so they are raised from the stored status on every run
if ((getbit(gearStatus, 0) = 1) and (ignGear = 0), adderror(1, "Control gear failure!"));
if ((getbit(gearStatus, 1) = 1) and (ignLamp = 0), adderror(2, "Lamp failure!"));
Inizializzazione
var x := 0; var rx := 0;
# QUERY STATUS 0x90: every reply byte proves the gear is present; 0x8000 = no answer, 0x20FF = bus collision
# an unread answer left in the gateway would be taken for this query: read it away and count it
x := modbusr(SH, 511, uint16); if (x != 0x8000, cntStale := cntStale + 1);
modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x90);
sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
x := modbusr(SH, 511, uint16);
cntQ := cntQ + 1; if (x = 0x8000, cntNone := cntNone + 1); if (x = 0x20FF, cntColl := cntColl + 1);
statusSeen := 0;
if x <= 0xFF
    # failure bits a gear reports from its first answer are its permanent state, not an event: shown, not raised
    gearStatus := x;
    ignGear := getbit(x, 0);
    ignLamp := getbit(x, 1);
    statusSeen := 1;
    Status := 0;
else
    Status := RANDINT(1, 60);
end

if Status = 0
    x := modbusr(SH, 511, uint16); if (x != 0x8000, cntStale := cntStale + 1);
    modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA2);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    x := modbusr(SH, 511, uint16);
    cntQ := cntQ + 1; if (x = 0x8000, cntNone := cntNone + 1); if (x = 0x20FF, cntColl := cntColl + 1);
    if (x <= 0xFE, minLevel := x);

    x := modbusr(SH, 511, uint16); if (x != 0x8000, cntStale := cntStale + 1);
    modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA1);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    x := modbusr(SH, 511, uint16);
    cntQ := cntQ + 1; if (x = 0x8000, cntNone := cntNone + 1); if (x = 0x20FF, cntColl := cntColl + 1);
    if (x <= 0xFE, maxLevel := x);
end
Lettura livello
var x := 0; var rx := 0; var y := 0;
if Status = 0
    if minLevel = 0
        # an unread answer left in the gateway would be taken for this query: read it away and count it
        x := modbusr(SH, 511, uint16); if (x != 0x8000, cntStale := cntStale + 1);
        modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA2);
        sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
        x := modbusr(SH, 511, uint16);
        cntQ := cntQ + 1; if (x = 0x8000, cntNone := cntNone + 1); if (x = 0x20FF, cntColl := cntColl + 1);
        if (x <= 0xFE, minLevel := x);
    end
    x := modbusr(SH, 511, uint16); if (x != 0x8000, cntStale := cntStale + 1);
    modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA0);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    x := modbusr(SH, 511, uint16);
    cntQ := cntQ + 1; if (x = 0x8000, cntNone := cntNone + 1); if (x = 0x20FF, cntColl := cntColl + 1);
    if (x != 0x8000 or rx, checkStatus := 60);
    # 0xFF = MASK, 0x20FF = collision, 0x8000 = no answer: keep the last level instead of a phantom value
    if x > 0xFE
        return(Le);
    end
    # an actual level is 0 or between the gear's min and max: anything else is not this gear's answer
    if x > 0 and x < minLevel
        cntBad := cntBad + 1;
        return(Le);
    end
    # a changed level must be read twice the same before it is taken
    if x != lastRaw
        y := modbusr(SH, 511, uint16); if (y != 0x8000, cntStale := cntStale + 1);
        modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA0);
        sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
        y := modbusr(SH, 511, uint16);
        cntQ := cntQ + 1; if (y = 0x8000, cntNone := cntNone + 1); if (y = 0x20FF, cntColl := cntColl + 1);
        if y != x
            cntBad := cntBad + 1;
            return(Le);
        end
        lastRaw := x;
    end
    return(if(x = 0, 0, linear(x, minLevel, 0.01, maxLevel, 1)));
else
    return(NaN);
end
Scrittura livello
var level := 0;
if(Le > 0, level := round(linear(Le, 0.01, minLevel, 1, maxLevel)));
modbusw(SH, 510, uint16, (ShortAddress << 8) + level );
Attributi di servizio
${xml_short_address}
ShortAddress
${xml_device_type}
var x := 0; var y := 0; var rx := 0; var s := ""; var i := 0;
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x99);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    x := modbusr(SH, 511, uint16);
    if (x < 0xFF, return("DT" + x));
    if x = 0xFF
        while i < 8
            modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA7);
            sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
            y := modbusr(SH, 511, uint16);
            if y < 0xFE
                s := if(s = "", "DT" + y, s + ", DT" + y);
                i := i + 1;
            else
                i := 8;
            end
        loop
        return(if(s = "", "MASK", s));
    end
end

return("--")
Physical Min Level
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x9A);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if (x <= 0xFE, return(round((x / 0xFE) * 100) + " %"));
end

return("--")
Max Level
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA1);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if (x <= 0xFE, return(round((x / 0xFE) * 100) + " %"));
end

return("--")
Min Level
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA2);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if (x <= 0xFE, return(round((x / 0xFE) * 100) + " %"));
end

return("--")
Power Up Level
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA3);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if (x <= 0xFE, return(round((x / 0xFE) * 100) + " %"));
end

return("--")
System Failure Level
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA4);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if (x <= 0xFE, return(round((x / 0xFE) * 100) + " %"));
end

return("--")
${xml_groups}
var x := 0; var rx := 0;
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xC0);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var g1 := modbusr(SH, 511, uint16);
    if (g1 > 0xFF, return("--")); 

    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xC1);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var g2 := modbusr(SH, 511, uint16);
    if (g2 > 0xFF, return("--")); 

    var ret := "";

    if (getbit(g1, 0), ret := ret + "0");
    if (getbit(g1, 1), if (ret = "", ret := "1", ret := ret + ",1"));
    if (getbit(g1, 2), if (ret = "", ret := "2", ret := ret + ",2"));
    if (getbit(g1, 3), if (ret = "", ret := "3", ret := ret + ",3"));
    if (getbit(g1, 4), if (ret = "", ret := "4", ret := ret + ",4"));
    if (getbit(g1, 5), if (ret = "", ret := "5", ret := ret + ",5"));
    if (getbit(g1, 6), if (ret = "", ret := "6", ret := ret + ",6"));
    if (getbit(g1, 7), if (ret = "", ret := "7", ret := ret + ",7"));
    if (getbit(g2, 0), if (ret = "", ret := "8", ret := ret + ",8"));
    if (getbit(g2, 1), if (ret = "", ret := "9", ret := ret + ",9"));
    if (getbit(g2, 2), if (ret = "", ret := "10", ret := ret + ",10"));
    if (getbit(g2, 3), if (ret = "", ret := "11", ret := ret + ",11"));
    if (getbit(g2, 4), if (ret = "", ret := "12", ret := ret + ",12"));
    if (getbit(g2, 5), if (ret = "", ret := "13", ret := ret + ",13"));
    if (getbit(g2, 6), if (ret = "", ret := "14", ret := ret + ",14"));
    if (getbit(g2, 7), if (ret = "", ret := "15", ret := ret + ",15"));

    if (ret = "", return("None"), return(ret));
else
    return("--");
end
DALI Status
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x90);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if x <= 0xFF
        var s := "";
        if (getbit(x, 0), s := if(s = "", "gear failure", s + ", gear failure"));
        if (getbit(x, 1), s := if(s = "", "lamp failure", s + ", lamp failure"));
        if (getbit(x, 2), s := if(s = "", "lamp on", s + ", lamp on"));
        if (getbit(x, 3), s := if(s = "", "limit error", s + ", limit error"));
        if (getbit(x, 4), s := if(s = "", "fade running", s + ", fade running"));
        if (getbit(x, 5), s := if(s = "", "reset state", s + ", reset state"));
        if (getbit(x, 6), s := if(s = "", "missing short address", s + ", missing short address"));
        if (getbit(x, 7), s := if(s = "", "power cycle", s + ", power cycle"));
        var ign := if((ignGear = 1) and (ignLamp = 1), "gear and lamp failure", if(ignGear = 1, "gear failure", if(ignLamp = 1, "lamp failure", "")));
        return(if(s = "", "OK", s) + " (0x" + tostring(x, "X2") + ")" + if(ign = "", "", "; not raised: " + ign + " reported since start"));
    end
end

return("--")
Fade
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA5);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if x <= 0xFF
        var t := getbits(x, 4, 4);
        var ret := if(t = 0, "off", t + " (" + round(sqrt(power(2, t)) * 5) / 10 + " s)");
        modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA8);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
        var e := modbusr(SH, 511, uint16);
        if (t = 0 and e <= 0xFF and e != 0, ret := "extended 0x" + tostring(e, "X2"));
        return("fade time " + ret + ", fade rate " + getbits(x, 0, 4));
    end
end

return("--")
DALI Version
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x97);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if x <= 0xFF
        return(if(x >= 8, "DALI-2 " + getbits(x, 2, 6) + "." + getbits(x, 0, 2), "DALI-1") + " (" + x + ")");
    end
end

return("--")
Bus statistics
return("since start: queries " + cntQ + ", stale answers read away " + cntStale + ", no answer " + cntNone + ", collisions " + cntColl + ", rejected levels " + cntBad)
Azioni di servizio
${xml_add_to_group}
Parametri: Group ID (0–15 grp)
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x60 + grp);
${xml_remove_from_group}
Parametri: Group ID (0–15 grp)
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x70 + grp);
${xml_reset_to_default_settings}
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x20);
${xml_set_startup_levels}
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x21);
sleep(10);
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x2c);
sleep(10);
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x2d);
Disable fading
modbusw(SH, 541, uint16, 0xA300);
sleep(100);
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x2E);
sleep(100);
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x30);
Gear 6 Dimmer Lettura e scrittura

Dispositivo di controllo DALI all'indirizzo breve 6 — dimmer TapHome mappato su DALI arc power 0–100 % tramite H:510 LAMP LEVEL (scrittura) e QUERY ACTUAL LEVEL tramite H:511 (lettura), delimitato dai propri MIN / MAX LEVEL del gear.

Registro: H:511 → H:510 UInt16 Unità: % numeric
Attributi di servizio
Indirizzo breveIndirizzo breve DALI (0–63) target di questo dispositivo — fissato al momento dell'importazione del template e utilizzato nel byte alto di ogni scrittura Modbus.
Device TypeByte device-type DALI restituito da QUERY DEVICE TYPE (0x99) — riporta DT0 (fluorescente), DT6 (driver LED), DT8 (colore / tunable white) ecc., o -- quando non c'è risposta.
Physical Min LevelLivello minimo di dimmerazione imposto dall'hardware riportato dal gear — letto da QUERY PHYSICAL MIN LEVEL (0x9A), in percentuale.
Max LevelDALI MAX LEVEL configurato — letto da QUERY MAX LEVEL (0xA1); utilizzato come limite superiore durante la scalatura di TapHome 0–100 % su DALI arc power.
Min LevelDALI MIN LEVEL configurato — letto da QUERY MIN LEVEL (0xA2); utilizzato come limite inferiore durante la scalatura di TapHome 0–100 % su DALI arc power.
Power Up LevelLuminosità ripristinata dopo il ripristino dell'alimentazione del bus DALI — letta da QUERY POWER ON LEVEL (0xA3).
System Failure LevelLuminosità adottata quando il bus DALI perde la comunicazione per più di 500 ms — letta da QUERY SYSTEM FAILURE LEVEL (0xA4).
GruppiElenco separato da virgole dei gruppi DALI (0–15) a cui appartiene il gear — decodificato da QUERY GROUPS 0-7 (0xC0) e QUERY GROUPS 8-15 (0xC1); mostra None o ad es. 0,3,7.
Support Lamp FailureSe la lampada / driver supporta il rilevamento dei guasti della lampada — Yes / No / --. Gestisce l'errore Lamp failure! nel readscript periodico.
Support Power FailureSe la lampada / driver supporta il rilevamento dei guasti di alimentazione — Yes / No / --. Gestisce l'errore Power failure! nel readscript periodico.
DALI Version
Bus statistics
Azioni di servizio
Add to GroupAggiunge questo gear a un gruppo DALI (0–15) tramite ADD TO GROUP (0x60+grp) — auto-ripetuto entro 100 ms come richiesto per i comandi di configurazione DALI.
Remove from GroupRimuove questo gear da un gruppo DALI (0–15) tramite REMOVE FROM GROUP (0x70+grp).
Reset to Default SettingsInvia DALI RESET (0x20) — ripristina ogni parametro NVM del gear (livelli max / min / power-on / system-failure, appartenenza al gruppo, scene) al valore predefinito del produttore.
Set Startup LevelsCattura l'arc power corrente e la memorizza come Power On Level e System Failure Level — sequenza STORE ACTUAL LEVEL IN DTR (0x21) → STORE DTR AS POWER ON LEVEL (0x2C) → STORE DTR AS SYSTEM FAILURE LEVEL (0x2D).
Disable fading

Gear 6

Lettura (modulo)
var x := 0; var rx := 0; var y := 0;
if Status > 0
    Status := Status - 1;
    adderror(3, "Gear not responding!");
    return(0);
end

# checkStatus: ReadLevel resets it while the gear answers; statusPoll: QUERY STATUS at least once per 60 runs
checkStatus := checkStatus - 1;
statusPoll := statusPoll - 1;
if checkStatus < 1 or statusPoll < 1
    # an unread answer left in the gateway would be taken for this query: read it away and count it
    x := modbusr(SH, 511, uint16); if (x != 0x8000, cntStale := cntStale + 1);
    modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x90);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    x := modbusr(SH, 511, uint16);
    cntQ := cntQ + 1; if (x = 0x8000, cntNone := cntNone + 1); if (x = 0x20FF, cntColl := cntColl + 1);
    # a single lost answer happens on DALI: ask once more before declaring the gear missing
    if x = 0x8000
        x := modbusr(SH, 511, uint16); if (x != 0x8000, cntStale := cntStale + 1);
        modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x90);
        sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
        x := modbusr(SH, 511, uint16);
        cntQ := cntQ + 1; if (x = 0x8000, cntNone := cntNone + 1); if (x = 0x20FF, cntColl := cntColl + 1);
    end
    if x <= 0xFF
        # a changed failure bit must be read twice the same before it is taken
        if statusSeen = 1 and getbits(x, 0, 2) != getbits(gearStatus, 0, 2)
            y := modbusr(SH, 511, uint16); if (y != 0x8000, cntStale := cntStale + 1);
            modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x90);
            sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
            y := modbusr(SH, 511, uint16);
            cntQ := cntQ + 1; if (y = 0x8000, cntNone := cntNone + 1); if (y = 0x20FF, cntColl := cntColl + 1);
            if y != x
                cntBad := cntBad + 1;
                x := gearStatus;
            end
        end
        if statusSeen = 0
            ignGear := getbit(x, 0);
            ignLamp := getbit(x, 1);
            statusSeen := 1;
        end
        # a bit that clears ends its ignore, so a later failure is raised
        if (getbit(x, 0) = 0, ignGear := 0);
        if (getbit(x, 1) = 0, ignLamp := 0);
        gearStatus := x;
        checkStatus := 60;
        statusPoll := 60;
    else
        if x = 0x8000
            Status := RANDINT(10, 60);
            adderror(3, "Gear not responding!");
            return(0);
        end
    end
end

# messages last one run only, so they are raised from the stored status on every run
if ((getbit(gearStatus, 0) = 1) and (ignGear = 0), adderror(1, "Control gear failure!"));
if ((getbit(gearStatus, 1) = 1) and (ignLamp = 0), adderror(2, "Lamp failure!"));
Inizializzazione
var x := 0; var rx := 0;
# QUERY STATUS 0x90: every reply byte proves the gear is present; 0x8000 = no answer, 0x20FF = bus collision
# an unread answer left in the gateway would be taken for this query: read it away and count it
x := modbusr(SH, 511, uint16); if (x != 0x8000, cntStale := cntStale + 1);
modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x90);
sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
x := modbusr(SH, 511, uint16);
cntQ := cntQ + 1; if (x = 0x8000, cntNone := cntNone + 1); if (x = 0x20FF, cntColl := cntColl + 1);
statusSeen := 0;
if x <= 0xFF
    # failure bits a gear reports from its first answer are its permanent state, not an event: shown, not raised
    gearStatus := x;
    ignGear := getbit(x, 0);
    ignLamp := getbit(x, 1);
    statusSeen := 1;
    Status := 0;
else
    Status := RANDINT(1, 60);
end

if Status = 0
    x := modbusr(SH, 511, uint16); if (x != 0x8000, cntStale := cntStale + 1);
    modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA2);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    x := modbusr(SH, 511, uint16);
    cntQ := cntQ + 1; if (x = 0x8000, cntNone := cntNone + 1); if (x = 0x20FF, cntColl := cntColl + 1);
    if (x <= 0xFE, minLevel := x);

    x := modbusr(SH, 511, uint16); if (x != 0x8000, cntStale := cntStale + 1);
    modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA1);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    x := modbusr(SH, 511, uint16);
    cntQ := cntQ + 1; if (x = 0x8000, cntNone := cntNone + 1); if (x = 0x20FF, cntColl := cntColl + 1);
    if (x <= 0xFE, maxLevel := x);
end
Lettura livello
var x := 0; var rx := 0; var y := 0;
if Status = 0
    if minLevel = 0
        # an unread answer left in the gateway would be taken for this query: read it away and count it
        x := modbusr(SH, 511, uint16); if (x != 0x8000, cntStale := cntStale + 1);
        modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA2);
        sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
        x := modbusr(SH, 511, uint16);
        cntQ := cntQ + 1; if (x = 0x8000, cntNone := cntNone + 1); if (x = 0x20FF, cntColl := cntColl + 1);
        if (x <= 0xFE, minLevel := x);
    end
    x := modbusr(SH, 511, uint16); if (x != 0x8000, cntStale := cntStale + 1);
    modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA0);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    x := modbusr(SH, 511, uint16);
    cntQ := cntQ + 1; if (x = 0x8000, cntNone := cntNone + 1); if (x = 0x20FF, cntColl := cntColl + 1);
    if (x != 0x8000 or rx, checkStatus := 60);
    # 0xFF = MASK, 0x20FF = collision, 0x8000 = no answer: keep the last level instead of a phantom value
    if x > 0xFE
        return(Le);
    end
    # an actual level is 0 or between the gear's min and max: anything else is not this gear's answer
    if x > 0 and x < minLevel
        cntBad := cntBad + 1;
        return(Le);
    end
    # a changed level must be read twice the same before it is taken
    if x != lastRaw
        y := modbusr(SH, 511, uint16); if (y != 0x8000, cntStale := cntStale + 1);
        modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA0);
        sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
        y := modbusr(SH, 511, uint16);
        cntQ := cntQ + 1; if (y = 0x8000, cntNone := cntNone + 1); if (y = 0x20FF, cntColl := cntColl + 1);
        if y != x
            cntBad := cntBad + 1;
            return(Le);
        end
        lastRaw := x;
    end
    return(if(x = 0, 0, linear(x, minLevel, 0.01, maxLevel, 1)));
else
    return(NaN);
end
Scrittura livello
var level := 0;
if(Le > 0, level := round(linear(Le, 0.01, minLevel, 1, maxLevel)));
modbusw(SH, 510, uint16, (ShortAddress << 8) + level );
Attributi di servizio
${xml_short_address}
ShortAddress
${xml_device_type}
var x := 0; var y := 0; var rx := 0; var s := ""; var i := 0;
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x99);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    x := modbusr(SH, 511, uint16);
    if (x < 0xFF, return("DT" + x));
    if x = 0xFF
        while i < 8
            modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA7);
            sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
            y := modbusr(SH, 511, uint16);
            if y < 0xFE
                s := if(s = "", "DT" + y, s + ", DT" + y);
                i := i + 1;
            else
                i := 8;
            end
        loop
        return(if(s = "", "MASK", s));
    end
end

return("--")
Physical Min Level
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x9A);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if (x <= 0xFE, return(round((x / 0xFE) * 100) + " %"));
end

return("--")
Max Level
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA1);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if (x <= 0xFE, return(round((x / 0xFE) * 100) + " %"));
end

return("--")
Min Level
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA2);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if (x <= 0xFE, return(round((x / 0xFE) * 100) + " %"));
end

return("--")
Power Up Level
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA3);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if (x <= 0xFE, return(round((x / 0xFE) * 100) + " %"));
end

return("--")
System Failure Level
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA4);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if (x <= 0xFE, return(round((x / 0xFE) * 100) + " %"));
end

return("--")
${xml_groups}
var x := 0; var rx := 0;
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xC0);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var g1 := modbusr(SH, 511, uint16);
    if (g1 > 0xFF, return("--")); 

    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xC1);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var g2 := modbusr(SH, 511, uint16);
    if (g2 > 0xFF, return("--")); 

    var ret := "";

    if (getbit(g1, 0), ret := ret + "0");
    if (getbit(g1, 1), if (ret = "", ret := "1", ret := ret + ",1"));
    if (getbit(g1, 2), if (ret = "", ret := "2", ret := ret + ",2"));
    if (getbit(g1, 3), if (ret = "", ret := "3", ret := ret + ",3"));
    if (getbit(g1, 4), if (ret = "", ret := "4", ret := ret + ",4"));
    if (getbit(g1, 5), if (ret = "", ret := "5", ret := ret + ",5"));
    if (getbit(g1, 6), if (ret = "", ret := "6", ret := ret + ",6"));
    if (getbit(g1, 7), if (ret = "", ret := "7", ret := ret + ",7"));
    if (getbit(g2, 0), if (ret = "", ret := "8", ret := ret + ",8"));
    if (getbit(g2, 1), if (ret = "", ret := "9", ret := ret + ",9"));
    if (getbit(g2, 2), if (ret = "", ret := "10", ret := ret + ",10"));
    if (getbit(g2, 3), if (ret = "", ret := "11", ret := ret + ",11"));
    if (getbit(g2, 4), if (ret = "", ret := "12", ret := ret + ",12"));
    if (getbit(g2, 5), if (ret = "", ret := "13", ret := ret + ",13"));
    if (getbit(g2, 6), if (ret = "", ret := "14", ret := ret + ",14"));
    if (getbit(g2, 7), if (ret = "", ret := "15", ret := ret + ",15"));

    if (ret = "", return("None"), return(ret));
else
    return("--");
end
DALI Status
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x90);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if x <= 0xFF
        var s := "";
        if (getbit(x, 0), s := if(s = "", "gear failure", s + ", gear failure"));
        if (getbit(x, 1), s := if(s = "", "lamp failure", s + ", lamp failure"));
        if (getbit(x, 2), s := if(s = "", "lamp on", s + ", lamp on"));
        if (getbit(x, 3), s := if(s = "", "limit error", s + ", limit error"));
        if (getbit(x, 4), s := if(s = "", "fade running", s + ", fade running"));
        if (getbit(x, 5), s := if(s = "", "reset state", s + ", reset state"));
        if (getbit(x, 6), s := if(s = "", "missing short address", s + ", missing short address"));
        if (getbit(x, 7), s := if(s = "", "power cycle", s + ", power cycle"));
        var ign := if((ignGear = 1) and (ignLamp = 1), "gear and lamp failure", if(ignGear = 1, "gear failure", if(ignLamp = 1, "lamp failure", "")));
        return(if(s = "", "OK", s) + " (0x" + tostring(x, "X2") + ")" + if(ign = "", "", "; not raised: " + ign + " reported since start"));
    end
end

return("--")
Fade
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA5);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if x <= 0xFF
        var t := getbits(x, 4, 4);
        var ret := if(t = 0, "off", t + " (" + round(sqrt(power(2, t)) * 5) / 10 + " s)");
        modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA8);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
        var e := modbusr(SH, 511, uint16);
        if (t = 0 and e <= 0xFF and e != 0, ret := "extended 0x" + tostring(e, "X2"));
        return("fade time " + ret + ", fade rate " + getbits(x, 0, 4));
    end
end

return("--")
DALI Version
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x97);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if x <= 0xFF
        return(if(x >= 8, "DALI-2 " + getbits(x, 2, 6) + "." + getbits(x, 0, 2), "DALI-1") + " (" + x + ")");
    end
end

return("--")
Bus statistics
return("since start: queries " + cntQ + ", stale answers read away " + cntStale + ", no answer " + cntNone + ", collisions " + cntColl + ", rejected levels " + cntBad)
Azioni di servizio
${xml_add_to_group}
Parametri: Group ID (0–15 grp)
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x60 + grp);
${xml_remove_from_group}
Parametri: Group ID (0–15 grp)
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x70 + grp);
${xml_reset_to_default_settings}
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x20);
${xml_set_startup_levels}
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x21);
sleep(10);
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x2c);
sleep(10);
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x2d);
Disable fading
modbusw(SH, 541, uint16, 0xA300);
sleep(100);
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x2E);
sleep(100);
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x30);
Gear 7 Dimmer Lettura e scrittura

Dispositivo di controllo DALI all'indirizzo breve 7 — dimmer TapHome mappato su DALI arc power 0–100 % tramite H:510 LAMP LEVEL (scrittura) e QUERY ACTUAL LEVEL tramite H:511 (lettura), delimitato dai propri MIN / MAX LEVEL del gear.

Registro: H:511 → H:510 UInt16 Unità: % numeric
Attributi di servizio
Indirizzo breveIndirizzo breve DALI (0–63) target di questo dispositivo — fissato al momento dell'importazione del template e utilizzato nel byte alto di ogni scrittura Modbus.
Device TypeByte device-type DALI restituito da QUERY DEVICE TYPE (0x99) — riporta DT0 (fluorescente), DT6 (driver LED), DT8 (colore / tunable white) ecc., o -- quando non c'è risposta.
Physical Min LevelLivello minimo di dimmerazione imposto dall'hardware riportato dal gear — letto da QUERY PHYSICAL MIN LEVEL (0x9A), in percentuale.
Max LevelDALI MAX LEVEL configurato — letto da QUERY MAX LEVEL (0xA1); utilizzato come limite superiore durante la scalatura di TapHome 0–100 % su DALI arc power.
Min LevelDALI MIN LEVEL configurato — letto da QUERY MIN LEVEL (0xA2); utilizzato come limite inferiore durante la scalatura di TapHome 0–100 % su DALI arc power.
Power Up LevelLuminosità ripristinata dopo il ripristino dell'alimentazione del bus DALI — letta da QUERY POWER ON LEVEL (0xA3).
System Failure LevelLuminosità adottata quando il bus DALI perde la comunicazione per più di 500 ms — letta da QUERY SYSTEM FAILURE LEVEL (0xA4).
GruppiElenco separato da virgole dei gruppi DALI (0–15) a cui appartiene il gear — decodificato da QUERY GROUPS 0-7 (0xC0) e QUERY GROUPS 8-15 (0xC1); mostra None o ad es. 0,3,7.
Support Lamp FailureSe la lampada / driver supporta il rilevamento dei guasti della lampada — Yes / No / --. Gestisce l'errore Lamp failure! nel readscript periodico.
Support Power FailureSe la lampada / driver supporta il rilevamento dei guasti di alimentazione — Yes / No / --. Gestisce l'errore Power failure! nel readscript periodico.
DALI Version
Bus statistics
Azioni di servizio
Add to GroupAggiunge questo gear a un gruppo DALI (0–15) tramite ADD TO GROUP (0x60+grp) — auto-ripetuto entro 100 ms come richiesto per i comandi di configurazione DALI.
Remove from GroupRimuove questo gear da un gruppo DALI (0–15) tramite REMOVE FROM GROUP (0x70+grp).
Reset to Default SettingsInvia DALI RESET (0x20) — ripristina ogni parametro NVM del gear (livelli max / min / power-on / system-failure, appartenenza al gruppo, scene) al valore predefinito del produttore.
Set Startup LevelsCattura l'arc power corrente e la memorizza come Power On Level e System Failure Level — sequenza STORE ACTUAL LEVEL IN DTR (0x21) → STORE DTR AS POWER ON LEVEL (0x2C) → STORE DTR AS SYSTEM FAILURE LEVEL (0x2D).
Disable fading

Gear 7

Lettura (modulo)
var x := 0; var rx := 0; var y := 0;
if Status > 0
    Status := Status - 1;
    adderror(3, "Gear not responding!");
    return(0);
end

# checkStatus: ReadLevel resets it while the gear answers; statusPoll: QUERY STATUS at least once per 60 runs
checkStatus := checkStatus - 1;
statusPoll := statusPoll - 1;
if checkStatus < 1 or statusPoll < 1
    # an unread answer left in the gateway would be taken for this query: read it away and count it
    x := modbusr(SH, 511, uint16); if (x != 0x8000, cntStale := cntStale + 1);
    modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x90);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    x := modbusr(SH, 511, uint16);
    cntQ := cntQ + 1; if (x = 0x8000, cntNone := cntNone + 1); if (x = 0x20FF, cntColl := cntColl + 1);
    # a single lost answer happens on DALI: ask once more before declaring the gear missing
    if x = 0x8000
        x := modbusr(SH, 511, uint16); if (x != 0x8000, cntStale := cntStale + 1);
        modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x90);
        sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
        x := modbusr(SH, 511, uint16);
        cntQ := cntQ + 1; if (x = 0x8000, cntNone := cntNone + 1); if (x = 0x20FF, cntColl := cntColl + 1);
    end
    if x <= 0xFF
        # a changed failure bit must be read twice the same before it is taken
        if statusSeen = 1 and getbits(x, 0, 2) != getbits(gearStatus, 0, 2)
            y := modbusr(SH, 511, uint16); if (y != 0x8000, cntStale := cntStale + 1);
            modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x90);
            sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
            y := modbusr(SH, 511, uint16);
            cntQ := cntQ + 1; if (y = 0x8000, cntNone := cntNone + 1); if (y = 0x20FF, cntColl := cntColl + 1);
            if y != x
                cntBad := cntBad + 1;
                x := gearStatus;
            end
        end
        if statusSeen = 0
            ignGear := getbit(x, 0);
            ignLamp := getbit(x, 1);
            statusSeen := 1;
        end
        # a bit that clears ends its ignore, so a later failure is raised
        if (getbit(x, 0) = 0, ignGear := 0);
        if (getbit(x, 1) = 0, ignLamp := 0);
        gearStatus := x;
        checkStatus := 60;
        statusPoll := 60;
    else
        if x = 0x8000
            Status := RANDINT(10, 60);
            adderror(3, "Gear not responding!");
            return(0);
        end
    end
end

# messages last one run only, so they are raised from the stored status on every run
if ((getbit(gearStatus, 0) = 1) and (ignGear = 0), adderror(1, "Control gear failure!"));
if ((getbit(gearStatus, 1) = 1) and (ignLamp = 0), adderror(2, "Lamp failure!"));
Inizializzazione
var x := 0; var rx := 0;
# QUERY STATUS 0x90: every reply byte proves the gear is present; 0x8000 = no answer, 0x20FF = bus collision
# an unread answer left in the gateway would be taken for this query: read it away and count it
x := modbusr(SH, 511, uint16); if (x != 0x8000, cntStale := cntStale + 1);
modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x90);
sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
x := modbusr(SH, 511, uint16);
cntQ := cntQ + 1; if (x = 0x8000, cntNone := cntNone + 1); if (x = 0x20FF, cntColl := cntColl + 1);
statusSeen := 0;
if x <= 0xFF
    # failure bits a gear reports from its first answer are its permanent state, not an event: shown, not raised
    gearStatus := x;
    ignGear := getbit(x, 0);
    ignLamp := getbit(x, 1);
    statusSeen := 1;
    Status := 0;
else
    Status := RANDINT(1, 60);
end

if Status = 0
    x := modbusr(SH, 511, uint16); if (x != 0x8000, cntStale := cntStale + 1);
    modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA2);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    x := modbusr(SH, 511, uint16);
    cntQ := cntQ + 1; if (x = 0x8000, cntNone := cntNone + 1); if (x = 0x20FF, cntColl := cntColl + 1);
    if (x <= 0xFE, minLevel := x);

    x := modbusr(SH, 511, uint16); if (x != 0x8000, cntStale := cntStale + 1);
    modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA1);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    x := modbusr(SH, 511, uint16);
    cntQ := cntQ + 1; if (x = 0x8000, cntNone := cntNone + 1); if (x = 0x20FF, cntColl := cntColl + 1);
    if (x <= 0xFE, maxLevel := x);
end
Lettura livello
var x := 0; var rx := 0; var y := 0;
if Status = 0
    if minLevel = 0
        # an unread answer left in the gateway would be taken for this query: read it away and count it
        x := modbusr(SH, 511, uint16); if (x != 0x8000, cntStale := cntStale + 1);
        modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA2);
        sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
        x := modbusr(SH, 511, uint16);
        cntQ := cntQ + 1; if (x = 0x8000, cntNone := cntNone + 1); if (x = 0x20FF, cntColl := cntColl + 1);
        if (x <= 0xFE, minLevel := x);
    end
    x := modbusr(SH, 511, uint16); if (x != 0x8000, cntStale := cntStale + 1);
    modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA0);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    x := modbusr(SH, 511, uint16);
    cntQ := cntQ + 1; if (x = 0x8000, cntNone := cntNone + 1); if (x = 0x20FF, cntColl := cntColl + 1);
    if (x != 0x8000 or rx, checkStatus := 60);
    # 0xFF = MASK, 0x20FF = collision, 0x8000 = no answer: keep the last level instead of a phantom value
    if x > 0xFE
        return(Le);
    end
    # an actual level is 0 or between the gear's min and max: anything else is not this gear's answer
    if x > 0 and x < minLevel
        cntBad := cntBad + 1;
        return(Le);
    end
    # a changed level must be read twice the same before it is taken
    if x != lastRaw
        y := modbusr(SH, 511, uint16); if (y != 0x8000, cntStale := cntStale + 1);
        modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA0);
        sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
        y := modbusr(SH, 511, uint16);
        cntQ := cntQ + 1; if (y = 0x8000, cntNone := cntNone + 1); if (y = 0x20FF, cntColl := cntColl + 1);
        if y != x
            cntBad := cntBad + 1;
            return(Le);
        end
        lastRaw := x;
    end
    return(if(x = 0, 0, linear(x, minLevel, 0.01, maxLevel, 1)));
else
    return(NaN);
end
Scrittura livello
var level := 0;
if(Le > 0, level := round(linear(Le, 0.01, minLevel, 1, maxLevel)));
modbusw(SH, 510, uint16, (ShortAddress << 8) + level );
Attributi di servizio
${xml_short_address}
ShortAddress
${xml_device_type}
var x := 0; var y := 0; var rx := 0; var s := ""; var i := 0;
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x99);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    x := modbusr(SH, 511, uint16);
    if (x < 0xFF, return("DT" + x));
    if x = 0xFF
        while i < 8
            modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA7);
            sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
            y := modbusr(SH, 511, uint16);
            if y < 0xFE
                s := if(s = "", "DT" + y, s + ", DT" + y);
                i := i + 1;
            else
                i := 8;
            end
        loop
        return(if(s = "", "MASK", s));
    end
end

return("--")
Physical Min Level
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x9A);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if (x <= 0xFE, return(round((x / 0xFE) * 100) + " %"));
end

return("--")
Max Level
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA1);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if (x <= 0xFE, return(round((x / 0xFE) * 100) + " %"));
end

return("--")
Min Level
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA2);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if (x <= 0xFE, return(round((x / 0xFE) * 100) + " %"));
end

return("--")
Power Up Level
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA3);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if (x <= 0xFE, return(round((x / 0xFE) * 100) + " %"));
end

return("--")
System Failure Level
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA4);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if (x <= 0xFE, return(round((x / 0xFE) * 100) + " %"));
end

return("--")
${xml_groups}
var x := 0; var rx := 0;
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xC0);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var g1 := modbusr(SH, 511, uint16);
    if (g1 > 0xFF, return("--")); 

    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xC1);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var g2 := modbusr(SH, 511, uint16);
    if (g2 > 0xFF, return("--")); 

    var ret := "";

    if (getbit(g1, 0), ret := ret + "0");
    if (getbit(g1, 1), if (ret = "", ret := "1", ret := ret + ",1"));
    if (getbit(g1, 2), if (ret = "", ret := "2", ret := ret + ",2"));
    if (getbit(g1, 3), if (ret = "", ret := "3", ret := ret + ",3"));
    if (getbit(g1, 4), if (ret = "", ret := "4", ret := ret + ",4"));
    if (getbit(g1, 5), if (ret = "", ret := "5", ret := ret + ",5"));
    if (getbit(g1, 6), if (ret = "", ret := "6", ret := ret + ",6"));
    if (getbit(g1, 7), if (ret = "", ret := "7", ret := ret + ",7"));
    if (getbit(g2, 0), if (ret = "", ret := "8", ret := ret + ",8"));
    if (getbit(g2, 1), if (ret = "", ret := "9", ret := ret + ",9"));
    if (getbit(g2, 2), if (ret = "", ret := "10", ret := ret + ",10"));
    if (getbit(g2, 3), if (ret = "", ret := "11", ret := ret + ",11"));
    if (getbit(g2, 4), if (ret = "", ret := "12", ret := ret + ",12"));
    if (getbit(g2, 5), if (ret = "", ret := "13", ret := ret + ",13"));
    if (getbit(g2, 6), if (ret = "", ret := "14", ret := ret + ",14"));
    if (getbit(g2, 7), if (ret = "", ret := "15", ret := ret + ",15"));

    if (ret = "", return("None"), return(ret));
else
    return("--");
end
DALI Status
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x90);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if x <= 0xFF
        var s := "";
        if (getbit(x, 0), s := if(s = "", "gear failure", s + ", gear failure"));
        if (getbit(x, 1), s := if(s = "", "lamp failure", s + ", lamp failure"));
        if (getbit(x, 2), s := if(s = "", "lamp on", s + ", lamp on"));
        if (getbit(x, 3), s := if(s = "", "limit error", s + ", limit error"));
        if (getbit(x, 4), s := if(s = "", "fade running", s + ", fade running"));
        if (getbit(x, 5), s := if(s = "", "reset state", s + ", reset state"));
        if (getbit(x, 6), s := if(s = "", "missing short address", s + ", missing short address"));
        if (getbit(x, 7), s := if(s = "", "power cycle", s + ", power cycle"));
        var ign := if((ignGear = 1) and (ignLamp = 1), "gear and lamp failure", if(ignGear = 1, "gear failure", if(ignLamp = 1, "lamp failure", "")));
        return(if(s = "", "OK", s) + " (0x" + tostring(x, "X2") + ")" + if(ign = "", "", "; not raised: " + ign + " reported since start"));
    end
end

return("--")
Fade
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA5);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if x <= 0xFF
        var t := getbits(x, 4, 4);
        var ret := if(t = 0, "off", t + " (" + round(sqrt(power(2, t)) * 5) / 10 + " s)");
        modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA8);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
        var e := modbusr(SH, 511, uint16);
        if (t = 0 and e <= 0xFF and e != 0, ret := "extended 0x" + tostring(e, "X2"));
        return("fade time " + ret + ", fade rate " + getbits(x, 0, 4));
    end
end

return("--")
DALI Version
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x97);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if x <= 0xFF
        return(if(x >= 8, "DALI-2 " + getbits(x, 2, 6) + "." + getbits(x, 0, 2), "DALI-1") + " (" + x + ")");
    end
end

return("--")
Bus statistics
return("since start: queries " + cntQ + ", stale answers read away " + cntStale + ", no answer " + cntNone + ", collisions " + cntColl + ", rejected levels " + cntBad)
Azioni di servizio
${xml_add_to_group}
Parametri: Group ID (0–15 grp)
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x60 + grp);
${xml_remove_from_group}
Parametri: Group ID (0–15 grp)
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x70 + grp);
${xml_reset_to_default_settings}
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x20);
${xml_set_startup_levels}
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x21);
sleep(10);
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x2c);
sleep(10);
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x2d);
Disable fading
modbusw(SH, 541, uint16, 0xA300);
sleep(100);
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x2E);
sleep(100);
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x30);
Gear 8 Dimmer Lettura e scrittura

Dispositivo di controllo DALI all'indirizzo breve 8 — dimmer TapHome mappato su DALI arc power 0–100 % tramite H:510 LAMP LEVEL (scrittura) e QUERY ACTUAL LEVEL tramite H:511 (lettura), delimitato dai propri MIN / MAX LEVEL del gear.

Registro: H:511 → H:510 UInt16 Unità: % numeric
Attributi di servizio
Indirizzo breveIndirizzo breve DALI (0–63) target di questo dispositivo — fissato al momento dell'importazione del template e utilizzato nel byte alto di ogni scrittura Modbus.
Device TypeByte device-type DALI restituito da QUERY DEVICE TYPE (0x99) — riporta DT0 (fluorescente), DT6 (driver LED), DT8 (colore / tunable white) ecc., o -- quando non c'è risposta.
Physical Min LevelLivello minimo di dimmerazione imposto dall'hardware riportato dal gear — letto da QUERY PHYSICAL MIN LEVEL (0x9A), in percentuale.
Max LevelDALI MAX LEVEL configurato — letto da QUERY MAX LEVEL (0xA1); utilizzato come limite superiore durante la scalatura di TapHome 0–100 % su DALI arc power.
Min LevelDALI MIN LEVEL configurato — letto da QUERY MIN LEVEL (0xA2); utilizzato come limite inferiore durante la scalatura di TapHome 0–100 % su DALI arc power.
Power Up LevelLuminosità ripristinata dopo il ripristino dell'alimentazione del bus DALI — letta da QUERY POWER ON LEVEL (0xA3).
System Failure LevelLuminosità adottata quando il bus DALI perde la comunicazione per più di 500 ms — letta da QUERY SYSTEM FAILURE LEVEL (0xA4).
GruppiElenco separato da virgole dei gruppi DALI (0–15) a cui appartiene il gear — decodificato da QUERY GROUPS 0-7 (0xC0) e QUERY GROUPS 8-15 (0xC1); mostra None o ad es. 0,3,7.
Support Lamp FailureSe la lampada / driver supporta il rilevamento dei guasti della lampada — Yes / No / --. Gestisce l'errore Lamp failure! nel readscript periodico.
Support Power FailureSe la lampada / driver supporta il rilevamento dei guasti di alimentazione — Yes / No / --. Gestisce l'errore Power failure! nel readscript periodico.
DALI Version
Bus statistics
Azioni di servizio
Add to GroupAggiunge questo gear a un gruppo DALI (0–15) tramite ADD TO GROUP (0x60+grp) — auto-ripetuto entro 100 ms come richiesto per i comandi di configurazione DALI.
Remove from GroupRimuove questo gear da un gruppo DALI (0–15) tramite REMOVE FROM GROUP (0x70+grp).
Reset to Default SettingsInvia DALI RESET (0x20) — ripristina ogni parametro NVM del gear (livelli max / min / power-on / system-failure, appartenenza al gruppo, scene) al valore predefinito del produttore.
Set Startup LevelsCattura l'arc power corrente e la memorizza come Power On Level e System Failure Level — sequenza STORE ACTUAL LEVEL IN DTR (0x21) → STORE DTR AS POWER ON LEVEL (0x2C) → STORE DTR AS SYSTEM FAILURE LEVEL (0x2D).
Disable fading

Gear 8

Lettura (modulo)
var x := 0; var rx := 0; var y := 0;
if Status > 0
    Status := Status - 1;
    adderror(3, "Gear not responding!");
    return(0);
end

# checkStatus: ReadLevel resets it while the gear answers; statusPoll: QUERY STATUS at least once per 60 runs
checkStatus := checkStatus - 1;
statusPoll := statusPoll - 1;
if checkStatus < 1 or statusPoll < 1
    # an unread answer left in the gateway would be taken for this query: read it away and count it
    x := modbusr(SH, 511, uint16); if (x != 0x8000, cntStale := cntStale + 1);
    modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x90);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    x := modbusr(SH, 511, uint16);
    cntQ := cntQ + 1; if (x = 0x8000, cntNone := cntNone + 1); if (x = 0x20FF, cntColl := cntColl + 1);
    # a single lost answer happens on DALI: ask once more before declaring the gear missing
    if x = 0x8000
        x := modbusr(SH, 511, uint16); if (x != 0x8000, cntStale := cntStale + 1);
        modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x90);
        sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
        x := modbusr(SH, 511, uint16);
        cntQ := cntQ + 1; if (x = 0x8000, cntNone := cntNone + 1); if (x = 0x20FF, cntColl := cntColl + 1);
    end
    if x <= 0xFF
        # a changed failure bit must be read twice the same before it is taken
        if statusSeen = 1 and getbits(x, 0, 2) != getbits(gearStatus, 0, 2)
            y := modbusr(SH, 511, uint16); if (y != 0x8000, cntStale := cntStale + 1);
            modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x90);
            sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
            y := modbusr(SH, 511, uint16);
            cntQ := cntQ + 1; if (y = 0x8000, cntNone := cntNone + 1); if (y = 0x20FF, cntColl := cntColl + 1);
            if y != x
                cntBad := cntBad + 1;
                x := gearStatus;
            end
        end
        if statusSeen = 0
            ignGear := getbit(x, 0);
            ignLamp := getbit(x, 1);
            statusSeen := 1;
        end
        # a bit that clears ends its ignore, so a later failure is raised
        if (getbit(x, 0) = 0, ignGear := 0);
        if (getbit(x, 1) = 0, ignLamp := 0);
        gearStatus := x;
        checkStatus := 60;
        statusPoll := 60;
    else
        if x = 0x8000
            Status := RANDINT(10, 60);
            adderror(3, "Gear not responding!");
            return(0);
        end
    end
end

# messages last one run only, so they are raised from the stored status on every run
if ((getbit(gearStatus, 0) = 1) and (ignGear = 0), adderror(1, "Control gear failure!"));
if ((getbit(gearStatus, 1) = 1) and (ignLamp = 0), adderror(2, "Lamp failure!"));
Inizializzazione
var x := 0; var rx := 0;
# QUERY STATUS 0x90: every reply byte proves the gear is present; 0x8000 = no answer, 0x20FF = bus collision
# an unread answer left in the gateway would be taken for this query: read it away and count it
x := modbusr(SH, 511, uint16); if (x != 0x8000, cntStale := cntStale + 1);
modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x90);
sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
x := modbusr(SH, 511, uint16);
cntQ := cntQ + 1; if (x = 0x8000, cntNone := cntNone + 1); if (x = 0x20FF, cntColl := cntColl + 1);
statusSeen := 0;
if x <= 0xFF
    # failure bits a gear reports from its first answer are its permanent state, not an event: shown, not raised
    gearStatus := x;
    ignGear := getbit(x, 0);
    ignLamp := getbit(x, 1);
    statusSeen := 1;
    Status := 0;
else
    Status := RANDINT(1, 60);
end

if Status = 0
    x := modbusr(SH, 511, uint16); if (x != 0x8000, cntStale := cntStale + 1);
    modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA2);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    x := modbusr(SH, 511, uint16);
    cntQ := cntQ + 1; if (x = 0x8000, cntNone := cntNone + 1); if (x = 0x20FF, cntColl := cntColl + 1);
    if (x <= 0xFE, minLevel := x);

    x := modbusr(SH, 511, uint16); if (x != 0x8000, cntStale := cntStale + 1);
    modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA1);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    x := modbusr(SH, 511, uint16);
    cntQ := cntQ + 1; if (x = 0x8000, cntNone := cntNone + 1); if (x = 0x20FF, cntColl := cntColl + 1);
    if (x <= 0xFE, maxLevel := x);
end
Lettura livello
var x := 0; var rx := 0; var y := 0;
if Status = 0
    if minLevel = 0
        # an unread answer left in the gateway would be taken for this query: read it away and count it
        x := modbusr(SH, 511, uint16); if (x != 0x8000, cntStale := cntStale + 1);
        modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA2);
        sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
        x := modbusr(SH, 511, uint16);
        cntQ := cntQ + 1; if (x = 0x8000, cntNone := cntNone + 1); if (x = 0x20FF, cntColl := cntColl + 1);
        if (x <= 0xFE, minLevel := x);
    end
    x := modbusr(SH, 511, uint16); if (x != 0x8000, cntStale := cntStale + 1);
    modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA0);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    x := modbusr(SH, 511, uint16);
    cntQ := cntQ + 1; if (x = 0x8000, cntNone := cntNone + 1); if (x = 0x20FF, cntColl := cntColl + 1);
    if (x != 0x8000 or rx, checkStatus := 60);
    # 0xFF = MASK, 0x20FF = collision, 0x8000 = no answer: keep the last level instead of a phantom value
    if x > 0xFE
        return(Le);
    end
    # an actual level is 0 or between the gear's min and max: anything else is not this gear's answer
    if x > 0 and x < minLevel
        cntBad := cntBad + 1;
        return(Le);
    end
    # a changed level must be read twice the same before it is taken
    if x != lastRaw
        y := modbusr(SH, 511, uint16); if (y != 0x8000, cntStale := cntStale + 1);
        modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA0);
        sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
        y := modbusr(SH, 511, uint16);
        cntQ := cntQ + 1; if (y = 0x8000, cntNone := cntNone + 1); if (y = 0x20FF, cntColl := cntColl + 1);
        if y != x
            cntBad := cntBad + 1;
            return(Le);
        end
        lastRaw := x;
    end
    return(if(x = 0, 0, linear(x, minLevel, 0.01, maxLevel, 1)));
else
    return(NaN);
end
Scrittura livello
var level := 0;
if(Le > 0, level := round(linear(Le, 0.01, minLevel, 1, maxLevel)));
modbusw(SH, 510, uint16, (ShortAddress << 8) + level );
Attributi di servizio
${xml_short_address}
ShortAddress
${xml_device_type}
var x := 0; var y := 0; var rx := 0; var s := ""; var i := 0;
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x99);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    x := modbusr(SH, 511, uint16);
    if (x < 0xFF, return("DT" + x));
    if x = 0xFF
        while i < 8
            modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA7);
            sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
            y := modbusr(SH, 511, uint16);
            if y < 0xFE
                s := if(s = "", "DT" + y, s + ", DT" + y);
                i := i + 1;
            else
                i := 8;
            end
        loop
        return(if(s = "", "MASK", s));
    end
end

return("--")
Physical Min Level
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x9A);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if (x <= 0xFE, return(round((x / 0xFE) * 100) + " %"));
end

return("--")
Max Level
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA1);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if (x <= 0xFE, return(round((x / 0xFE) * 100) + " %"));
end

return("--")
Min Level
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA2);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if (x <= 0xFE, return(round((x / 0xFE) * 100) + " %"));
end

return("--")
Power Up Level
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA3);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if (x <= 0xFE, return(round((x / 0xFE) * 100) + " %"));
end

return("--")
System Failure Level
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA4);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if (x <= 0xFE, return(round((x / 0xFE) * 100) + " %"));
end

return("--")
${xml_groups}
var x := 0; var rx := 0;
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xC0);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var g1 := modbusr(SH, 511, uint16);
    if (g1 > 0xFF, return("--")); 

    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xC1);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var g2 := modbusr(SH, 511, uint16);
    if (g2 > 0xFF, return("--")); 

    var ret := "";

    if (getbit(g1, 0), ret := ret + "0");
    if (getbit(g1, 1), if (ret = "", ret := "1", ret := ret + ",1"));
    if (getbit(g1, 2), if (ret = "", ret := "2", ret := ret + ",2"));
    if (getbit(g1, 3), if (ret = "", ret := "3", ret := ret + ",3"));
    if (getbit(g1, 4), if (ret = "", ret := "4", ret := ret + ",4"));
    if (getbit(g1, 5), if (ret = "", ret := "5", ret := ret + ",5"));
    if (getbit(g1, 6), if (ret = "", ret := "6", ret := ret + ",6"));
    if (getbit(g1, 7), if (ret = "", ret := "7", ret := ret + ",7"));
    if (getbit(g2, 0), if (ret = "", ret := "8", ret := ret + ",8"));
    if (getbit(g2, 1), if (ret = "", ret := "9", ret := ret + ",9"));
    if (getbit(g2, 2), if (ret = "", ret := "10", ret := ret + ",10"));
    if (getbit(g2, 3), if (ret = "", ret := "11", ret := ret + ",11"));
    if (getbit(g2, 4), if (ret = "", ret := "12", ret := ret + ",12"));
    if (getbit(g2, 5), if (ret = "", ret := "13", ret := ret + ",13"));
    if (getbit(g2, 6), if (ret = "", ret := "14", ret := ret + ",14"));
    if (getbit(g2, 7), if (ret = "", ret := "15", ret := ret + ",15"));

    if (ret = "", return("None"), return(ret));
else
    return("--");
end
DALI Status
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x90);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if x <= 0xFF
        var s := "";
        if (getbit(x, 0), s := if(s = "", "gear failure", s + ", gear failure"));
        if (getbit(x, 1), s := if(s = "", "lamp failure", s + ", lamp failure"));
        if (getbit(x, 2), s := if(s = "", "lamp on", s + ", lamp on"));
        if (getbit(x, 3), s := if(s = "", "limit error", s + ", limit error"));
        if (getbit(x, 4), s := if(s = "", "fade running", s + ", fade running"));
        if (getbit(x, 5), s := if(s = "", "reset state", s + ", reset state"));
        if (getbit(x, 6), s := if(s = "", "missing short address", s + ", missing short address"));
        if (getbit(x, 7), s := if(s = "", "power cycle", s + ", power cycle"));
        var ign := if((ignGear = 1) and (ignLamp = 1), "gear and lamp failure", if(ignGear = 1, "gear failure", if(ignLamp = 1, "lamp failure", "")));
        return(if(s = "", "OK", s) + " (0x" + tostring(x, "X2") + ")" + if(ign = "", "", "; not raised: " + ign + " reported since start"));
    end
end

return("--")
Fade
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA5);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if x <= 0xFF
        var t := getbits(x, 4, 4);
        var ret := if(t = 0, "off", t + " (" + round(sqrt(power(2, t)) * 5) / 10 + " s)");
        modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA8);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
        var e := modbusr(SH, 511, uint16);
        if (t = 0 and e <= 0xFF and e != 0, ret := "extended 0x" + tostring(e, "X2"));
        return("fade time " + ret + ", fade rate " + getbits(x, 0, 4));
    end
end

return("--")
DALI Version
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x97);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if x <= 0xFF
        return(if(x >= 8, "DALI-2 " + getbits(x, 2, 6) + "." + getbits(x, 0, 2), "DALI-1") + " (" + x + ")");
    end
end

return("--")
Bus statistics
return("since start: queries " + cntQ + ", stale answers read away " + cntStale + ", no answer " + cntNone + ", collisions " + cntColl + ", rejected levels " + cntBad)
Azioni di servizio
${xml_add_to_group}
Parametri: Group ID (0–15 grp)
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x60 + grp);
${xml_remove_from_group}
Parametri: Group ID (0–15 grp)
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x70 + grp);
${xml_reset_to_default_settings}
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x20);
${xml_set_startup_levels}
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x21);
sleep(10);
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x2c);
sleep(10);
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x2d);
Disable fading
modbusw(SH, 541, uint16, 0xA300);
sleep(100);
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x2E);
sleep(100);
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x30);
Gear 9 Dimmer Lettura e scrittura

Dispositivo di controllo DALI all'indirizzo breve 9 — dimmer TapHome mappato su DALI arc power 0–100 % tramite H:510 LAMP LEVEL (scrittura) e QUERY ACTUAL LEVEL tramite H:511 (lettura), delimitato dai propri MIN / MAX LEVEL del gear.

Registro: H:511 → H:510 UInt16 Unità: % numeric
Attributi di servizio
Indirizzo breveIndirizzo breve DALI (0–63) target di questo dispositivo — fissato al momento dell'importazione del template e utilizzato nel byte alto di ogni scrittura Modbus.
Device TypeByte device-type DALI restituito da QUERY DEVICE TYPE (0x99) — riporta DT0 (fluorescente), DT6 (driver LED), DT8 (colore / tunable white) ecc., o -- quando non c'è risposta.
Physical Min LevelLivello minimo di dimmerazione imposto dall'hardware riportato dal gear — letto da QUERY PHYSICAL MIN LEVEL (0x9A), in percentuale.
Max LevelDALI MAX LEVEL configurato — letto da QUERY MAX LEVEL (0xA1); utilizzato come limite superiore durante la scalatura di TapHome 0–100 % su DALI arc power.
Min LevelDALI MIN LEVEL configurato — letto da QUERY MIN LEVEL (0xA2); utilizzato come limite inferiore durante la scalatura di TapHome 0–100 % su DALI arc power.
Power Up LevelLuminosità ripristinata dopo il ripristino dell'alimentazione del bus DALI — letta da QUERY POWER ON LEVEL (0xA3).
System Failure LevelLuminosità adottata quando il bus DALI perde la comunicazione per più di 500 ms — letta da QUERY SYSTEM FAILURE LEVEL (0xA4).
GruppiElenco separato da virgole dei gruppi DALI (0–15) a cui appartiene il gear — decodificato da QUERY GROUPS 0-7 (0xC0) e QUERY GROUPS 8-15 (0xC1); mostra None o ad es. 0,3,7.
Support Lamp FailureSe la lampada / driver supporta il rilevamento dei guasti della lampada — Yes / No / --. Gestisce l'errore Lamp failure! nel readscript periodico.
Support Power FailureSe la lampada / driver supporta il rilevamento dei guasti di alimentazione — Yes / No / --. Gestisce l'errore Power failure! nel readscript periodico.
DALI Version
Bus statistics
Azioni di servizio
Add to GroupAggiunge questo gear a un gruppo DALI (0–15) tramite ADD TO GROUP (0x60+grp) — auto-ripetuto entro 100 ms come richiesto per i comandi di configurazione DALI.
Remove from GroupRimuove questo gear da un gruppo DALI (0–15) tramite REMOVE FROM GROUP (0x70+grp).
Reset to Default SettingsInvia DALI RESET (0x20) — ripristina ogni parametro NVM del gear (livelli max / min / power-on / system-failure, appartenenza al gruppo, scene) al valore predefinito del produttore.
Set Startup LevelsCattura l'arc power corrente e la memorizza come Power On Level e System Failure Level — sequenza STORE ACTUAL LEVEL IN DTR (0x21) → STORE DTR AS POWER ON LEVEL (0x2C) → STORE DTR AS SYSTEM FAILURE LEVEL (0x2D).
Disable fading

Gear 9

Lettura (modulo)
var x := 0; var rx := 0; var y := 0;
if Status > 0
    Status := Status - 1;
    adderror(3, "Gear not responding!");
    return(0);
end

# checkStatus: ReadLevel resets it while the gear answers; statusPoll: QUERY STATUS at least once per 60 runs
checkStatus := checkStatus - 1;
statusPoll := statusPoll - 1;
if checkStatus < 1 or statusPoll < 1
    # an unread answer left in the gateway would be taken for this query: read it away and count it
    x := modbusr(SH, 511, uint16); if (x != 0x8000, cntStale := cntStale + 1);
    modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x90);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    x := modbusr(SH, 511, uint16);
    cntQ := cntQ + 1; if (x = 0x8000, cntNone := cntNone + 1); if (x = 0x20FF, cntColl := cntColl + 1);
    # a single lost answer happens on DALI: ask once more before declaring the gear missing
    if x = 0x8000
        x := modbusr(SH, 511, uint16); if (x != 0x8000, cntStale := cntStale + 1);
        modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x90);
        sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
        x := modbusr(SH, 511, uint16);
        cntQ := cntQ + 1; if (x = 0x8000, cntNone := cntNone + 1); if (x = 0x20FF, cntColl := cntColl + 1);
    end
    if x <= 0xFF
        # a changed failure bit must be read twice the same before it is taken
        if statusSeen = 1 and getbits(x, 0, 2) != getbits(gearStatus, 0, 2)
            y := modbusr(SH, 511, uint16); if (y != 0x8000, cntStale := cntStale + 1);
            modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x90);
            sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
            y := modbusr(SH, 511, uint16);
            cntQ := cntQ + 1; if (y = 0x8000, cntNone := cntNone + 1); if (y = 0x20FF, cntColl := cntColl + 1);
            if y != x
                cntBad := cntBad + 1;
                x := gearStatus;
            end
        end
        if statusSeen = 0
            ignGear := getbit(x, 0);
            ignLamp := getbit(x, 1);
            statusSeen := 1;
        end
        # a bit that clears ends its ignore, so a later failure is raised
        if (getbit(x, 0) = 0, ignGear := 0);
        if (getbit(x, 1) = 0, ignLamp := 0);
        gearStatus := x;
        checkStatus := 60;
        statusPoll := 60;
    else
        if x = 0x8000
            Status := RANDINT(10, 60);
            adderror(3, "Gear not responding!");
            return(0);
        end
    end
end

# messages last one run only, so they are raised from the stored status on every run
if ((getbit(gearStatus, 0) = 1) and (ignGear = 0), adderror(1, "Control gear failure!"));
if ((getbit(gearStatus, 1) = 1) and (ignLamp = 0), adderror(2, "Lamp failure!"));
Inizializzazione
var x := 0; var rx := 0;
# QUERY STATUS 0x90: every reply byte proves the gear is present; 0x8000 = no answer, 0x20FF = bus collision
# an unread answer left in the gateway would be taken for this query: read it away and count it
x := modbusr(SH, 511, uint16); if (x != 0x8000, cntStale := cntStale + 1);
modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x90);
sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
x := modbusr(SH, 511, uint16);
cntQ := cntQ + 1; if (x = 0x8000, cntNone := cntNone + 1); if (x = 0x20FF, cntColl := cntColl + 1);
statusSeen := 0;
if x <= 0xFF
    # failure bits a gear reports from its first answer are its permanent state, not an event: shown, not raised
    gearStatus := x;
    ignGear := getbit(x, 0);
    ignLamp := getbit(x, 1);
    statusSeen := 1;
    Status := 0;
else
    Status := RANDINT(1, 60);
end

if Status = 0
    x := modbusr(SH, 511, uint16); if (x != 0x8000, cntStale := cntStale + 1);
    modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA2);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    x := modbusr(SH, 511, uint16);
    cntQ := cntQ + 1; if (x = 0x8000, cntNone := cntNone + 1); if (x = 0x20FF, cntColl := cntColl + 1);
    if (x <= 0xFE, minLevel := x);

    x := modbusr(SH, 511, uint16); if (x != 0x8000, cntStale := cntStale + 1);
    modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA1);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    x := modbusr(SH, 511, uint16);
    cntQ := cntQ + 1; if (x = 0x8000, cntNone := cntNone + 1); if (x = 0x20FF, cntColl := cntColl + 1);
    if (x <= 0xFE, maxLevel := x);
end
Lettura livello
var x := 0; var rx := 0; var y := 0;
if Status = 0
    if minLevel = 0
        # an unread answer left in the gateway would be taken for this query: read it away and count it
        x := modbusr(SH, 511, uint16); if (x != 0x8000, cntStale := cntStale + 1);
        modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA2);
        sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
        x := modbusr(SH, 511, uint16);
        cntQ := cntQ + 1; if (x = 0x8000, cntNone := cntNone + 1); if (x = 0x20FF, cntColl := cntColl + 1);
        if (x <= 0xFE, minLevel := x);
    end
    x := modbusr(SH, 511, uint16); if (x != 0x8000, cntStale := cntStale + 1);
    modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA0);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    x := modbusr(SH, 511, uint16);
    cntQ := cntQ + 1; if (x = 0x8000, cntNone := cntNone + 1); if (x = 0x20FF, cntColl := cntColl + 1);
    if (x != 0x8000 or rx, checkStatus := 60);
    # 0xFF = MASK, 0x20FF = collision, 0x8000 = no answer: keep the last level instead of a phantom value
    if x > 0xFE
        return(Le);
    end
    # an actual level is 0 or between the gear's min and max: anything else is not this gear's answer
    if x > 0 and x < minLevel
        cntBad := cntBad + 1;
        return(Le);
    end
    # a changed level must be read twice the same before it is taken
    if x != lastRaw
        y := modbusr(SH, 511, uint16); if (y != 0x8000, cntStale := cntStale + 1);
        modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA0);
        sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
        y := modbusr(SH, 511, uint16);
        cntQ := cntQ + 1; if (y = 0x8000, cntNone := cntNone + 1); if (y = 0x20FF, cntColl := cntColl + 1);
        if y != x
            cntBad := cntBad + 1;
            return(Le);
        end
        lastRaw := x;
    end
    return(if(x = 0, 0, linear(x, minLevel, 0.01, maxLevel, 1)));
else
    return(NaN);
end
Scrittura livello
var level := 0;
if(Le > 0, level := round(linear(Le, 0.01, minLevel, 1, maxLevel)));
modbusw(SH, 510, uint16, (ShortAddress << 8) + level );
Attributi di servizio
${xml_short_address}
ShortAddress
${xml_device_type}
var x := 0; var y := 0; var rx := 0; var s := ""; var i := 0;
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x99);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    x := modbusr(SH, 511, uint16);
    if (x < 0xFF, return("DT" + x));
    if x = 0xFF
        while i < 8
            modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA7);
            sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
            y := modbusr(SH, 511, uint16);
            if y < 0xFE
                s := if(s = "", "DT" + y, s + ", DT" + y);
                i := i + 1;
            else
                i := 8;
            end
        loop
        return(if(s = "", "MASK", s));
    end
end

return("--")
Physical Min Level
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x9A);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if (x <= 0xFE, return(round((x / 0xFE) * 100) + " %"));
end

return("--")
Max Level
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA1);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if (x <= 0xFE, return(round((x / 0xFE) * 100) + " %"));
end

return("--")
Min Level
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA2);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if (x <= 0xFE, return(round((x / 0xFE) * 100) + " %"));
end

return("--")
Power Up Level
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA3);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if (x <= 0xFE, return(round((x / 0xFE) * 100) + " %"));
end

return("--")
System Failure Level
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA4);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if (x <= 0xFE, return(round((x / 0xFE) * 100) + " %"));
end

return("--")
${xml_groups}
var x := 0; var rx := 0;
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xC0);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var g1 := modbusr(SH, 511, uint16);
    if (g1 > 0xFF, return("--")); 

    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xC1);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var g2 := modbusr(SH, 511, uint16);
    if (g2 > 0xFF, return("--")); 

    var ret := "";

    if (getbit(g1, 0), ret := ret + "0");
    if (getbit(g1, 1), if (ret = "", ret := "1", ret := ret + ",1"));
    if (getbit(g1, 2), if (ret = "", ret := "2", ret := ret + ",2"));
    if (getbit(g1, 3), if (ret = "", ret := "3", ret := ret + ",3"));
    if (getbit(g1, 4), if (ret = "", ret := "4", ret := ret + ",4"));
    if (getbit(g1, 5), if (ret = "", ret := "5", ret := ret + ",5"));
    if (getbit(g1, 6), if (ret = "", ret := "6", ret := ret + ",6"));
    if (getbit(g1, 7), if (ret = "", ret := "7", ret := ret + ",7"));
    if (getbit(g2, 0), if (ret = "", ret := "8", ret := ret + ",8"));
    if (getbit(g2, 1), if (ret = "", ret := "9", ret := ret + ",9"));
    if (getbit(g2, 2), if (ret = "", ret := "10", ret := ret + ",10"));
    if (getbit(g2, 3), if (ret = "", ret := "11", ret := ret + ",11"));
    if (getbit(g2, 4), if (ret = "", ret := "12", ret := ret + ",12"));
    if (getbit(g2, 5), if (ret = "", ret := "13", ret := ret + ",13"));
    if (getbit(g2, 6), if (ret = "", ret := "14", ret := ret + ",14"));
    if (getbit(g2, 7), if (ret = "", ret := "15", ret := ret + ",15"));

    if (ret = "", return("None"), return(ret));
else
    return("--");
end
DALI Status
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x90);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if x <= 0xFF
        var s := "";
        if (getbit(x, 0), s := if(s = "", "gear failure", s + ", gear failure"));
        if (getbit(x, 1), s := if(s = "", "lamp failure", s + ", lamp failure"));
        if (getbit(x, 2), s := if(s = "", "lamp on", s + ", lamp on"));
        if (getbit(x, 3), s := if(s = "", "limit error", s + ", limit error"));
        if (getbit(x, 4), s := if(s = "", "fade running", s + ", fade running"));
        if (getbit(x, 5), s := if(s = "", "reset state", s + ", reset state"));
        if (getbit(x, 6), s := if(s = "", "missing short address", s + ", missing short address"));
        if (getbit(x, 7), s := if(s = "", "power cycle", s + ", power cycle"));
        var ign := if((ignGear = 1) and (ignLamp = 1), "gear and lamp failure", if(ignGear = 1, "gear failure", if(ignLamp = 1, "lamp failure", "")));
        return(if(s = "", "OK", s) + " (0x" + tostring(x, "X2") + ")" + if(ign = "", "", "; not raised: " + ign + " reported since start"));
    end
end

return("--")
Fade
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA5);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if x <= 0xFF
        var t := getbits(x, 4, 4);
        var ret := if(t = 0, "off", t + " (" + round(sqrt(power(2, t)) * 5) / 10 + " s)");
        modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA8);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
        var e := modbusr(SH, 511, uint16);
        if (t = 0 and e <= 0xFF and e != 0, ret := "extended 0x" + tostring(e, "X2"));
        return("fade time " + ret + ", fade rate " + getbits(x, 0, 4));
    end
end

return("--")
DALI Version
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x97);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if x <= 0xFF
        return(if(x >= 8, "DALI-2 " + getbits(x, 2, 6) + "." + getbits(x, 0, 2), "DALI-1") + " (" + x + ")");
    end
end

return("--")
Bus statistics
return("since start: queries " + cntQ + ", stale answers read away " + cntStale + ", no answer " + cntNone + ", collisions " + cntColl + ", rejected levels " + cntBad)
Azioni di servizio
${xml_add_to_group}
Parametri: Group ID (0–15 grp)
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x60 + grp);
${xml_remove_from_group}
Parametri: Group ID (0–15 grp)
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x70 + grp);
${xml_reset_to_default_settings}
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x20);
${xml_set_startup_levels}
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x21);
sleep(10);
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x2c);
sleep(10);
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x2d);
Disable fading
modbusw(SH, 541, uint16, 0xA300);
sleep(100);
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x2E);
sleep(100);
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x30);
Gear 10 Dimmer Lettura e scrittura

Dispositivo di controllo DALI all'indirizzo breve 10 — dimmer TapHome mappato su DALI arc power 0–100 % tramite H:510 LAMP LEVEL (scrittura) e QUERY ACTUAL LEVEL tramite H:511 (lettura), delimitato dai propri MIN / MAX LEVEL del gear.

Registro: H:511 → H:510 UInt16 Unità: % numeric
Attributi di servizio
Indirizzo breveIndirizzo breve DALI (0–63) target di questo dispositivo — fissato al momento dell'importazione del template e utilizzato nel byte alto di ogni scrittura Modbus.
Device TypeByte device-type DALI restituito da QUERY DEVICE TYPE (0x99) — riporta DT0 (fluorescente), DT6 (driver LED), DT8 (colore / tunable white) ecc., o -- quando non c'è risposta.
Physical Min LevelLivello minimo di dimmerazione imposto dall'hardware riportato dal gear — letto da QUERY PHYSICAL MIN LEVEL (0x9A), in percentuale.
Max LevelDALI MAX LEVEL configurato — letto da QUERY MAX LEVEL (0xA1); utilizzato come limite superiore durante la scalatura di TapHome 0–100 % su DALI arc power.
Min LevelDALI MIN LEVEL configurato — letto da QUERY MIN LEVEL (0xA2); utilizzato come limite inferiore durante la scalatura di TapHome 0–100 % su DALI arc power.
Power Up LevelLuminosità ripristinata dopo il ripristino dell'alimentazione del bus DALI — letta da QUERY POWER ON LEVEL (0xA3).
System Failure LevelLuminosità adottata quando il bus DALI perde la comunicazione per più di 500 ms — letta da QUERY SYSTEM FAILURE LEVEL (0xA4).
GruppiElenco separato da virgole dei gruppi DALI (0–15) a cui appartiene il gear — decodificato da QUERY GROUPS 0-7 (0xC0) e QUERY GROUPS 8-15 (0xC1); mostra None o ad es. 0,3,7.
Support Lamp FailureSe la lampada / driver supporta il rilevamento dei guasti della lampada — Yes / No / --. Gestisce l'errore Lamp failure! nel readscript periodico.
Support Power FailureSe la lampada / driver supporta il rilevamento dei guasti di alimentazione — Yes / No / --. Gestisce l'errore Power failure! nel readscript periodico.
DALI Version
Bus statistics
Azioni di servizio
Add to GroupAggiunge questo gear a un gruppo DALI (0–15) tramite ADD TO GROUP (0x60+grp) — auto-ripetuto entro 100 ms come richiesto per i comandi di configurazione DALI.
Remove from GroupRimuove questo gear da un gruppo DALI (0–15) tramite REMOVE FROM GROUP (0x70+grp).
Reset to Default SettingsInvia DALI RESET (0x20) — ripristina ogni parametro NVM del gear (livelli max / min / power-on / system-failure, appartenenza al gruppo, scene) al valore predefinito del produttore.
Set Startup LevelsCattura l'arc power corrente e la memorizza come Power On Level e System Failure Level — sequenza STORE ACTUAL LEVEL IN DTR (0x21) → STORE DTR AS POWER ON LEVEL (0x2C) → STORE DTR AS SYSTEM FAILURE LEVEL (0x2D).
Disable fading

Gear 10

Lettura (modulo)
var x := 0; var rx := 0; var y := 0;
if Status > 0
    Status := Status - 1;
    adderror(3, "Gear not responding!");
    return(0);
end

# checkStatus: ReadLevel resets it while the gear answers; statusPoll: QUERY STATUS at least once per 60 runs
checkStatus := checkStatus - 1;
statusPoll := statusPoll - 1;
if checkStatus < 1 or statusPoll < 1
    # an unread answer left in the gateway would be taken for this query: read it away and count it
    x := modbusr(SH, 511, uint16); if (x != 0x8000, cntStale := cntStale + 1);
    modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x90);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    x := modbusr(SH, 511, uint16);
    cntQ := cntQ + 1; if (x = 0x8000, cntNone := cntNone + 1); if (x = 0x20FF, cntColl := cntColl + 1);
    # a single lost answer happens on DALI: ask once more before declaring the gear missing
    if x = 0x8000
        x := modbusr(SH, 511, uint16); if (x != 0x8000, cntStale := cntStale + 1);
        modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x90);
        sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
        x := modbusr(SH, 511, uint16);
        cntQ := cntQ + 1; if (x = 0x8000, cntNone := cntNone + 1); if (x = 0x20FF, cntColl := cntColl + 1);
    end
    if x <= 0xFF
        # a changed failure bit must be read twice the same before it is taken
        if statusSeen = 1 and getbits(x, 0, 2) != getbits(gearStatus, 0, 2)
            y := modbusr(SH, 511, uint16); if (y != 0x8000, cntStale := cntStale + 1);
            modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x90);
            sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
            y := modbusr(SH, 511, uint16);
            cntQ := cntQ + 1; if (y = 0x8000, cntNone := cntNone + 1); if (y = 0x20FF, cntColl := cntColl + 1);
            if y != x
                cntBad := cntBad + 1;
                x := gearStatus;
            end
        end
        if statusSeen = 0
            ignGear := getbit(x, 0);
            ignLamp := getbit(x, 1);
            statusSeen := 1;
        end
        # a bit that clears ends its ignore, so a later failure is raised
        if (getbit(x, 0) = 0, ignGear := 0);
        if (getbit(x, 1) = 0, ignLamp := 0);
        gearStatus := x;
        checkStatus := 60;
        statusPoll := 60;
    else
        if x = 0x8000
            Status := RANDINT(10, 60);
            adderror(3, "Gear not responding!");
            return(0);
        end
    end
end

# messages last one run only, so they are raised from the stored status on every run
if ((getbit(gearStatus, 0) = 1) and (ignGear = 0), adderror(1, "Control gear failure!"));
if ((getbit(gearStatus, 1) = 1) and (ignLamp = 0), adderror(2, "Lamp failure!"));
Inizializzazione
var x := 0; var rx := 0;
# QUERY STATUS 0x90: every reply byte proves the gear is present; 0x8000 = no answer, 0x20FF = bus collision
# an unread answer left in the gateway would be taken for this query: read it away and count it
x := modbusr(SH, 511, uint16); if (x != 0x8000, cntStale := cntStale + 1);
modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x90);
sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
x := modbusr(SH, 511, uint16);
cntQ := cntQ + 1; if (x = 0x8000, cntNone := cntNone + 1); if (x = 0x20FF, cntColl := cntColl + 1);
statusSeen := 0;
if x <= 0xFF
    # failure bits a gear reports from its first answer are its permanent state, not an event: shown, not raised
    gearStatus := x;
    ignGear := getbit(x, 0);
    ignLamp := getbit(x, 1);
    statusSeen := 1;
    Status := 0;
else
    Status := RANDINT(1, 60);
end

if Status = 0
    x := modbusr(SH, 511, uint16); if (x != 0x8000, cntStale := cntStale + 1);
    modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA2);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    x := modbusr(SH, 511, uint16);
    cntQ := cntQ + 1; if (x = 0x8000, cntNone := cntNone + 1); if (x = 0x20FF, cntColl := cntColl + 1);
    if (x <= 0xFE, minLevel := x);

    x := modbusr(SH, 511, uint16); if (x != 0x8000, cntStale := cntStale + 1);
    modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA1);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    x := modbusr(SH, 511, uint16);
    cntQ := cntQ + 1; if (x = 0x8000, cntNone := cntNone + 1); if (x = 0x20FF, cntColl := cntColl + 1);
    if (x <= 0xFE, maxLevel := x);
end
Lettura livello
var x := 0; var rx := 0; var y := 0;
if Status = 0
    if minLevel = 0
        # an unread answer left in the gateway would be taken for this query: read it away and count it
        x := modbusr(SH, 511, uint16); if (x != 0x8000, cntStale := cntStale + 1);
        modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA2);
        sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
        x := modbusr(SH, 511, uint16);
        cntQ := cntQ + 1; if (x = 0x8000, cntNone := cntNone + 1); if (x = 0x20FF, cntColl := cntColl + 1);
        if (x <= 0xFE, minLevel := x);
    end
    x := modbusr(SH, 511, uint16); if (x != 0x8000, cntStale := cntStale + 1);
    modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA0);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    x := modbusr(SH, 511, uint16);
    cntQ := cntQ + 1; if (x = 0x8000, cntNone := cntNone + 1); if (x = 0x20FF, cntColl := cntColl + 1);
    if (x != 0x8000 or rx, checkStatus := 60);
    # 0xFF = MASK, 0x20FF = collision, 0x8000 = no answer: keep the last level instead of a phantom value
    if x > 0xFE
        return(Le);
    end
    # an actual level is 0 or between the gear's min and max: anything else is not this gear's answer
    if x > 0 and x < minLevel
        cntBad := cntBad + 1;
        return(Le);
    end
    # a changed level must be read twice the same before it is taken
    if x != lastRaw
        y := modbusr(SH, 511, uint16); if (y != 0x8000, cntStale := cntStale + 1);
        modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA0);
        sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
        y := modbusr(SH, 511, uint16);
        cntQ := cntQ + 1; if (y = 0x8000, cntNone := cntNone + 1); if (y = 0x20FF, cntColl := cntColl + 1);
        if y != x
            cntBad := cntBad + 1;
            return(Le);
        end
        lastRaw := x;
    end
    return(if(x = 0, 0, linear(x, minLevel, 0.01, maxLevel, 1)));
else
    return(NaN);
end
Scrittura livello
var level := 0;
if(Le > 0, level := round(linear(Le, 0.01, minLevel, 1, maxLevel)));
modbusw(SH, 510, uint16, (ShortAddress << 8) + level );
Attributi di servizio
${xml_short_address}
ShortAddress
${xml_device_type}
var x := 0; var y := 0; var rx := 0; var s := ""; var i := 0;
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x99);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    x := modbusr(SH, 511, uint16);
    if (x < 0xFF, return("DT" + x));
    if x = 0xFF
        while i < 8
            modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA7);
            sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
            y := modbusr(SH, 511, uint16);
            if y < 0xFE
                s := if(s = "", "DT" + y, s + ", DT" + y);
                i := i + 1;
            else
                i := 8;
            end
        loop
        return(if(s = "", "MASK", s));
    end
end

return("--")
Physical Min Level
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x9A);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if (x <= 0xFE, return(round((x / 0xFE) * 100) + " %"));
end

return("--")
Max Level
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA1);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if (x <= 0xFE, return(round((x / 0xFE) * 100) + " %"));
end

return("--")
Min Level
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA2);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if (x <= 0xFE, return(round((x / 0xFE) * 100) + " %"));
end

return("--")
Power Up Level
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA3);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if (x <= 0xFE, return(round((x / 0xFE) * 100) + " %"));
end

return("--")
System Failure Level
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA4);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if (x <= 0xFE, return(round((x / 0xFE) * 100) + " %"));
end

return("--")
${xml_groups}
var x := 0; var rx := 0;
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xC0);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var g1 := modbusr(SH, 511, uint16);
    if (g1 > 0xFF, return("--")); 

    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xC1);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var g2 := modbusr(SH, 511, uint16);
    if (g2 > 0xFF, return("--")); 

    var ret := "";

    if (getbit(g1, 0), ret := ret + "0");
    if (getbit(g1, 1), if (ret = "", ret := "1", ret := ret + ",1"));
    if (getbit(g1, 2), if (ret = "", ret := "2", ret := ret + ",2"));
    if (getbit(g1, 3), if (ret = "", ret := "3", ret := ret + ",3"));
    if (getbit(g1, 4), if (ret = "", ret := "4", ret := ret + ",4"));
    if (getbit(g1, 5), if (ret = "", ret := "5", ret := ret + ",5"));
    if (getbit(g1, 6), if (ret = "", ret := "6", ret := ret + ",6"));
    if (getbit(g1, 7), if (ret = "", ret := "7", ret := ret + ",7"));
    if (getbit(g2, 0), if (ret = "", ret := "8", ret := ret + ",8"));
    if (getbit(g2, 1), if (ret = "", ret := "9", ret := ret + ",9"));
    if (getbit(g2, 2), if (ret = "", ret := "10", ret := ret + ",10"));
    if (getbit(g2, 3), if (ret = "", ret := "11", ret := ret + ",11"));
    if (getbit(g2, 4), if (ret = "", ret := "12", ret := ret + ",12"));
    if (getbit(g2, 5), if (ret = "", ret := "13", ret := ret + ",13"));
    if (getbit(g2, 6), if (ret = "", ret := "14", ret := ret + ",14"));
    if (getbit(g2, 7), if (ret = "", ret := "15", ret := ret + ",15"));

    if (ret = "", return("None"), return(ret));
else
    return("--");
end
DALI Status
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x90);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if x <= 0xFF
        var s := "";
        if (getbit(x, 0), s := if(s = "", "gear failure", s + ", gear failure"));
        if (getbit(x, 1), s := if(s = "", "lamp failure", s + ", lamp failure"));
        if (getbit(x, 2), s := if(s = "", "lamp on", s + ", lamp on"));
        if (getbit(x, 3), s := if(s = "", "limit error", s + ", limit error"));
        if (getbit(x, 4), s := if(s = "", "fade running", s + ", fade running"));
        if (getbit(x, 5), s := if(s = "", "reset state", s + ", reset state"));
        if (getbit(x, 6), s := if(s = "", "missing short address", s + ", missing short address"));
        if (getbit(x, 7), s := if(s = "", "power cycle", s + ", power cycle"));
        var ign := if((ignGear = 1) and (ignLamp = 1), "gear and lamp failure", if(ignGear = 1, "gear failure", if(ignLamp = 1, "lamp failure", "")));
        return(if(s = "", "OK", s) + " (0x" + tostring(x, "X2") + ")" + if(ign = "", "", "; not raised: " + ign + " reported since start"));
    end
end

return("--")
Fade
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA5);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if x <= 0xFF
        var t := getbits(x, 4, 4);
        var ret := if(t = 0, "off", t + " (" + round(sqrt(power(2, t)) * 5) / 10 + " s)");
        modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA8);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
        var e := modbusr(SH, 511, uint16);
        if (t = 0 and e <= 0xFF and e != 0, ret := "extended 0x" + tostring(e, "X2"));
        return("fade time " + ret + ", fade rate " + getbits(x, 0, 4));
    end
end

return("--")
DALI Version
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x97);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if x <= 0xFF
        return(if(x >= 8, "DALI-2 " + getbits(x, 2, 6) + "." + getbits(x, 0, 2), "DALI-1") + " (" + x + ")");
    end
end

return("--")
Bus statistics
return("since start: queries " + cntQ + ", stale answers read away " + cntStale + ", no answer " + cntNone + ", collisions " + cntColl + ", rejected levels " + cntBad)
Azioni di servizio
${xml_add_to_group}
Parametri: Group ID (0–15 grp)
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x60 + grp);
${xml_remove_from_group}
Parametri: Group ID (0–15 grp)
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x70 + grp);
${xml_reset_to_default_settings}
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x20);
${xml_set_startup_levels}
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x21);
sleep(10);
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x2c);
sleep(10);
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x2d);
Disable fading
modbusw(SH, 541, uint16, 0xA300);
sleep(100);
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x2E);
sleep(100);
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x30);
Gear 11 Dimmer Lettura e scrittura

Dispositivo di controllo DALI all'indirizzo breve 11 — dimmer TapHome mappato su DALI arc power 0–100 % tramite H:510 LAMP LEVEL (scrittura) e QUERY ACTUAL LEVEL tramite H:511 (lettura), delimitato dai propri MIN / MAX LEVEL del gear.

Registro: H:511 → H:510 UInt16 Unità: % numeric
Attributi di servizio
Indirizzo breveIndirizzo breve DALI (0–63) target di questo dispositivo — fissato al momento dell'importazione del template e utilizzato nel byte alto di ogni scrittura Modbus.
Device TypeByte device-type DALI restituito da QUERY DEVICE TYPE (0x99) — riporta DT0 (fluorescente), DT6 (driver LED), DT8 (colore / tunable white) ecc., o -- quando non c'è risposta.
Physical Min LevelLivello minimo di dimmerazione imposto dall'hardware riportato dal gear — letto da QUERY PHYSICAL MIN LEVEL (0x9A), in percentuale.
Max LevelDALI MAX LEVEL configurato — letto da QUERY MAX LEVEL (0xA1); utilizzato come limite superiore durante la scalatura di TapHome 0–100 % su DALI arc power.
Min LevelDALI MIN LEVEL configurato — letto da QUERY MIN LEVEL (0xA2); utilizzato come limite inferiore durante la scalatura di TapHome 0–100 % su DALI arc power.
Power Up LevelLuminosità ripristinata dopo il ripristino dell'alimentazione del bus DALI — letta da QUERY POWER ON LEVEL (0xA3).
System Failure LevelLuminosità adottata quando il bus DALI perde la comunicazione per più di 500 ms — letta da QUERY SYSTEM FAILURE LEVEL (0xA4).
GruppiElenco separato da virgole dei gruppi DALI (0–15) a cui appartiene il gear — decodificato da QUERY GROUPS 0-7 (0xC0) e QUERY GROUPS 8-15 (0xC1); mostra None o ad es. 0,3,7.
Support Lamp FailureSe la lampada / driver supporta il rilevamento dei guasti della lampada — Yes / No / --. Gestisce l'errore Lamp failure! nel readscript periodico.
Support Power FailureSe la lampada / driver supporta il rilevamento dei guasti di alimentazione — Yes / No / --. Gestisce l'errore Power failure! nel readscript periodico.
DALI Version
Bus statistics
Azioni di servizio
Add to GroupAggiunge questo gear a un gruppo DALI (0–15) tramite ADD TO GROUP (0x60+grp) — auto-ripetuto entro 100 ms come richiesto per i comandi di configurazione DALI.
Remove from GroupRimuove questo gear da un gruppo DALI (0–15) tramite REMOVE FROM GROUP (0x70+grp).
Reset to Default SettingsInvia DALI RESET (0x20) — ripristina ogni parametro NVM del gear (livelli max / min / power-on / system-failure, appartenenza al gruppo, scene) al valore predefinito del produttore.
Set Startup LevelsCattura l'arc power corrente e la memorizza come Power On Level e System Failure Level — sequenza STORE ACTUAL LEVEL IN DTR (0x21) → STORE DTR AS POWER ON LEVEL (0x2C) → STORE DTR AS SYSTEM FAILURE LEVEL (0x2D).
Disable fading

Gear 11

Lettura (modulo)
var x := 0; var rx := 0; var y := 0;
if Status > 0
    Status := Status - 1;
    adderror(3, "Gear not responding!");
    return(0);
end

# checkStatus: ReadLevel resets it while the gear answers; statusPoll: QUERY STATUS at least once per 60 runs
checkStatus := checkStatus - 1;
statusPoll := statusPoll - 1;
if checkStatus < 1 or statusPoll < 1
    # an unread answer left in the gateway would be taken for this query: read it away and count it
    x := modbusr(SH, 511, uint16); if (x != 0x8000, cntStale := cntStale + 1);
    modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x90);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    x := modbusr(SH, 511, uint16);
    cntQ := cntQ + 1; if (x = 0x8000, cntNone := cntNone + 1); if (x = 0x20FF, cntColl := cntColl + 1);
    # a single lost answer happens on DALI: ask once more before declaring the gear missing
    if x = 0x8000
        x := modbusr(SH, 511, uint16); if (x != 0x8000, cntStale := cntStale + 1);
        modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x90);
        sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
        x := modbusr(SH, 511, uint16);
        cntQ := cntQ + 1; if (x = 0x8000, cntNone := cntNone + 1); if (x = 0x20FF, cntColl := cntColl + 1);
    end
    if x <= 0xFF
        # a changed failure bit must be read twice the same before it is taken
        if statusSeen = 1 and getbits(x, 0, 2) != getbits(gearStatus, 0, 2)
            y := modbusr(SH, 511, uint16); if (y != 0x8000, cntStale := cntStale + 1);
            modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x90);
            sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
            y := modbusr(SH, 511, uint16);
            cntQ := cntQ + 1; if (y = 0x8000, cntNone := cntNone + 1); if (y = 0x20FF, cntColl := cntColl + 1);
            if y != x
                cntBad := cntBad + 1;
                x := gearStatus;
            end
        end
        if statusSeen = 0
            ignGear := getbit(x, 0);
            ignLamp := getbit(x, 1);
            statusSeen := 1;
        end
        # a bit that clears ends its ignore, so a later failure is raised
        if (getbit(x, 0) = 0, ignGear := 0);
        if (getbit(x, 1) = 0, ignLamp := 0);
        gearStatus := x;
        checkStatus := 60;
        statusPoll := 60;
    else
        if x = 0x8000
            Status := RANDINT(10, 60);
            adderror(3, "Gear not responding!");
            return(0);
        end
    end
end

# messages last one run only, so they are raised from the stored status on every run
if ((getbit(gearStatus, 0) = 1) and (ignGear = 0), adderror(1, "Control gear failure!"));
if ((getbit(gearStatus, 1) = 1) and (ignLamp = 0), adderror(2, "Lamp failure!"));
Inizializzazione
var x := 0; var rx := 0;
# QUERY STATUS 0x90: every reply byte proves the gear is present; 0x8000 = no answer, 0x20FF = bus collision
# an unread answer left in the gateway would be taken for this query: read it away and count it
x := modbusr(SH, 511, uint16); if (x != 0x8000, cntStale := cntStale + 1);
modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x90);
sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
x := modbusr(SH, 511, uint16);
cntQ := cntQ + 1; if (x = 0x8000, cntNone := cntNone + 1); if (x = 0x20FF, cntColl := cntColl + 1);
statusSeen := 0;
if x <= 0xFF
    # failure bits a gear reports from its first answer are its permanent state, not an event: shown, not raised
    gearStatus := x;
    ignGear := getbit(x, 0);
    ignLamp := getbit(x, 1);
    statusSeen := 1;
    Status := 0;
else
    Status := RANDINT(1, 60);
end

if Status = 0
    x := modbusr(SH, 511, uint16); if (x != 0x8000, cntStale := cntStale + 1);
    modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA2);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    x := modbusr(SH, 511, uint16);
    cntQ := cntQ + 1; if (x = 0x8000, cntNone := cntNone + 1); if (x = 0x20FF, cntColl := cntColl + 1);
    if (x <= 0xFE, minLevel := x);

    x := modbusr(SH, 511, uint16); if (x != 0x8000, cntStale := cntStale + 1);
    modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA1);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    x := modbusr(SH, 511, uint16);
    cntQ := cntQ + 1; if (x = 0x8000, cntNone := cntNone + 1); if (x = 0x20FF, cntColl := cntColl + 1);
    if (x <= 0xFE, maxLevel := x);
end
Lettura livello
var x := 0; var rx := 0; var y := 0;
if Status = 0
    if minLevel = 0
        # an unread answer left in the gateway would be taken for this query: read it away and count it
        x := modbusr(SH, 511, uint16); if (x != 0x8000, cntStale := cntStale + 1);
        modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA2);
        sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
        x := modbusr(SH, 511, uint16);
        cntQ := cntQ + 1; if (x = 0x8000, cntNone := cntNone + 1); if (x = 0x20FF, cntColl := cntColl + 1);
        if (x <= 0xFE, minLevel := x);
    end
    x := modbusr(SH, 511, uint16); if (x != 0x8000, cntStale := cntStale + 1);
    modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA0);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    x := modbusr(SH, 511, uint16);
    cntQ := cntQ + 1; if (x = 0x8000, cntNone := cntNone + 1); if (x = 0x20FF, cntColl := cntColl + 1);
    if (x != 0x8000 or rx, checkStatus := 60);
    # 0xFF = MASK, 0x20FF = collision, 0x8000 = no answer: keep the last level instead of a phantom value
    if x > 0xFE
        return(Le);
    end
    # an actual level is 0 or between the gear's min and max: anything else is not this gear's answer
    if x > 0 and x < minLevel
        cntBad := cntBad + 1;
        return(Le);
    end
    # a changed level must be read twice the same before it is taken
    if x != lastRaw
        y := modbusr(SH, 511, uint16); if (y != 0x8000, cntStale := cntStale + 1);
        modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA0);
        sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
        y := modbusr(SH, 511, uint16);
        cntQ := cntQ + 1; if (y = 0x8000, cntNone := cntNone + 1); if (y = 0x20FF, cntColl := cntColl + 1);
        if y != x
            cntBad := cntBad + 1;
            return(Le);
        end
        lastRaw := x;
    end
    return(if(x = 0, 0, linear(x, minLevel, 0.01, maxLevel, 1)));
else
    return(NaN);
end
Scrittura livello
var level := 0;
if(Le > 0, level := round(linear(Le, 0.01, minLevel, 1, maxLevel)));
modbusw(SH, 510, uint16, (ShortAddress << 8) + level );
Attributi di servizio
${xml_short_address}
ShortAddress
${xml_device_type}
var x := 0; var y := 0; var rx := 0; var s := ""; var i := 0;
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x99);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    x := modbusr(SH, 511, uint16);
    if (x < 0xFF, return("DT" + x));
    if x = 0xFF
        while i < 8
            modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA7);
            sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
            y := modbusr(SH, 511, uint16);
            if y < 0xFE
                s := if(s = "", "DT" + y, s + ", DT" + y);
                i := i + 1;
            else
                i := 8;
            end
        loop
        return(if(s = "", "MASK", s));
    end
end

return("--")
Physical Min Level
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x9A);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if (x <= 0xFE, return(round((x / 0xFE) * 100) + " %"));
end

return("--")
Max Level
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA1);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if (x <= 0xFE, return(round((x / 0xFE) * 100) + " %"));
end

return("--")
Min Level
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA2);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if (x <= 0xFE, return(round((x / 0xFE) * 100) + " %"));
end

return("--")
Power Up Level
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA3);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if (x <= 0xFE, return(round((x / 0xFE) * 100) + " %"));
end

return("--")
System Failure Level
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA4);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if (x <= 0xFE, return(round((x / 0xFE) * 100) + " %"));
end

return("--")
${xml_groups}
var x := 0; var rx := 0;
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xC0);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var g1 := modbusr(SH, 511, uint16);
    if (g1 > 0xFF, return("--")); 

    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xC1);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var g2 := modbusr(SH, 511, uint16);
    if (g2 > 0xFF, return("--")); 

    var ret := "";

    if (getbit(g1, 0), ret := ret + "0");
    if (getbit(g1, 1), if (ret = "", ret := "1", ret := ret + ",1"));
    if (getbit(g1, 2), if (ret = "", ret := "2", ret := ret + ",2"));
    if (getbit(g1, 3), if (ret = "", ret := "3", ret := ret + ",3"));
    if (getbit(g1, 4), if (ret = "", ret := "4", ret := ret + ",4"));
    if (getbit(g1, 5), if (ret = "", ret := "5", ret := ret + ",5"));
    if (getbit(g1, 6), if (ret = "", ret := "6", ret := ret + ",6"));
    if (getbit(g1, 7), if (ret = "", ret := "7", ret := ret + ",7"));
    if (getbit(g2, 0), if (ret = "", ret := "8", ret := ret + ",8"));
    if (getbit(g2, 1), if (ret = "", ret := "9", ret := ret + ",9"));
    if (getbit(g2, 2), if (ret = "", ret := "10", ret := ret + ",10"));
    if (getbit(g2, 3), if (ret = "", ret := "11", ret := ret + ",11"));
    if (getbit(g2, 4), if (ret = "", ret := "12", ret := ret + ",12"));
    if (getbit(g2, 5), if (ret = "", ret := "13", ret := ret + ",13"));
    if (getbit(g2, 6), if (ret = "", ret := "14", ret := ret + ",14"));
    if (getbit(g2, 7), if (ret = "", ret := "15", ret := ret + ",15"));

    if (ret = "", return("None"), return(ret));
else
    return("--");
end
DALI Status
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x90);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if x <= 0xFF
        var s := "";
        if (getbit(x, 0), s := if(s = "", "gear failure", s + ", gear failure"));
        if (getbit(x, 1), s := if(s = "", "lamp failure", s + ", lamp failure"));
        if (getbit(x, 2), s := if(s = "", "lamp on", s + ", lamp on"));
        if (getbit(x, 3), s := if(s = "", "limit error", s + ", limit error"));
        if (getbit(x, 4), s := if(s = "", "fade running", s + ", fade running"));
        if (getbit(x, 5), s := if(s = "", "reset state", s + ", reset state"));
        if (getbit(x, 6), s := if(s = "", "missing short address", s + ", missing short address"));
        if (getbit(x, 7), s := if(s = "", "power cycle", s + ", power cycle"));
        var ign := if((ignGear = 1) and (ignLamp = 1), "gear and lamp failure", if(ignGear = 1, "gear failure", if(ignLamp = 1, "lamp failure", "")));
        return(if(s = "", "OK", s) + " (0x" + tostring(x, "X2") + ")" + if(ign = "", "", "; not raised: " + ign + " reported since start"));
    end
end

return("--")
Fade
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA5);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if x <= 0xFF
        var t := getbits(x, 4, 4);
        var ret := if(t = 0, "off", t + " (" + round(sqrt(power(2, t)) * 5) / 10 + " s)");
        modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA8);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
        var e := modbusr(SH, 511, uint16);
        if (t = 0 and e <= 0xFF and e != 0, ret := "extended 0x" + tostring(e, "X2"));
        return("fade time " + ret + ", fade rate " + getbits(x, 0, 4));
    end
end

return("--")
DALI Version
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x97);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if x <= 0xFF
        return(if(x >= 8, "DALI-2 " + getbits(x, 2, 6) + "." + getbits(x, 0, 2), "DALI-1") + " (" + x + ")");
    end
end

return("--")
Bus statistics
return("since start: queries " + cntQ + ", stale answers read away " + cntStale + ", no answer " + cntNone + ", collisions " + cntColl + ", rejected levels " + cntBad)
Azioni di servizio
${xml_add_to_group}
Parametri: Group ID (0–15 grp)
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x60 + grp);
${xml_remove_from_group}
Parametri: Group ID (0–15 grp)
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x70 + grp);
${xml_reset_to_default_settings}
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x20);
${xml_set_startup_levels}
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x21);
sleep(10);
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x2c);
sleep(10);
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x2d);
Disable fading
modbusw(SH, 541, uint16, 0xA300);
sleep(100);
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x2E);
sleep(100);
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x30);
Gear 12 Dimmer Lettura e scrittura

Dispositivo di controllo DALI all'indirizzo breve 12 — dimmer TapHome mappato su DALI arc power 0–100 % tramite H:510 LAMP LEVEL (scrittura) e QUERY ACTUAL LEVEL tramite H:511 (lettura), delimitato dai propri MIN / MAX LEVEL del gear.

Registro: H:511 → H:510 UInt16 Unità: % numeric
Attributi di servizio
Indirizzo breveIndirizzo breve DALI (0–63) target di questo dispositivo — fissato al momento dell'importazione del template e utilizzato nel byte alto di ogni scrittura Modbus.
Device TypeByte device-type DALI restituito da QUERY DEVICE TYPE (0x99) — riporta DT0 (fluorescente), DT6 (driver LED), DT8 (colore / tunable white) ecc., o -- quando non c'è risposta.
Physical Min LevelLivello minimo di dimmerazione imposto dall'hardware riportato dal gear — letto da QUERY PHYSICAL MIN LEVEL (0x9A), in percentuale.
Max LevelDALI MAX LEVEL configurato — letto da QUERY MAX LEVEL (0xA1); utilizzato come limite superiore durante la scalatura di TapHome 0–100 % su DALI arc power.
Min LevelDALI MIN LEVEL configurato — letto da QUERY MIN LEVEL (0xA2); utilizzato come limite inferiore durante la scalatura di TapHome 0–100 % su DALI arc power.
Power Up LevelLuminosità ripristinata dopo il ripristino dell'alimentazione del bus DALI — letta da QUERY POWER ON LEVEL (0xA3).
System Failure LevelLuminosità adottata quando il bus DALI perde la comunicazione per più di 500 ms — letta da QUERY SYSTEM FAILURE LEVEL (0xA4).
GruppiElenco separato da virgole dei gruppi DALI (0–15) a cui appartiene il gear — decodificato da QUERY GROUPS 0-7 (0xC0) e QUERY GROUPS 8-15 (0xC1); mostra None o ad es. 0,3,7.
Support Lamp FailureSe la lampada / driver supporta il rilevamento dei guasti della lampada — Yes / No / --. Gestisce l'errore Lamp failure! nel readscript periodico.
Support Power FailureSe la lampada / driver supporta il rilevamento dei guasti di alimentazione — Yes / No / --. Gestisce l'errore Power failure! nel readscript periodico.
DALI Version
Bus statistics
Azioni di servizio
Add to GroupAggiunge questo gear a un gruppo DALI (0–15) tramite ADD TO GROUP (0x60+grp) — auto-ripetuto entro 100 ms come richiesto per i comandi di configurazione DALI.
Remove from GroupRimuove questo gear da un gruppo DALI (0–15) tramite REMOVE FROM GROUP (0x70+grp).
Reset to Default SettingsInvia DALI RESET (0x20) — ripristina ogni parametro NVM del gear (livelli max / min / power-on / system-failure, appartenenza al gruppo, scene) al valore predefinito del produttore.
Set Startup LevelsCattura l'arc power corrente e la memorizza come Power On Level e System Failure Level — sequenza STORE ACTUAL LEVEL IN DTR (0x21) → STORE DTR AS POWER ON LEVEL (0x2C) → STORE DTR AS SYSTEM FAILURE LEVEL (0x2D).
Disable fading

Gear 12

Lettura (modulo)
var x := 0; var rx := 0; var y := 0;
if Status > 0
    Status := Status - 1;
    adderror(3, "Gear not responding!");
    return(0);
end

# checkStatus: ReadLevel resets it while the gear answers; statusPoll: QUERY STATUS at least once per 60 runs
checkStatus := checkStatus - 1;
statusPoll := statusPoll - 1;
if checkStatus < 1 or statusPoll < 1
    # an unread answer left in the gateway would be taken for this query: read it away and count it
    x := modbusr(SH, 511, uint16); if (x != 0x8000, cntStale := cntStale + 1);
    modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x90);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    x := modbusr(SH, 511, uint16);
    cntQ := cntQ + 1; if (x = 0x8000, cntNone := cntNone + 1); if (x = 0x20FF, cntColl := cntColl + 1);
    # a single lost answer happens on DALI: ask once more before declaring the gear missing
    if x = 0x8000
        x := modbusr(SH, 511, uint16); if (x != 0x8000, cntStale := cntStale + 1);
        modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x90);
        sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
        x := modbusr(SH, 511, uint16);
        cntQ := cntQ + 1; if (x = 0x8000, cntNone := cntNone + 1); if (x = 0x20FF, cntColl := cntColl + 1);
    end
    if x <= 0xFF
        # a changed failure bit must be read twice the same before it is taken
        if statusSeen = 1 and getbits(x, 0, 2) != getbits(gearStatus, 0, 2)
            y := modbusr(SH, 511, uint16); if (y != 0x8000, cntStale := cntStale + 1);
            modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x90);
            sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
            y := modbusr(SH, 511, uint16);
            cntQ := cntQ + 1; if (y = 0x8000, cntNone := cntNone + 1); if (y = 0x20FF, cntColl := cntColl + 1);
            if y != x
                cntBad := cntBad + 1;
                x := gearStatus;
            end
        end
        if statusSeen = 0
            ignGear := getbit(x, 0);
            ignLamp := getbit(x, 1);
            statusSeen := 1;
        end
        # a bit that clears ends its ignore, so a later failure is raised
        if (getbit(x, 0) = 0, ignGear := 0);
        if (getbit(x, 1) = 0, ignLamp := 0);
        gearStatus := x;
        checkStatus := 60;
        statusPoll := 60;
    else
        if x = 0x8000
            Status := RANDINT(10, 60);
            adderror(3, "Gear not responding!");
            return(0);
        end
    end
end

# messages last one run only, so they are raised from the stored status on every run
if ((getbit(gearStatus, 0) = 1) and (ignGear = 0), adderror(1, "Control gear failure!"));
if ((getbit(gearStatus, 1) = 1) and (ignLamp = 0), adderror(2, "Lamp failure!"));
Inizializzazione
var x := 0; var rx := 0;
# QUERY STATUS 0x90: every reply byte proves the gear is present; 0x8000 = no answer, 0x20FF = bus collision
# an unread answer left in the gateway would be taken for this query: read it away and count it
x := modbusr(SH, 511, uint16); if (x != 0x8000, cntStale := cntStale + 1);
modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x90);
sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
x := modbusr(SH, 511, uint16);
cntQ := cntQ + 1; if (x = 0x8000, cntNone := cntNone + 1); if (x = 0x20FF, cntColl := cntColl + 1);
statusSeen := 0;
if x <= 0xFF
    # failure bits a gear reports from its first answer are its permanent state, not an event: shown, not raised
    gearStatus := x;
    ignGear := getbit(x, 0);
    ignLamp := getbit(x, 1);
    statusSeen := 1;
    Status := 0;
else
    Status := RANDINT(1, 60);
end

if Status = 0
    x := modbusr(SH, 511, uint16); if (x != 0x8000, cntStale := cntStale + 1);
    modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA2);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    x := modbusr(SH, 511, uint16);
    cntQ := cntQ + 1; if (x = 0x8000, cntNone := cntNone + 1); if (x = 0x20FF, cntColl := cntColl + 1);
    if (x <= 0xFE, minLevel := x);

    x := modbusr(SH, 511, uint16); if (x != 0x8000, cntStale := cntStale + 1);
    modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA1);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    x := modbusr(SH, 511, uint16);
    cntQ := cntQ + 1; if (x = 0x8000, cntNone := cntNone + 1); if (x = 0x20FF, cntColl := cntColl + 1);
    if (x <= 0xFE, maxLevel := x);
end
Lettura livello
var x := 0; var rx := 0; var y := 0;
if Status = 0
    if minLevel = 0
        # an unread answer left in the gateway would be taken for this query: read it away and count it
        x := modbusr(SH, 511, uint16); if (x != 0x8000, cntStale := cntStale + 1);
        modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA2);
        sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
        x := modbusr(SH, 511, uint16);
        cntQ := cntQ + 1; if (x = 0x8000, cntNone := cntNone + 1); if (x = 0x20FF, cntColl := cntColl + 1);
        if (x <= 0xFE, minLevel := x);
    end
    x := modbusr(SH, 511, uint16); if (x != 0x8000, cntStale := cntStale + 1);
    modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA0);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    x := modbusr(SH, 511, uint16);
    cntQ := cntQ + 1; if (x = 0x8000, cntNone := cntNone + 1); if (x = 0x20FF, cntColl := cntColl + 1);
    if (x != 0x8000 or rx, checkStatus := 60);
    # 0xFF = MASK, 0x20FF = collision, 0x8000 = no answer: keep the last level instead of a phantom value
    if x > 0xFE
        return(Le);
    end
    # an actual level is 0 or between the gear's min and max: anything else is not this gear's answer
    if x > 0 and x < minLevel
        cntBad := cntBad + 1;
        return(Le);
    end
    # a changed level must be read twice the same before it is taken
    if x != lastRaw
        y := modbusr(SH, 511, uint16); if (y != 0x8000, cntStale := cntStale + 1);
        modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA0);
        sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
        y := modbusr(SH, 511, uint16);
        cntQ := cntQ + 1; if (y = 0x8000, cntNone := cntNone + 1); if (y = 0x20FF, cntColl := cntColl + 1);
        if y != x
            cntBad := cntBad + 1;
            return(Le);
        end
        lastRaw := x;
    end
    return(if(x = 0, 0, linear(x, minLevel, 0.01, maxLevel, 1)));
else
    return(NaN);
end
Scrittura livello
var level := 0;
if(Le > 0, level := round(linear(Le, 0.01, minLevel, 1, maxLevel)));
modbusw(SH, 510, uint16, (ShortAddress << 8) + level );
Attributi di servizio
${xml_short_address}
ShortAddress
${xml_device_type}
var x := 0; var y := 0; var rx := 0; var s := ""; var i := 0;
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x99);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    x := modbusr(SH, 511, uint16);
    if (x < 0xFF, return("DT" + x));
    if x = 0xFF
        while i < 8
            modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA7);
            sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
            y := modbusr(SH, 511, uint16);
            if y < 0xFE
                s := if(s = "", "DT" + y, s + ", DT" + y);
                i := i + 1;
            else
                i := 8;
            end
        loop
        return(if(s = "", "MASK", s));
    end
end

return("--")
Physical Min Level
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x9A);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if (x <= 0xFE, return(round((x / 0xFE) * 100) + " %"));
end

return("--")
Max Level
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA1);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if (x <= 0xFE, return(round((x / 0xFE) * 100) + " %"));
end

return("--")
Min Level
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA2);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if (x <= 0xFE, return(round((x / 0xFE) * 100) + " %"));
end

return("--")
Power Up Level
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA3);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if (x <= 0xFE, return(round((x / 0xFE) * 100) + " %"));
end

return("--")
System Failure Level
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA4);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if (x <= 0xFE, return(round((x / 0xFE) * 100) + " %"));
end

return("--")
${xml_groups}
var x := 0; var rx := 0;
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xC0);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var g1 := modbusr(SH, 511, uint16);
    if (g1 > 0xFF, return("--")); 

    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xC1);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var g2 := modbusr(SH, 511, uint16);
    if (g2 > 0xFF, return("--")); 

    var ret := "";

    if (getbit(g1, 0), ret := ret + "0");
    if (getbit(g1, 1), if (ret = "", ret := "1", ret := ret + ",1"));
    if (getbit(g1, 2), if (ret = "", ret := "2", ret := ret + ",2"));
    if (getbit(g1, 3), if (ret = "", ret := "3", ret := ret + ",3"));
    if (getbit(g1, 4), if (ret = "", ret := "4", ret := ret + ",4"));
    if (getbit(g1, 5), if (ret = "", ret := "5", ret := ret + ",5"));
    if (getbit(g1, 6), if (ret = "", ret := "6", ret := ret + ",6"));
    if (getbit(g1, 7), if (ret = "", ret := "7", ret := ret + ",7"));
    if (getbit(g2, 0), if (ret = "", ret := "8", ret := ret + ",8"));
    if (getbit(g2, 1), if (ret = "", ret := "9", ret := ret + ",9"));
    if (getbit(g2, 2), if (ret = "", ret := "10", ret := ret + ",10"));
    if (getbit(g2, 3), if (ret = "", ret := "11", ret := ret + ",11"));
    if (getbit(g2, 4), if (ret = "", ret := "12", ret := ret + ",12"));
    if (getbit(g2, 5), if (ret = "", ret := "13", ret := ret + ",13"));
    if (getbit(g2, 6), if (ret = "", ret := "14", ret := ret + ",14"));
    if (getbit(g2, 7), if (ret = "", ret := "15", ret := ret + ",15"));

    if (ret = "", return("None"), return(ret));
else
    return("--");
end
DALI Status
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x90);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if x <= 0xFF
        var s := "";
        if (getbit(x, 0), s := if(s = "", "gear failure", s + ", gear failure"));
        if (getbit(x, 1), s := if(s = "", "lamp failure", s + ", lamp failure"));
        if (getbit(x, 2), s := if(s = "", "lamp on", s + ", lamp on"));
        if (getbit(x, 3), s := if(s = "", "limit error", s + ", limit error"));
        if (getbit(x, 4), s := if(s = "", "fade running", s + ", fade running"));
        if (getbit(x, 5), s := if(s = "", "reset state", s + ", reset state"));
        if (getbit(x, 6), s := if(s = "", "missing short address", s + ", missing short address"));
        if (getbit(x, 7), s := if(s = "", "power cycle", s + ", power cycle"));
        var ign := if((ignGear = 1) and (ignLamp = 1), "gear and lamp failure", if(ignGear = 1, "gear failure", if(ignLamp = 1, "lamp failure", "")));
        return(if(s = "", "OK", s) + " (0x" + tostring(x, "X2") + ")" + if(ign = "", "", "; not raised: " + ign + " reported since start"));
    end
end

return("--")
Fade
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA5);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if x <= 0xFF
        var t := getbits(x, 4, 4);
        var ret := if(t = 0, "off", t + " (" + round(sqrt(power(2, t)) * 5) / 10 + " s)");
        modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA8);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
        var e := modbusr(SH, 511, uint16);
        if (t = 0 and e <= 0xFF and e != 0, ret := "extended 0x" + tostring(e, "X2"));
        return("fade time " + ret + ", fade rate " + getbits(x, 0, 4));
    end
end

return("--")
DALI Version
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x97);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if x <= 0xFF
        return(if(x >= 8, "DALI-2 " + getbits(x, 2, 6) + "." + getbits(x, 0, 2), "DALI-1") + " (" + x + ")");
    end
end

return("--")
Bus statistics
return("since start: queries " + cntQ + ", stale answers read away " + cntStale + ", no answer " + cntNone + ", collisions " + cntColl + ", rejected levels " + cntBad)
Azioni di servizio
${xml_add_to_group}
Parametri: Group ID (0–15 grp)
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x60 + grp);
${xml_remove_from_group}
Parametri: Group ID (0–15 grp)
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x70 + grp);
${xml_reset_to_default_settings}
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x20);
${xml_set_startup_levels}
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x21);
sleep(10);
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x2c);
sleep(10);
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x2d);
Disable fading
modbusw(SH, 541, uint16, 0xA300);
sleep(100);
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x2E);
sleep(100);
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x30);
Gear 13 Dimmer Lettura e scrittura

Dispositivo di controllo DALI all'indirizzo breve 13 — dimmer TapHome mappato su DALI arc power 0–100 % tramite H:510 LAMP LEVEL (scrittura) e QUERY ACTUAL LEVEL tramite H:511 (lettura), delimitato dai propri MIN / MAX LEVEL del gear.

Registro: H:511 → H:510 UInt16 Unità: % numeric
Attributi di servizio
Indirizzo breveIndirizzo breve DALI (0–63) target di questo dispositivo — fissato al momento dell'importazione del template e utilizzato nel byte alto di ogni scrittura Modbus.
Device TypeByte device-type DALI restituito da QUERY DEVICE TYPE (0x99) — riporta DT0 (fluorescente), DT6 (driver LED), DT8 (colore / tunable white) ecc., o -- quando non c'è risposta.
Physical Min LevelLivello minimo di dimmerazione imposto dall'hardware riportato dal gear — letto da QUERY PHYSICAL MIN LEVEL (0x9A), in percentuale.
Max LevelDALI MAX LEVEL configurato — letto da QUERY MAX LEVEL (0xA1); utilizzato come limite superiore durante la scalatura di TapHome 0–100 % su DALI arc power.
Min LevelDALI MIN LEVEL configurato — letto da QUERY MIN LEVEL (0xA2); utilizzato come limite inferiore durante la scalatura di TapHome 0–100 % su DALI arc power.
Power Up LevelLuminosità ripristinata dopo il ripristino dell'alimentazione del bus DALI — letta da QUERY POWER ON LEVEL (0xA3).
System Failure LevelLuminosità adottata quando il bus DALI perde la comunicazione per più di 500 ms — letta da QUERY SYSTEM FAILURE LEVEL (0xA4).
GruppiElenco separato da virgole dei gruppi DALI (0–15) a cui appartiene il gear — decodificato da QUERY GROUPS 0-7 (0xC0) e QUERY GROUPS 8-15 (0xC1); mostra None o ad es. 0,3,7.
Support Lamp FailureSe la lampada / driver supporta il rilevamento dei guasti della lampada — Yes / No / --. Gestisce l'errore Lamp failure! nel readscript periodico.
Support Power FailureSe la lampada / driver supporta il rilevamento dei guasti di alimentazione — Yes / No / --. Gestisce l'errore Power failure! nel readscript periodico.
DALI Version
Bus statistics
Azioni di servizio
Add to GroupAggiunge questo gear a un gruppo DALI (0–15) tramite ADD TO GROUP (0x60+grp) — auto-ripetuto entro 100 ms come richiesto per i comandi di configurazione DALI.
Remove from GroupRimuove questo gear da un gruppo DALI (0–15) tramite REMOVE FROM GROUP (0x70+grp).
Reset to Default SettingsInvia DALI RESET (0x20) — ripristina ogni parametro NVM del gear (livelli max / min / power-on / system-failure, appartenenza al gruppo, scene) al valore predefinito del produttore.
Set Startup LevelsCattura l'arc power corrente e la memorizza come Power On Level e System Failure Level — sequenza STORE ACTUAL LEVEL IN DTR (0x21) → STORE DTR AS POWER ON LEVEL (0x2C) → STORE DTR AS SYSTEM FAILURE LEVEL (0x2D).
Disable fading

Gear 13

Lettura (modulo)
var x := 0; var rx := 0; var y := 0;
if Status > 0
    Status := Status - 1;
    adderror(3, "Gear not responding!");
    return(0);
end

# checkStatus: ReadLevel resets it while the gear answers; statusPoll: QUERY STATUS at least once per 60 runs
checkStatus := checkStatus - 1;
statusPoll := statusPoll - 1;
if checkStatus < 1 or statusPoll < 1
    # an unread answer left in the gateway would be taken for this query: read it away and count it
    x := modbusr(SH, 511, uint16); if (x != 0x8000, cntStale := cntStale + 1);
    modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x90);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    x := modbusr(SH, 511, uint16);
    cntQ := cntQ + 1; if (x = 0x8000, cntNone := cntNone + 1); if (x = 0x20FF, cntColl := cntColl + 1);
    # a single lost answer happens on DALI: ask once more before declaring the gear missing
    if x = 0x8000
        x := modbusr(SH, 511, uint16); if (x != 0x8000, cntStale := cntStale + 1);
        modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x90);
        sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
        x := modbusr(SH, 511, uint16);
        cntQ := cntQ + 1; if (x = 0x8000, cntNone := cntNone + 1); if (x = 0x20FF, cntColl := cntColl + 1);
    end
    if x <= 0xFF
        # a changed failure bit must be read twice the same before it is taken
        if statusSeen = 1 and getbits(x, 0, 2) != getbits(gearStatus, 0, 2)
            y := modbusr(SH, 511, uint16); if (y != 0x8000, cntStale := cntStale + 1);
            modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x90);
            sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
            y := modbusr(SH, 511, uint16);
            cntQ := cntQ + 1; if (y = 0x8000, cntNone := cntNone + 1); if (y = 0x20FF, cntColl := cntColl + 1);
            if y != x
                cntBad := cntBad + 1;
                x := gearStatus;
            end
        end
        if statusSeen = 0
            ignGear := getbit(x, 0);
            ignLamp := getbit(x, 1);
            statusSeen := 1;
        end
        # a bit that clears ends its ignore, so a later failure is raised
        if (getbit(x, 0) = 0, ignGear := 0);
        if (getbit(x, 1) = 0, ignLamp := 0);
        gearStatus := x;
        checkStatus := 60;
        statusPoll := 60;
    else
        if x = 0x8000
            Status := RANDINT(10, 60);
            adderror(3, "Gear not responding!");
            return(0);
        end
    end
end

# messages last one run only, so they are raised from the stored status on every run
if ((getbit(gearStatus, 0) = 1) and (ignGear = 0), adderror(1, "Control gear failure!"));
if ((getbit(gearStatus, 1) = 1) and (ignLamp = 0), adderror(2, "Lamp failure!"));
Inizializzazione
var x := 0; var rx := 0;
# QUERY STATUS 0x90: every reply byte proves the gear is present; 0x8000 = no answer, 0x20FF = bus collision
# an unread answer left in the gateway would be taken for this query: read it away and count it
x := modbusr(SH, 511, uint16); if (x != 0x8000, cntStale := cntStale + 1);
modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x90);
sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
x := modbusr(SH, 511, uint16);
cntQ := cntQ + 1; if (x = 0x8000, cntNone := cntNone + 1); if (x = 0x20FF, cntColl := cntColl + 1);
statusSeen := 0;
if x <= 0xFF
    # failure bits a gear reports from its first answer are its permanent state, not an event: shown, not raised
    gearStatus := x;
    ignGear := getbit(x, 0);
    ignLamp := getbit(x, 1);
    statusSeen := 1;
    Status := 0;
else
    Status := RANDINT(1, 60);
end

if Status = 0
    x := modbusr(SH, 511, uint16); if (x != 0x8000, cntStale := cntStale + 1);
    modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA2);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    x := modbusr(SH, 511, uint16);
    cntQ := cntQ + 1; if (x = 0x8000, cntNone := cntNone + 1); if (x = 0x20FF, cntColl := cntColl + 1);
    if (x <= 0xFE, minLevel := x);

    x := modbusr(SH, 511, uint16); if (x != 0x8000, cntStale := cntStale + 1);
    modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA1);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    x := modbusr(SH, 511, uint16);
    cntQ := cntQ + 1; if (x = 0x8000, cntNone := cntNone + 1); if (x = 0x20FF, cntColl := cntColl + 1);
    if (x <= 0xFE, maxLevel := x);
end
Lettura livello
var x := 0; var rx := 0; var y := 0;
if Status = 0
    if minLevel = 0
        # an unread answer left in the gateway would be taken for this query: read it away and count it
        x := modbusr(SH, 511, uint16); if (x != 0x8000, cntStale := cntStale + 1);
        modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA2);
        sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
        x := modbusr(SH, 511, uint16);
        cntQ := cntQ + 1; if (x = 0x8000, cntNone := cntNone + 1); if (x = 0x20FF, cntColl := cntColl + 1);
        if (x <= 0xFE, minLevel := x);
    end
    x := modbusr(SH, 511, uint16); if (x != 0x8000, cntStale := cntStale + 1);
    modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA0);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    x := modbusr(SH, 511, uint16);
    cntQ := cntQ + 1; if (x = 0x8000, cntNone := cntNone + 1); if (x = 0x20FF, cntColl := cntColl + 1);
    if (x != 0x8000 or rx, checkStatus := 60);
    # 0xFF = MASK, 0x20FF = collision, 0x8000 = no answer: keep the last level instead of a phantom value
    if x > 0xFE
        return(Le);
    end
    # an actual level is 0 or between the gear's min and max: anything else is not this gear's answer
    if x > 0 and x < minLevel
        cntBad := cntBad + 1;
        return(Le);
    end
    # a changed level must be read twice the same before it is taken
    if x != lastRaw
        y := modbusr(SH, 511, uint16); if (y != 0x8000, cntStale := cntStale + 1);
        modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA0);
        sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
        y := modbusr(SH, 511, uint16);
        cntQ := cntQ + 1; if (y = 0x8000, cntNone := cntNone + 1); if (y = 0x20FF, cntColl := cntColl + 1);
        if y != x
            cntBad := cntBad + 1;
            return(Le);
        end
        lastRaw := x;
    end
    return(if(x = 0, 0, linear(x, minLevel, 0.01, maxLevel, 1)));
else
    return(NaN);
end
Scrittura livello
var level := 0;
if(Le > 0, level := round(linear(Le, 0.01, minLevel, 1, maxLevel)));
modbusw(SH, 510, uint16, (ShortAddress << 8) + level );
Attributi di servizio
${xml_short_address}
ShortAddress
${xml_device_type}
var x := 0; var y := 0; var rx := 0; var s := ""; var i := 0;
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x99);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    x := modbusr(SH, 511, uint16);
    if (x < 0xFF, return("DT" + x));
    if x = 0xFF
        while i < 8
            modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA7);
            sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
            y := modbusr(SH, 511, uint16);
            if y < 0xFE
                s := if(s = "", "DT" + y, s + ", DT" + y);
                i := i + 1;
            else
                i := 8;
            end
        loop
        return(if(s = "", "MASK", s));
    end
end

return("--")
Physical Min Level
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x9A);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if (x <= 0xFE, return(round((x / 0xFE) * 100) + " %"));
end

return("--")
Max Level
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA1);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if (x <= 0xFE, return(round((x / 0xFE) * 100) + " %"));
end

return("--")
Min Level
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA2);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if (x <= 0xFE, return(round((x / 0xFE) * 100) + " %"));
end

return("--")
Power Up Level
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA3);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if (x <= 0xFE, return(round((x / 0xFE) * 100) + " %"));
end

return("--")
System Failure Level
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA4);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if (x <= 0xFE, return(round((x / 0xFE) * 100) + " %"));
end

return("--")
${xml_groups}
var x := 0; var rx := 0;
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xC0);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var g1 := modbusr(SH, 511, uint16);
    if (g1 > 0xFF, return("--")); 

    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xC1);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var g2 := modbusr(SH, 511, uint16);
    if (g2 > 0xFF, return("--")); 

    var ret := "";

    if (getbit(g1, 0), ret := ret + "0");
    if (getbit(g1, 1), if (ret = "", ret := "1", ret := ret + ",1"));
    if (getbit(g1, 2), if (ret = "", ret := "2", ret := ret + ",2"));
    if (getbit(g1, 3), if (ret = "", ret := "3", ret := ret + ",3"));
    if (getbit(g1, 4), if (ret = "", ret := "4", ret := ret + ",4"));
    if (getbit(g1, 5), if (ret = "", ret := "5", ret := ret + ",5"));
    if (getbit(g1, 6), if (ret = "", ret := "6", ret := ret + ",6"));
    if (getbit(g1, 7), if (ret = "", ret := "7", ret := ret + ",7"));
    if (getbit(g2, 0), if (ret = "", ret := "8", ret := ret + ",8"));
    if (getbit(g2, 1), if (ret = "", ret := "9", ret := ret + ",9"));
    if (getbit(g2, 2), if (ret = "", ret := "10", ret := ret + ",10"));
    if (getbit(g2, 3), if (ret = "", ret := "11", ret := ret + ",11"));
    if (getbit(g2, 4), if (ret = "", ret := "12", ret := ret + ",12"));
    if (getbit(g2, 5), if (ret = "", ret := "13", ret := ret + ",13"));
    if (getbit(g2, 6), if (ret = "", ret := "14", ret := ret + ",14"));
    if (getbit(g2, 7), if (ret = "", ret := "15", ret := ret + ",15"));

    if (ret = "", return("None"), return(ret));
else
    return("--");
end
DALI Status
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x90);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if x <= 0xFF
        var s := "";
        if (getbit(x, 0), s := if(s = "", "gear failure", s + ", gear failure"));
        if (getbit(x, 1), s := if(s = "", "lamp failure", s + ", lamp failure"));
        if (getbit(x, 2), s := if(s = "", "lamp on", s + ", lamp on"));
        if (getbit(x, 3), s := if(s = "", "limit error", s + ", limit error"));
        if (getbit(x, 4), s := if(s = "", "fade running", s + ", fade running"));
        if (getbit(x, 5), s := if(s = "", "reset state", s + ", reset state"));
        if (getbit(x, 6), s := if(s = "", "missing short address", s + ", missing short address"));
        if (getbit(x, 7), s := if(s = "", "power cycle", s + ", power cycle"));
        var ign := if((ignGear = 1) and (ignLamp = 1), "gear and lamp failure", if(ignGear = 1, "gear failure", if(ignLamp = 1, "lamp failure", "")));
        return(if(s = "", "OK", s) + " (0x" + tostring(x, "X2") + ")" + if(ign = "", "", "; not raised: " + ign + " reported since start"));
    end
end

return("--")
Fade
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA5);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if x <= 0xFF
        var t := getbits(x, 4, 4);
        var ret := if(t = 0, "off", t + " (" + round(sqrt(power(2, t)) * 5) / 10 + " s)");
        modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA8);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
        var e := modbusr(SH, 511, uint16);
        if (t = 0 and e <= 0xFF and e != 0, ret := "extended 0x" + tostring(e, "X2"));
        return("fade time " + ret + ", fade rate " + getbits(x, 0, 4));
    end
end

return("--")
DALI Version
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x97);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if x <= 0xFF
        return(if(x >= 8, "DALI-2 " + getbits(x, 2, 6) + "." + getbits(x, 0, 2), "DALI-1") + " (" + x + ")");
    end
end

return("--")
Bus statistics
return("since start: queries " + cntQ + ", stale answers read away " + cntStale + ", no answer " + cntNone + ", collisions " + cntColl + ", rejected levels " + cntBad)
Azioni di servizio
${xml_add_to_group}
Parametri: Group ID (0–15 grp)
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x60 + grp);
${xml_remove_from_group}
Parametri: Group ID (0–15 grp)
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x70 + grp);
${xml_reset_to_default_settings}
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x20);
${xml_set_startup_levels}
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x21);
sleep(10);
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x2c);
sleep(10);
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x2d);
Disable fading
modbusw(SH, 541, uint16, 0xA300);
sleep(100);
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x2E);
sleep(100);
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x30);
Gear 14 Dimmer Lettura e scrittura

Dispositivo di controllo DALI all'indirizzo breve 14 — dimmer TapHome mappato su DALI arc power 0–100 % tramite H:510 LAMP LEVEL (scrittura) e QUERY ACTUAL LEVEL tramite H:511 (lettura), delimitato dai propri MIN / MAX LEVEL del gear.

Registro: H:511 → H:510 UInt16 Unità: % numeric
Attributi di servizio
Indirizzo breveIndirizzo breve DALI (0–63) target di questo dispositivo — fissato al momento dell'importazione del template e utilizzato nel byte alto di ogni scrittura Modbus.
Device TypeByte device-type DALI restituito da QUERY DEVICE TYPE (0x99) — riporta DT0 (fluorescente), DT6 (driver LED), DT8 (colore / tunable white) ecc., o -- quando non c'è risposta.
Physical Min LevelLivello minimo di dimmerazione imposto dall'hardware riportato dal gear — letto da QUERY PHYSICAL MIN LEVEL (0x9A), in percentuale.
Max LevelDALI MAX LEVEL configurato — letto da QUERY MAX LEVEL (0xA1); utilizzato come limite superiore durante la scalatura di TapHome 0–100 % su DALI arc power.
Min LevelDALI MIN LEVEL configurato — letto da QUERY MIN LEVEL (0xA2); utilizzato come limite inferiore durante la scalatura di TapHome 0–100 % su DALI arc power.
Power Up LevelLuminosità ripristinata dopo il ripristino dell'alimentazione del bus DALI — letta da QUERY POWER ON LEVEL (0xA3).
System Failure LevelLuminosità adottata quando il bus DALI perde la comunicazione per più di 500 ms — letta da QUERY SYSTEM FAILURE LEVEL (0xA4).
GruppiElenco separato da virgole dei gruppi DALI (0–15) a cui appartiene il gear — decodificato da QUERY GROUPS 0-7 (0xC0) e QUERY GROUPS 8-15 (0xC1); mostra None o ad es. 0,3,7.
Support Lamp FailureSe la lampada / driver supporta il rilevamento dei guasti della lampada — Yes / No / --. Gestisce l'errore Lamp failure! nel readscript periodico.
Support Power FailureSe la lampada / driver supporta il rilevamento dei guasti di alimentazione — Yes / No / --. Gestisce l'errore Power failure! nel readscript periodico.
DALI Version
Bus statistics
Azioni di servizio
Add to GroupAggiunge questo gear a un gruppo DALI (0–15) tramite ADD TO GROUP (0x60+grp) — auto-ripetuto entro 100 ms come richiesto per i comandi di configurazione DALI.
Remove from GroupRimuove questo gear da un gruppo DALI (0–15) tramite REMOVE FROM GROUP (0x70+grp).
Reset to Default SettingsInvia DALI RESET (0x20) — ripristina ogni parametro NVM del gear (livelli max / min / power-on / system-failure, appartenenza al gruppo, scene) al valore predefinito del produttore.
Set Startup LevelsCattura l'arc power corrente e la memorizza come Power On Level e System Failure Level — sequenza STORE ACTUAL LEVEL IN DTR (0x21) → STORE DTR AS POWER ON LEVEL (0x2C) → STORE DTR AS SYSTEM FAILURE LEVEL (0x2D).
Disable fading

Gear 14

Lettura (modulo)
var x := 0; var rx := 0; var y := 0;
if Status > 0
    Status := Status - 1;
    adderror(3, "Gear not responding!");
    return(0);
end

# checkStatus: ReadLevel resets it while the gear answers; statusPoll: QUERY STATUS at least once per 60 runs
checkStatus := checkStatus - 1;
statusPoll := statusPoll - 1;
if checkStatus < 1 or statusPoll < 1
    # an unread answer left in the gateway would be taken for this query: read it away and count it
    x := modbusr(SH, 511, uint16); if (x != 0x8000, cntStale := cntStale + 1);
    modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x90);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    x := modbusr(SH, 511, uint16);
    cntQ := cntQ + 1; if (x = 0x8000, cntNone := cntNone + 1); if (x = 0x20FF, cntColl := cntColl + 1);
    # a single lost answer happens on DALI: ask once more before declaring the gear missing
    if x = 0x8000
        x := modbusr(SH, 511, uint16); if (x != 0x8000, cntStale := cntStale + 1);
        modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x90);
        sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
        x := modbusr(SH, 511, uint16);
        cntQ := cntQ + 1; if (x = 0x8000, cntNone := cntNone + 1); if (x = 0x20FF, cntColl := cntColl + 1);
    end
    if x <= 0xFF
        # a changed failure bit must be read twice the same before it is taken
        if statusSeen = 1 and getbits(x, 0, 2) != getbits(gearStatus, 0, 2)
            y := modbusr(SH, 511, uint16); if (y != 0x8000, cntStale := cntStale + 1);
            modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x90);
            sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
            y := modbusr(SH, 511, uint16);
            cntQ := cntQ + 1; if (y = 0x8000, cntNone := cntNone + 1); if (y = 0x20FF, cntColl := cntColl + 1);
            if y != x
                cntBad := cntBad + 1;
                x := gearStatus;
            end
        end
        if statusSeen = 0
            ignGear := getbit(x, 0);
            ignLamp := getbit(x, 1);
            statusSeen := 1;
        end
        # a bit that clears ends its ignore, so a later failure is raised
        if (getbit(x, 0) = 0, ignGear := 0);
        if (getbit(x, 1) = 0, ignLamp := 0);
        gearStatus := x;
        checkStatus := 60;
        statusPoll := 60;
    else
        if x = 0x8000
            Status := RANDINT(10, 60);
            adderror(3, "Gear not responding!");
            return(0);
        end
    end
end

# messages last one run only, so they are raised from the stored status on every run
if ((getbit(gearStatus, 0) = 1) and (ignGear = 0), adderror(1, "Control gear failure!"));
if ((getbit(gearStatus, 1) = 1) and (ignLamp = 0), adderror(2, "Lamp failure!"));
Inizializzazione
var x := 0; var rx := 0;
# QUERY STATUS 0x90: every reply byte proves the gear is present; 0x8000 = no answer, 0x20FF = bus collision
# an unread answer left in the gateway would be taken for this query: read it away and count it
x := modbusr(SH, 511, uint16); if (x != 0x8000, cntStale := cntStale + 1);
modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x90);
sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
x := modbusr(SH, 511, uint16);
cntQ := cntQ + 1; if (x = 0x8000, cntNone := cntNone + 1); if (x = 0x20FF, cntColl := cntColl + 1);
statusSeen := 0;
if x <= 0xFF
    # failure bits a gear reports from its first answer are its permanent state, not an event: shown, not raised
    gearStatus := x;
    ignGear := getbit(x, 0);
    ignLamp := getbit(x, 1);
    statusSeen := 1;
    Status := 0;
else
    Status := RANDINT(1, 60);
end

if Status = 0
    x := modbusr(SH, 511, uint16); if (x != 0x8000, cntStale := cntStale + 1);
    modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA2);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    x := modbusr(SH, 511, uint16);
    cntQ := cntQ + 1; if (x = 0x8000, cntNone := cntNone + 1); if (x = 0x20FF, cntColl := cntColl + 1);
    if (x <= 0xFE, minLevel := x);

    x := modbusr(SH, 511, uint16); if (x != 0x8000, cntStale := cntStale + 1);
    modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA1);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    x := modbusr(SH, 511, uint16);
    cntQ := cntQ + 1; if (x = 0x8000, cntNone := cntNone + 1); if (x = 0x20FF, cntColl := cntColl + 1);
    if (x <= 0xFE, maxLevel := x);
end
Lettura livello
var x := 0; var rx := 0; var y := 0;
if Status = 0
    if minLevel = 0
        # an unread answer left in the gateway would be taken for this query: read it away and count it
        x := modbusr(SH, 511, uint16); if (x != 0x8000, cntStale := cntStale + 1);
        modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA2);
        sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
        x := modbusr(SH, 511, uint16);
        cntQ := cntQ + 1; if (x = 0x8000, cntNone := cntNone + 1); if (x = 0x20FF, cntColl := cntColl + 1);
        if (x <= 0xFE, minLevel := x);
    end
    x := modbusr(SH, 511, uint16); if (x != 0x8000, cntStale := cntStale + 1);
    modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA0);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    x := modbusr(SH, 511, uint16);
    cntQ := cntQ + 1; if (x = 0x8000, cntNone := cntNone + 1); if (x = 0x20FF, cntColl := cntColl + 1);
    if (x != 0x8000 or rx, checkStatus := 60);
    # 0xFF = MASK, 0x20FF = collision, 0x8000 = no answer: keep the last level instead of a phantom value
    if x > 0xFE
        return(Le);
    end
    # an actual level is 0 or between the gear's min and max: anything else is not this gear's answer
    if x > 0 and x < minLevel
        cntBad := cntBad + 1;
        return(Le);
    end
    # a changed level must be read twice the same before it is taken
    if x != lastRaw
        y := modbusr(SH, 511, uint16); if (y != 0x8000, cntStale := cntStale + 1);
        modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA0);
        sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
        y := modbusr(SH, 511, uint16);
        cntQ := cntQ + 1; if (y = 0x8000, cntNone := cntNone + 1); if (y = 0x20FF, cntColl := cntColl + 1);
        if y != x
            cntBad := cntBad + 1;
            return(Le);
        end
        lastRaw := x;
    end
    return(if(x = 0, 0, linear(x, minLevel, 0.01, maxLevel, 1)));
else
    return(NaN);
end
Scrittura livello
var level := 0;
if(Le > 0, level := round(linear(Le, 0.01, minLevel, 1, maxLevel)));
modbusw(SH, 510, uint16, (ShortAddress << 8) + level );
Attributi di servizio
${xml_short_address}
ShortAddress
${xml_device_type}
var x := 0; var y := 0; var rx := 0; var s := ""; var i := 0;
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x99);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    x := modbusr(SH, 511, uint16);
    if (x < 0xFF, return("DT" + x));
    if x = 0xFF
        while i < 8
            modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA7);
            sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
            y := modbusr(SH, 511, uint16);
            if y < 0xFE
                s := if(s = "", "DT" + y, s + ", DT" + y);
                i := i + 1;
            else
                i := 8;
            end
        loop
        return(if(s = "", "MASK", s));
    end
end

return("--")
Physical Min Level
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x9A);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if (x <= 0xFE, return(round((x / 0xFE) * 100) + " %"));
end

return("--")
Max Level
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA1);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if (x <= 0xFE, return(round((x / 0xFE) * 100) + " %"));
end

return("--")
Min Level
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA2);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if (x <= 0xFE, return(round((x / 0xFE) * 100) + " %"));
end

return("--")
Power Up Level
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA3);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if (x <= 0xFE, return(round((x / 0xFE) * 100) + " %"));
end

return("--")
System Failure Level
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA4);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if (x <= 0xFE, return(round((x / 0xFE) * 100) + " %"));
end

return("--")
${xml_groups}
var x := 0; var rx := 0;
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xC0);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var g1 := modbusr(SH, 511, uint16);
    if (g1 > 0xFF, return("--")); 

    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xC1);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var g2 := modbusr(SH, 511, uint16);
    if (g2 > 0xFF, return("--")); 

    var ret := "";

    if (getbit(g1, 0), ret := ret + "0");
    if (getbit(g1, 1), if (ret = "", ret := "1", ret := ret + ",1"));
    if (getbit(g1, 2), if (ret = "", ret := "2", ret := ret + ",2"));
    if (getbit(g1, 3), if (ret = "", ret := "3", ret := ret + ",3"));
    if (getbit(g1, 4), if (ret = "", ret := "4", ret := ret + ",4"));
    if (getbit(g1, 5), if (ret = "", ret := "5", ret := ret + ",5"));
    if (getbit(g1, 6), if (ret = "", ret := "6", ret := ret + ",6"));
    if (getbit(g1, 7), if (ret = "", ret := "7", ret := ret + ",7"));
    if (getbit(g2, 0), if (ret = "", ret := "8", ret := ret + ",8"));
    if (getbit(g2, 1), if (ret = "", ret := "9", ret := ret + ",9"));
    if (getbit(g2, 2), if (ret = "", ret := "10", ret := ret + ",10"));
    if (getbit(g2, 3), if (ret = "", ret := "11", ret := ret + ",11"));
    if (getbit(g2, 4), if (ret = "", ret := "12", ret := ret + ",12"));
    if (getbit(g2, 5), if (ret = "", ret := "13", ret := ret + ",13"));
    if (getbit(g2, 6), if (ret = "", ret := "14", ret := ret + ",14"));
    if (getbit(g2, 7), if (ret = "", ret := "15", ret := ret + ",15"));

    if (ret = "", return("None"), return(ret));
else
    return("--");
end
DALI Status
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x90);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if x <= 0xFF
        var s := "";
        if (getbit(x, 0), s := if(s = "", "gear failure", s + ", gear failure"));
        if (getbit(x, 1), s := if(s = "", "lamp failure", s + ", lamp failure"));
        if (getbit(x, 2), s := if(s = "", "lamp on", s + ", lamp on"));
        if (getbit(x, 3), s := if(s = "", "limit error", s + ", limit error"));
        if (getbit(x, 4), s := if(s = "", "fade running", s + ", fade running"));
        if (getbit(x, 5), s := if(s = "", "reset state", s + ", reset state"));
        if (getbit(x, 6), s := if(s = "", "missing short address", s + ", missing short address"));
        if (getbit(x, 7), s := if(s = "", "power cycle", s + ", power cycle"));
        var ign := if((ignGear = 1) and (ignLamp = 1), "gear and lamp failure", if(ignGear = 1, "gear failure", if(ignLamp = 1, "lamp failure", "")));
        return(if(s = "", "OK", s) + " (0x" + tostring(x, "X2") + ")" + if(ign = "", "", "; not raised: " + ign + " reported since start"));
    end
end

return("--")
Fade
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA5);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if x <= 0xFF
        var t := getbits(x, 4, 4);
        var ret := if(t = 0, "off", t + " (" + round(sqrt(power(2, t)) * 5) / 10 + " s)");
        modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA8);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
        var e := modbusr(SH, 511, uint16);
        if (t = 0 and e <= 0xFF and e != 0, ret := "extended 0x" + tostring(e, "X2"));
        return("fade time " + ret + ", fade rate " + getbits(x, 0, 4));
    end
end

return("--")
DALI Version
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x97);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if x <= 0xFF
        return(if(x >= 8, "DALI-2 " + getbits(x, 2, 6) + "." + getbits(x, 0, 2), "DALI-1") + " (" + x + ")");
    end
end

return("--")
Bus statistics
return("since start: queries " + cntQ + ", stale answers read away " + cntStale + ", no answer " + cntNone + ", collisions " + cntColl + ", rejected levels " + cntBad)
Azioni di servizio
${xml_add_to_group}
Parametri: Group ID (0–15 grp)
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x60 + grp);
${xml_remove_from_group}
Parametri: Group ID (0–15 grp)
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x70 + grp);
${xml_reset_to_default_settings}
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x20);
${xml_set_startup_levels}
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x21);
sleep(10);
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x2c);
sleep(10);
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x2d);
Disable fading
modbusw(SH, 541, uint16, 0xA300);
sleep(100);
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x2E);
sleep(100);
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x30);
Gear 15 Dimmer Lettura e scrittura

Dispositivo di controllo DALI all'indirizzo breve 15 — dimmer TapHome mappato su DALI arc power 0–100 % tramite H:510 LAMP LEVEL (scrittura) e QUERY ACTUAL LEVEL tramite H:511 (lettura), delimitato dai propri MIN / MAX LEVEL del gear.

Registro: H:511 → H:510 UInt16 Unità: % numeric
Attributi di servizio
Indirizzo breveIndirizzo breve DALI (0–63) target di questo dispositivo — fissato al momento dell'importazione del template e utilizzato nel byte alto di ogni scrittura Modbus.
Device TypeByte device-type DALI restituito da QUERY DEVICE TYPE (0x99) — riporta DT0 (fluorescente), DT6 (driver LED), DT8 (colore / tunable white) ecc., o -- quando non c'è risposta.
Physical Min LevelLivello minimo di dimmerazione imposto dall'hardware riportato dal gear — letto da QUERY PHYSICAL MIN LEVEL (0x9A), in percentuale.
Max LevelDALI MAX LEVEL configurato — letto da QUERY MAX LEVEL (0xA1); utilizzato come limite superiore durante la scalatura di TapHome 0–100 % su DALI arc power.
Min LevelDALI MIN LEVEL configurato — letto da QUERY MIN LEVEL (0xA2); utilizzato come limite inferiore durante la scalatura di TapHome 0–100 % su DALI arc power.
Power Up LevelLuminosità ripristinata dopo il ripristino dell'alimentazione del bus DALI — letta da QUERY POWER ON LEVEL (0xA3).
System Failure LevelLuminosità adottata quando il bus DALI perde la comunicazione per più di 500 ms — letta da QUERY SYSTEM FAILURE LEVEL (0xA4).
GruppiElenco separato da virgole dei gruppi DALI (0–15) a cui appartiene il gear — decodificato da QUERY GROUPS 0-7 (0xC0) e QUERY GROUPS 8-15 (0xC1); mostra None o ad es. 0,3,7.
Support Lamp FailureSe la lampada / driver supporta il rilevamento dei guasti della lampada — Yes / No / --. Gestisce l'errore Lamp failure! nel readscript periodico.
Support Power FailureSe la lampada / driver supporta il rilevamento dei guasti di alimentazione — Yes / No / --. Gestisce l'errore Power failure! nel readscript periodico.
DALI Version
Bus statistics
Azioni di servizio
Add to GroupAggiunge questo gear a un gruppo DALI (0–15) tramite ADD TO GROUP (0x60+grp) — auto-ripetuto entro 100 ms come richiesto per i comandi di configurazione DALI.
Remove from GroupRimuove questo gear da un gruppo DALI (0–15) tramite REMOVE FROM GROUP (0x70+grp).
Reset to Default SettingsInvia DALI RESET (0x20) — ripristina ogni parametro NVM del gear (livelli max / min / power-on / system-failure, appartenenza al gruppo, scene) al valore predefinito del produttore.
Set Startup LevelsCattura l'arc power corrente e la memorizza come Power On Level e System Failure Level — sequenza STORE ACTUAL LEVEL IN DTR (0x21) → STORE DTR AS POWER ON LEVEL (0x2C) → STORE DTR AS SYSTEM FAILURE LEVEL (0x2D).
Disable fading

Gear 15

Lettura (modulo)
var x := 0; var rx := 0; var y := 0;
if Status > 0
    Status := Status - 1;
    adderror(3, "Gear not responding!");
    return(0);
end

# checkStatus: ReadLevel resets it while the gear answers; statusPoll: QUERY STATUS at least once per 60 runs
checkStatus := checkStatus - 1;
statusPoll := statusPoll - 1;
if checkStatus < 1 or statusPoll < 1
    # an unread answer left in the gateway would be taken for this query: read it away and count it
    x := modbusr(SH, 511, uint16); if (x != 0x8000, cntStale := cntStale + 1);
    modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x90);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    x := modbusr(SH, 511, uint16);
    cntQ := cntQ + 1; if (x = 0x8000, cntNone := cntNone + 1); if (x = 0x20FF, cntColl := cntColl + 1);
    # a single lost answer happens on DALI: ask once more before declaring the gear missing
    if x = 0x8000
        x := modbusr(SH, 511, uint16); if (x != 0x8000, cntStale := cntStale + 1);
        modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x90);
        sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
        x := modbusr(SH, 511, uint16);
        cntQ := cntQ + 1; if (x = 0x8000, cntNone := cntNone + 1); if (x = 0x20FF, cntColl := cntColl + 1);
    end
    if x <= 0xFF
        # a changed failure bit must be read twice the same before it is taken
        if statusSeen = 1 and getbits(x, 0, 2) != getbits(gearStatus, 0, 2)
            y := modbusr(SH, 511, uint16); if (y != 0x8000, cntStale := cntStale + 1);
            modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x90);
            sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
            y := modbusr(SH, 511, uint16);
            cntQ := cntQ + 1; if (y = 0x8000, cntNone := cntNone + 1); if (y = 0x20FF, cntColl := cntColl + 1);
            if y != x
                cntBad := cntBad + 1;
                x := gearStatus;
            end
        end
        if statusSeen = 0
            ignGear := getbit(x, 0);
            ignLamp := getbit(x, 1);
            statusSeen := 1;
        end
        # a bit that clears ends its ignore, so a later failure is raised
        if (getbit(x, 0) = 0, ignGear := 0);
        if (getbit(x, 1) = 0, ignLamp := 0);
        gearStatus := x;
        checkStatus := 60;
        statusPoll := 60;
    else
        if x = 0x8000
            Status := RANDINT(10, 60);
            adderror(3, "Gear not responding!");
            return(0);
        end
    end
end

# messages last one run only, so they are raised from the stored status on every run
if ((getbit(gearStatus, 0) = 1) and (ignGear = 0), adderror(1, "Control gear failure!"));
if ((getbit(gearStatus, 1) = 1) and (ignLamp = 0), adderror(2, "Lamp failure!"));
Inizializzazione
var x := 0; var rx := 0;
# QUERY STATUS 0x90: every reply byte proves the gear is present; 0x8000 = no answer, 0x20FF = bus collision
# an unread answer left in the gateway would be taken for this query: read it away and count it
x := modbusr(SH, 511, uint16); if (x != 0x8000, cntStale := cntStale + 1);
modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x90);
sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
x := modbusr(SH, 511, uint16);
cntQ := cntQ + 1; if (x = 0x8000, cntNone := cntNone + 1); if (x = 0x20FF, cntColl := cntColl + 1);
statusSeen := 0;
if x <= 0xFF
    # failure bits a gear reports from its first answer are its permanent state, not an event: shown, not raised
    gearStatus := x;
    ignGear := getbit(x, 0);
    ignLamp := getbit(x, 1);
    statusSeen := 1;
    Status := 0;
else
    Status := RANDINT(1, 60);
end

if Status = 0
    x := modbusr(SH, 511, uint16); if (x != 0x8000, cntStale := cntStale + 1);
    modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA2);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    x := modbusr(SH, 511, uint16);
    cntQ := cntQ + 1; if (x = 0x8000, cntNone := cntNone + 1); if (x = 0x20FF, cntColl := cntColl + 1);
    if (x <= 0xFE, minLevel := x);

    x := modbusr(SH, 511, uint16); if (x != 0x8000, cntStale := cntStale + 1);
    modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA1);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    x := modbusr(SH, 511, uint16);
    cntQ := cntQ + 1; if (x = 0x8000, cntNone := cntNone + 1); if (x = 0x20FF, cntColl := cntColl + 1);
    if (x <= 0xFE, maxLevel := x);
end
Lettura livello
var x := 0; var rx := 0; var y := 0;
if Status = 0
    if minLevel = 0
        # an unread answer left in the gateway would be taken for this query: read it away and count it
        x := modbusr(SH, 511, uint16); if (x != 0x8000, cntStale := cntStale + 1);
        modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA2);
        sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
        x := modbusr(SH, 511, uint16);
        cntQ := cntQ + 1; if (x = 0x8000, cntNone := cntNone + 1); if (x = 0x20FF, cntColl := cntColl + 1);
        if (x <= 0xFE, minLevel := x);
    end
    x := modbusr(SH, 511, uint16); if (x != 0x8000, cntStale := cntStale + 1);
    modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA0);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    x := modbusr(SH, 511, uint16);
    cntQ := cntQ + 1; if (x = 0x8000, cntNone := cntNone + 1); if (x = 0x20FF, cntColl := cntColl + 1);
    if (x != 0x8000 or rx, checkStatus := 60);
    # 0xFF = MASK, 0x20FF = collision, 0x8000 = no answer: keep the last level instead of a phantom value
    if x > 0xFE
        return(Le);
    end
    # an actual level is 0 or between the gear's min and max: anything else is not this gear's answer
    if x > 0 and x < minLevel
        cntBad := cntBad + 1;
        return(Le);
    end
    # a changed level must be read twice the same before it is taken
    if x != lastRaw
        y := modbusr(SH, 511, uint16); if (y != 0x8000, cntStale := cntStale + 1);
        modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA0);
        sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
        y := modbusr(SH, 511, uint16);
        cntQ := cntQ + 1; if (y = 0x8000, cntNone := cntNone + 1); if (y = 0x20FF, cntColl := cntColl + 1);
        if y != x
            cntBad := cntBad + 1;
            return(Le);
        end
        lastRaw := x;
    end
    return(if(x = 0, 0, linear(x, minLevel, 0.01, maxLevel, 1)));
else
    return(NaN);
end
Scrittura livello
var level := 0;
if(Le > 0, level := round(linear(Le, 0.01, minLevel, 1, maxLevel)));
modbusw(SH, 510, uint16, (ShortAddress << 8) + level );
Attributi di servizio
${xml_short_address}
ShortAddress
${xml_device_type}
var x := 0; var y := 0; var rx := 0; var s := ""; var i := 0;
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x99);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    x := modbusr(SH, 511, uint16);
    if (x < 0xFF, return("DT" + x));
    if x = 0xFF
        while i < 8
            modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA7);
            sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
            y := modbusr(SH, 511, uint16);
            if y < 0xFE
                s := if(s = "", "DT" + y, s + ", DT" + y);
                i := i + 1;
            else
                i := 8;
            end
        loop
        return(if(s = "", "MASK", s));
    end
end

return("--")
Physical Min Level
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x9A);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if (x <= 0xFE, return(round((x / 0xFE) * 100) + " %"));
end

return("--")
Max Level
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA1);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if (x <= 0xFE, return(round((x / 0xFE) * 100) + " %"));
end

return("--")
Min Level
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA2);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if (x <= 0xFE, return(round((x / 0xFE) * 100) + " %"));
end

return("--")
Power Up Level
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA3);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if (x <= 0xFE, return(round((x / 0xFE) * 100) + " %"));
end

return("--")
System Failure Level
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA4);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if (x <= 0xFE, return(round((x / 0xFE) * 100) + " %"));
end

return("--")
${xml_groups}
var x := 0; var rx := 0;
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xC0);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var g1 := modbusr(SH, 511, uint16);
    if (g1 > 0xFF, return("--")); 

    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xC1);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var g2 := modbusr(SH, 511, uint16);
    if (g2 > 0xFF, return("--")); 

    var ret := "";

    if (getbit(g1, 0), ret := ret + "0");
    if (getbit(g1, 1), if (ret = "", ret := "1", ret := ret + ",1"));
    if (getbit(g1, 2), if (ret = "", ret := "2", ret := ret + ",2"));
    if (getbit(g1, 3), if (ret = "", ret := "3", ret := ret + ",3"));
    if (getbit(g1, 4), if (ret = "", ret := "4", ret := ret + ",4"));
    if (getbit(g1, 5), if (ret = "", ret := "5", ret := ret + ",5"));
    if (getbit(g1, 6), if (ret = "", ret := "6", ret := ret + ",6"));
    if (getbit(g1, 7), if (ret = "", ret := "7", ret := ret + ",7"));
    if (getbit(g2, 0), if (ret = "", ret := "8", ret := ret + ",8"));
    if (getbit(g2, 1), if (ret = "", ret := "9", ret := ret + ",9"));
    if (getbit(g2, 2), if (ret = "", ret := "10", ret := ret + ",10"));
    if (getbit(g2, 3), if (ret = "", ret := "11", ret := ret + ",11"));
    if (getbit(g2, 4), if (ret = "", ret := "12", ret := ret + ",12"));
    if (getbit(g2, 5), if (ret = "", ret := "13", ret := ret + ",13"));
    if (getbit(g2, 6), if (ret = "", ret := "14", ret := ret + ",14"));
    if (getbit(g2, 7), if (ret = "", ret := "15", ret := ret + ",15"));

    if (ret = "", return("None"), return(ret));
else
    return("--");
end
DALI Status
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x90);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if x <= 0xFF
        var s := "";
        if (getbit(x, 0), s := if(s = "", "gear failure", s + ", gear failure"));
        if (getbit(x, 1), s := if(s = "", "lamp failure", s + ", lamp failure"));
        if (getbit(x, 2), s := if(s = "", "lamp on", s + ", lamp on"));
        if (getbit(x, 3), s := if(s = "", "limit error", s + ", limit error"));
        if (getbit(x, 4), s := if(s = "", "fade running", s + ", fade running"));
        if (getbit(x, 5), s := if(s = "", "reset state", s + ", reset state"));
        if (getbit(x, 6), s := if(s = "", "missing short address", s + ", missing short address"));
        if (getbit(x, 7), s := if(s = "", "power cycle", s + ", power cycle"));
        var ign := if((ignGear = 1) and (ignLamp = 1), "gear and lamp failure", if(ignGear = 1, "gear failure", if(ignLamp = 1, "lamp failure", "")));
        return(if(s = "", "OK", s) + " (0x" + tostring(x, "X2") + ")" + if(ign = "", "", "; not raised: " + ign + " reported since start"));
    end
end

return("--")
Fade
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA5);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if x <= 0xFF
        var t := getbits(x, 4, 4);
        var ret := if(t = 0, "off", t + " (" + round(sqrt(power(2, t)) * 5) / 10 + " s)");
        modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA8);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
        var e := modbusr(SH, 511, uint16);
        if (t = 0 and e <= 0xFF and e != 0, ret := "extended 0x" + tostring(e, "X2"));
        return("fade time " + ret + ", fade rate " + getbits(x, 0, 4));
    end
end

return("--")
DALI Version
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x97);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if x <= 0xFF
        return(if(x >= 8, "DALI-2 " + getbits(x, 2, 6) + "." + getbits(x, 0, 2), "DALI-1") + " (" + x + ")");
    end
end

return("--")
Bus statistics
return("since start: queries " + cntQ + ", stale answers read away " + cntStale + ", no answer " + cntNone + ", collisions " + cntColl + ", rejected levels " + cntBad)
Azioni di servizio
${xml_add_to_group}
Parametri: Group ID (0–15 grp)
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x60 + grp);
${xml_remove_from_group}
Parametri: Group ID (0–15 grp)
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x70 + grp);
${xml_reset_to_default_settings}
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x20);
${xml_set_startup_levels}
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x21);
sleep(10);
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x2c);
sleep(10);
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x2d);
Disable fading
modbusw(SH, 541, uint16, 0xA300);
sleep(100);
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x2E);
sleep(100);
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x30);
Gear 16 Dimmer Lettura e scrittura

Dispositivo di controllo DALI all'indirizzo breve 16 — dimmer TapHome mappato su DALI arc power 0–100 % tramite H:510 LAMP LEVEL (scrittura) e QUERY ACTUAL LEVEL tramite H:511 (lettura), delimitato dai propri MIN / MAX LEVEL del gear.

Registro: H:511 → H:510 UInt16 Unità: % numeric
Attributi di servizio
Indirizzo breveIndirizzo breve DALI (0–63) target di questo dispositivo — fissato al momento dell'importazione del template e utilizzato nel byte alto di ogni scrittura Modbus.
Device TypeByte device-type DALI restituito da QUERY DEVICE TYPE (0x99) — riporta DT0 (fluorescente), DT6 (driver LED), DT8 (colore / tunable white) ecc., o -- quando non c'è risposta.
Physical Min LevelLivello minimo di dimmerazione imposto dall'hardware riportato dal gear — letto da QUERY PHYSICAL MIN LEVEL (0x9A), in percentuale.
Max LevelDALI MAX LEVEL configurato — letto da QUERY MAX LEVEL (0xA1); utilizzato come limite superiore durante la scalatura di TapHome 0–100 % su DALI arc power.
Min LevelDALI MIN LEVEL configurato — letto da QUERY MIN LEVEL (0xA2); utilizzato come limite inferiore durante la scalatura di TapHome 0–100 % su DALI arc power.
Power Up LevelLuminosità ripristinata dopo il ripristino dell'alimentazione del bus DALI — letta da QUERY POWER ON LEVEL (0xA3).
System Failure LevelLuminosità adottata quando il bus DALI perde la comunicazione per più di 500 ms — letta da QUERY SYSTEM FAILURE LEVEL (0xA4).
GruppiElenco separato da virgole dei gruppi DALI (0–15) a cui appartiene il gear — decodificato da QUERY GROUPS 0-7 (0xC0) e QUERY GROUPS 8-15 (0xC1); mostra None o ad es. 0,3,7.
Support Lamp FailureSe la lampada / driver supporta il rilevamento dei guasti della lampada — Yes / No / --. Gestisce l'errore Lamp failure! nel readscript periodico.
Support Power FailureSe la lampada / driver supporta il rilevamento dei guasti di alimentazione — Yes / No / --. Gestisce l'errore Power failure! nel readscript periodico.
DALI Version
Bus statistics
Azioni di servizio
Add to GroupAggiunge questo gear a un gruppo DALI (0–15) tramite ADD TO GROUP (0x60+grp) — auto-ripetuto entro 100 ms come richiesto per i comandi di configurazione DALI.
Remove from GroupRimuove questo gear da un gruppo DALI (0–15) tramite REMOVE FROM GROUP (0x70+grp).
Reset to Default SettingsInvia DALI RESET (0x20) — ripristina ogni parametro NVM del gear (livelli max / min / power-on / system-failure, appartenenza al gruppo, scene) al valore predefinito del produttore.
Set Startup LevelsCattura l'arc power corrente e la memorizza come Power On Level e System Failure Level — sequenza STORE ACTUAL LEVEL IN DTR (0x21) → STORE DTR AS POWER ON LEVEL (0x2C) → STORE DTR AS SYSTEM FAILURE LEVEL (0x2D).
Disable fading

Gear 16

Lettura (modulo)
var x := 0; var rx := 0; var y := 0;
if Status > 0
    Status := Status - 1;
    adderror(3, "Gear not responding!");
    return(0);
end

# checkStatus: ReadLevel resets it while the gear answers; statusPoll: QUERY STATUS at least once per 60 runs
checkStatus := checkStatus - 1;
statusPoll := statusPoll - 1;
if checkStatus < 1 or statusPoll < 1
    # an unread answer left in the gateway would be taken for this query: read it away and count it
    x := modbusr(SH, 511, uint16); if (x != 0x8000, cntStale := cntStale + 1);
    modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x90);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    x := modbusr(SH, 511, uint16);
    cntQ := cntQ + 1; if (x = 0x8000, cntNone := cntNone + 1); if (x = 0x20FF, cntColl := cntColl + 1);
    # a single lost answer happens on DALI: ask once more before declaring the gear missing
    if x = 0x8000
        x := modbusr(SH, 511, uint16); if (x != 0x8000, cntStale := cntStale + 1);
        modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x90);
        sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
        x := modbusr(SH, 511, uint16);
        cntQ := cntQ + 1; if (x = 0x8000, cntNone := cntNone + 1); if (x = 0x20FF, cntColl := cntColl + 1);
    end
    if x <= 0xFF
        # a changed failure bit must be read twice the same before it is taken
        if statusSeen = 1 and getbits(x, 0, 2) != getbits(gearStatus, 0, 2)
            y := modbusr(SH, 511, uint16); if (y != 0x8000, cntStale := cntStale + 1);
            modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x90);
            sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
            y := modbusr(SH, 511, uint16);
            cntQ := cntQ + 1; if (y = 0x8000, cntNone := cntNone + 1); if (y = 0x20FF, cntColl := cntColl + 1);
            if y != x
                cntBad := cntBad + 1;
                x := gearStatus;
            end
        end
        if statusSeen = 0
            ignGear := getbit(x, 0);
            ignLamp := getbit(x, 1);
            statusSeen := 1;
        end
        # a bit that clears ends its ignore, so a later failure is raised
        if (getbit(x, 0) = 0, ignGear := 0);
        if (getbit(x, 1) = 0, ignLamp := 0);
        gearStatus := x;
        checkStatus := 60;
        statusPoll := 60;
    else
        if x = 0x8000
            Status := RANDINT(10, 60);
            adderror(3, "Gear not responding!");
            return(0);
        end
    end
end

# messages last one run only, so they are raised from the stored status on every run
if ((getbit(gearStatus, 0) = 1) and (ignGear = 0), adderror(1, "Control gear failure!"));
if ((getbit(gearStatus, 1) = 1) and (ignLamp = 0), adderror(2, "Lamp failure!"));
Inizializzazione
var x := 0; var rx := 0;
# QUERY STATUS 0x90: every reply byte proves the gear is present; 0x8000 = no answer, 0x20FF = bus collision
# an unread answer left in the gateway would be taken for this query: read it away and count it
x := modbusr(SH, 511, uint16); if (x != 0x8000, cntStale := cntStale + 1);
modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x90);
sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
x := modbusr(SH, 511, uint16);
cntQ := cntQ + 1; if (x = 0x8000, cntNone := cntNone + 1); if (x = 0x20FF, cntColl := cntColl + 1);
statusSeen := 0;
if x <= 0xFF
    # failure bits a gear reports from its first answer are its permanent state, not an event: shown, not raised
    gearStatus := x;
    ignGear := getbit(x, 0);
    ignLamp := getbit(x, 1);
    statusSeen := 1;
    Status := 0;
else
    Status := RANDINT(1, 60);
end

if Status = 0
    x := modbusr(SH, 511, uint16); if (x != 0x8000, cntStale := cntStale + 1);
    modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA2);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    x := modbusr(SH, 511, uint16);
    cntQ := cntQ + 1; if (x = 0x8000, cntNone := cntNone + 1); if (x = 0x20FF, cntColl := cntColl + 1);
    if (x <= 0xFE, minLevel := x);

    x := modbusr(SH, 511, uint16); if (x != 0x8000, cntStale := cntStale + 1);
    modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA1);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    x := modbusr(SH, 511, uint16);
    cntQ := cntQ + 1; if (x = 0x8000, cntNone := cntNone + 1); if (x = 0x20FF, cntColl := cntColl + 1);
    if (x <= 0xFE, maxLevel := x);
end
Lettura livello
var x := 0; var rx := 0; var y := 0;
if Status = 0
    if minLevel = 0
        # an unread answer left in the gateway would be taken for this query: read it away and count it
        x := modbusr(SH, 511, uint16); if (x != 0x8000, cntStale := cntStale + 1);
        modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA2);
        sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
        x := modbusr(SH, 511, uint16);
        cntQ := cntQ + 1; if (x = 0x8000, cntNone := cntNone + 1); if (x = 0x20FF, cntColl := cntColl + 1);
        if (x <= 0xFE, minLevel := x);
    end
    x := modbusr(SH, 511, uint16); if (x != 0x8000, cntStale := cntStale + 1);
    modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA0);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    x := modbusr(SH, 511, uint16);
    cntQ := cntQ + 1; if (x = 0x8000, cntNone := cntNone + 1); if (x = 0x20FF, cntColl := cntColl + 1);
    if (x != 0x8000 or rx, checkStatus := 60);
    # 0xFF = MASK, 0x20FF = collision, 0x8000 = no answer: keep the last level instead of a phantom value
    if x > 0xFE
        return(Le);
    end
    # an actual level is 0 or between the gear's min and max: anything else is not this gear's answer
    if x > 0 and x < minLevel
        cntBad := cntBad + 1;
        return(Le);
    end
    # a changed level must be read twice the same before it is taken
    if x != lastRaw
        y := modbusr(SH, 511, uint16); if (y != 0x8000, cntStale := cntStale + 1);
        modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA0);
        sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
        y := modbusr(SH, 511, uint16);
        cntQ := cntQ + 1; if (y = 0x8000, cntNone := cntNone + 1); if (y = 0x20FF, cntColl := cntColl + 1);
        if y != x
            cntBad := cntBad + 1;
            return(Le);
        end
        lastRaw := x;
    end
    return(if(x = 0, 0, linear(x, minLevel, 0.01, maxLevel, 1)));
else
    return(NaN);
end
Scrittura livello
var level := 0;
if(Le > 0, level := round(linear(Le, 0.01, minLevel, 1, maxLevel)));
modbusw(SH, 510, uint16, (ShortAddress << 8) + level );
Attributi di servizio
${xml_short_address}
ShortAddress
${xml_device_type}
var x := 0; var y := 0; var rx := 0; var s := ""; var i := 0;
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x99);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    x := modbusr(SH, 511, uint16);
    if (x < 0xFF, return("DT" + x));
    if x = 0xFF
        while i < 8
            modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA7);
            sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
            y := modbusr(SH, 511, uint16);
            if y < 0xFE
                s := if(s = "", "DT" + y, s + ", DT" + y);
                i := i + 1;
            else
                i := 8;
            end
        loop
        return(if(s = "", "MASK", s));
    end
end

return("--")
Physical Min Level
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x9A);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if (x <= 0xFE, return(round((x / 0xFE) * 100) + " %"));
end

return("--")
Max Level
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA1);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if (x <= 0xFE, return(round((x / 0xFE) * 100) + " %"));
end

return("--")
Min Level
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA2);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if (x <= 0xFE, return(round((x / 0xFE) * 100) + " %"));
end

return("--")
Power Up Level
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA3);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if (x <= 0xFE, return(round((x / 0xFE) * 100) + " %"));
end

return("--")
System Failure Level
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA4);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if (x <= 0xFE, return(round((x / 0xFE) * 100) + " %"));
end

return("--")
${xml_groups}
var x := 0; var rx := 0;
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xC0);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var g1 := modbusr(SH, 511, uint16);
    if (g1 > 0xFF, return("--")); 

    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xC1);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var g2 := modbusr(SH, 511, uint16);
    if (g2 > 0xFF, return("--")); 

    var ret := "";

    if (getbit(g1, 0), ret := ret + "0");
    if (getbit(g1, 1), if (ret = "", ret := "1", ret := ret + ",1"));
    if (getbit(g1, 2), if (ret = "", ret := "2", ret := ret + ",2"));
    if (getbit(g1, 3), if (ret = "", ret := "3", ret := ret + ",3"));
    if (getbit(g1, 4), if (ret = "", ret := "4", ret := ret + ",4"));
    if (getbit(g1, 5), if (ret = "", ret := "5", ret := ret + ",5"));
    if (getbit(g1, 6), if (ret = "", ret := "6", ret := ret + ",6"));
    if (getbit(g1, 7), if (ret = "", ret := "7", ret := ret + ",7"));
    if (getbit(g2, 0), if (ret = "", ret := "8", ret := ret + ",8"));
    if (getbit(g2, 1), if (ret = "", ret := "9", ret := ret + ",9"));
    if (getbit(g2, 2), if (ret = "", ret := "10", ret := ret + ",10"));
    if (getbit(g2, 3), if (ret = "", ret := "11", ret := ret + ",11"));
    if (getbit(g2, 4), if (ret = "", ret := "12", ret := ret + ",12"));
    if (getbit(g2, 5), if (ret = "", ret := "13", ret := ret + ",13"));
    if (getbit(g2, 6), if (ret = "", ret := "14", ret := ret + ",14"));
    if (getbit(g2, 7), if (ret = "", ret := "15", ret := ret + ",15"));

    if (ret = "", return("None"), return(ret));
else
    return("--");
end
DALI Status
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x90);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if x <= 0xFF
        var s := "";
        if (getbit(x, 0), s := if(s = "", "gear failure", s + ", gear failure"));
        if (getbit(x, 1), s := if(s = "", "lamp failure", s + ", lamp failure"));
        if (getbit(x, 2), s := if(s = "", "lamp on", s + ", lamp on"));
        if (getbit(x, 3), s := if(s = "", "limit error", s + ", limit error"));
        if (getbit(x, 4), s := if(s = "", "fade running", s + ", fade running"));
        if (getbit(x, 5), s := if(s = "", "reset state", s + ", reset state"));
        if (getbit(x, 6), s := if(s = "", "missing short address", s + ", missing short address"));
        if (getbit(x, 7), s := if(s = "", "power cycle", s + ", power cycle"));
        var ign := if((ignGear = 1) and (ignLamp = 1), "gear and lamp failure", if(ignGear = 1, "gear failure", if(ignLamp = 1, "lamp failure", "")));
        return(if(s = "", "OK", s) + " (0x" + tostring(x, "X2") + ")" + if(ign = "", "", "; not raised: " + ign + " reported since start"));
    end
end

return("--")
Fade
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA5);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if x <= 0xFF
        var t := getbits(x, 4, 4);
        var ret := if(t = 0, "off", t + " (" + round(sqrt(power(2, t)) * 5) / 10 + " s)");
        modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA8);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
        var e := modbusr(SH, 511, uint16);
        if (t = 0 and e <= 0xFF and e != 0, ret := "extended 0x" + tostring(e, "X2"));
        return("fade time " + ret + ", fade rate " + getbits(x, 0, 4));
    end
end

return("--")
DALI Version
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x97);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if x <= 0xFF
        return(if(x >= 8, "DALI-2 " + getbits(x, 2, 6) + "." + getbits(x, 0, 2), "DALI-1") + " (" + x + ")");
    end
end

return("--")
Bus statistics
return("since start: queries " + cntQ + ", stale answers read away " + cntStale + ", no answer " + cntNone + ", collisions " + cntColl + ", rejected levels " + cntBad)
Azioni di servizio
${xml_add_to_group}
Parametri: Group ID (0–15 grp)
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x60 + grp);
${xml_remove_from_group}
Parametri: Group ID (0–15 grp)
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x70 + grp);
${xml_reset_to_default_settings}
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x20);
${xml_set_startup_levels}
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x21);
sleep(10);
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x2c);
sleep(10);
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x2d);
Disable fading
modbusw(SH, 541, uint16, 0xA300);
sleep(100);
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x2E);
sleep(100);
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x30);
Gear 17 Dimmer Lettura e scrittura

Dispositivo di controllo DALI all'indirizzo breve 17 — dimmer TapHome mappato su DALI arc power 0–100 % tramite H:510 LAMP LEVEL (scrittura) e QUERY ACTUAL LEVEL tramite H:511 (lettura), delimitato dai propri MIN / MAX LEVEL del gear.

Registro: H:511 → H:510 UInt16 Unità: % numeric
Attributi di servizio
Indirizzo breveIndirizzo breve DALI (0–63) target di questo dispositivo — fissato al momento dell'importazione del template e utilizzato nel byte alto di ogni scrittura Modbus.
Device TypeByte device-type DALI restituito da QUERY DEVICE TYPE (0x99) — riporta DT0 (fluorescente), DT6 (driver LED), DT8 (colore / tunable white) ecc., o -- quando non c'è risposta.
Physical Min LevelLivello minimo di dimmerazione imposto dall'hardware riportato dal gear — letto da QUERY PHYSICAL MIN LEVEL (0x9A), in percentuale.
Max LevelDALI MAX LEVEL configurato — letto da QUERY MAX LEVEL (0xA1); utilizzato come limite superiore durante la scalatura di TapHome 0–100 % su DALI arc power.
Min LevelDALI MIN LEVEL configurato — letto da QUERY MIN LEVEL (0xA2); utilizzato come limite inferiore durante la scalatura di TapHome 0–100 % su DALI arc power.
Power Up LevelLuminosità ripristinata dopo il ripristino dell'alimentazione del bus DALI — letta da QUERY POWER ON LEVEL (0xA3).
System Failure LevelLuminosità adottata quando il bus DALI perde la comunicazione per più di 500 ms — letta da QUERY SYSTEM FAILURE LEVEL (0xA4).
GruppiElenco separato da virgole dei gruppi DALI (0–15) a cui appartiene il gear — decodificato da QUERY GROUPS 0-7 (0xC0) e QUERY GROUPS 8-15 (0xC1); mostra None o ad es. 0,3,7.
Support Lamp FailureSe la lampada / driver supporta il rilevamento dei guasti della lampada — Yes / No / --. Gestisce l'errore Lamp failure! nel readscript periodico.
Support Power FailureSe la lampada / driver supporta il rilevamento dei guasti di alimentazione — Yes / No / --. Gestisce l'errore Power failure! nel readscript periodico.
DALI Version
Bus statistics
Azioni di servizio
Add to GroupAggiunge questo gear a un gruppo DALI (0–15) tramite ADD TO GROUP (0x60+grp) — auto-ripetuto entro 100 ms come richiesto per i comandi di configurazione DALI.
Remove from GroupRimuove questo gear da un gruppo DALI (0–15) tramite REMOVE FROM GROUP (0x70+grp).
Reset to Default SettingsInvia DALI RESET (0x20) — ripristina ogni parametro NVM del gear (livelli max / min / power-on / system-failure, appartenenza al gruppo, scene) al valore predefinito del produttore.
Set Startup LevelsCattura l'arc power corrente e la memorizza come Power On Level e System Failure Level — sequenza STORE ACTUAL LEVEL IN DTR (0x21) → STORE DTR AS POWER ON LEVEL (0x2C) → STORE DTR AS SYSTEM FAILURE LEVEL (0x2D).
Disable fading

Gear 17

Lettura (modulo)
var x := 0; var rx := 0; var y := 0;
if Status > 0
    Status := Status - 1;
    adderror(3, "Gear not responding!");
    return(0);
end

# checkStatus: ReadLevel resets it while the gear answers; statusPoll: QUERY STATUS at least once per 60 runs
checkStatus := checkStatus - 1;
statusPoll := statusPoll - 1;
if checkStatus < 1 or statusPoll < 1
    # an unread answer left in the gateway would be taken for this query: read it away and count it
    x := modbusr(SH, 511, uint16); if (x != 0x8000, cntStale := cntStale + 1);
    modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x90);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    x := modbusr(SH, 511, uint16);
    cntQ := cntQ + 1; if (x = 0x8000, cntNone := cntNone + 1); if (x = 0x20FF, cntColl := cntColl + 1);
    # a single lost answer happens on DALI: ask once more before declaring the gear missing
    if x = 0x8000
        x := modbusr(SH, 511, uint16); if (x != 0x8000, cntStale := cntStale + 1);
        modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x90);
        sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
        x := modbusr(SH, 511, uint16);
        cntQ := cntQ + 1; if (x = 0x8000, cntNone := cntNone + 1); if (x = 0x20FF, cntColl := cntColl + 1);
    end
    if x <= 0xFF
        # a changed failure bit must be read twice the same before it is taken
        if statusSeen = 1 and getbits(x, 0, 2) != getbits(gearStatus, 0, 2)
            y := modbusr(SH, 511, uint16); if (y != 0x8000, cntStale := cntStale + 1);
            modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x90);
            sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
            y := modbusr(SH, 511, uint16);
            cntQ := cntQ + 1; if (y = 0x8000, cntNone := cntNone + 1); if (y = 0x20FF, cntColl := cntColl + 1);
            if y != x
                cntBad := cntBad + 1;
                x := gearStatus;
            end
        end
        if statusSeen = 0
            ignGear := getbit(x, 0);
            ignLamp := getbit(x, 1);
            statusSeen := 1;
        end
        # a bit that clears ends its ignore, so a later failure is raised
        if (getbit(x, 0) = 0, ignGear := 0);
        if (getbit(x, 1) = 0, ignLamp := 0);
        gearStatus := x;
        checkStatus := 60;
        statusPoll := 60;
    else
        if x = 0x8000
            Status := RANDINT(10, 60);
            adderror(3, "Gear not responding!");
            return(0);
        end
    end
end

# messages last one run only, so they are raised from the stored status on every run
if ((getbit(gearStatus, 0) = 1) and (ignGear = 0), adderror(1, "Control gear failure!"));
if ((getbit(gearStatus, 1) = 1) and (ignLamp = 0), adderror(2, "Lamp failure!"));
Inizializzazione
var x := 0; var rx := 0;
# QUERY STATUS 0x90: every reply byte proves the gear is present; 0x8000 = no answer, 0x20FF = bus collision
# an unread answer left in the gateway would be taken for this query: read it away and count it
x := modbusr(SH, 511, uint16); if (x != 0x8000, cntStale := cntStale + 1);
modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x90);
sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
x := modbusr(SH, 511, uint16);
cntQ := cntQ + 1; if (x = 0x8000, cntNone := cntNone + 1); if (x = 0x20FF, cntColl := cntColl + 1);
statusSeen := 0;
if x <= 0xFF
    # failure bits a gear reports from its first answer are its permanent state, not an event: shown, not raised
    gearStatus := x;
    ignGear := getbit(x, 0);
    ignLamp := getbit(x, 1);
    statusSeen := 1;
    Status := 0;
else
    Status := RANDINT(1, 60);
end

if Status = 0
    x := modbusr(SH, 511, uint16); if (x != 0x8000, cntStale := cntStale + 1);
    modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA2);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    x := modbusr(SH, 511, uint16);
    cntQ := cntQ + 1; if (x = 0x8000, cntNone := cntNone + 1); if (x = 0x20FF, cntColl := cntColl + 1);
    if (x <= 0xFE, minLevel := x);

    x := modbusr(SH, 511, uint16); if (x != 0x8000, cntStale := cntStale + 1);
    modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA1);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    x := modbusr(SH, 511, uint16);
    cntQ := cntQ + 1; if (x = 0x8000, cntNone := cntNone + 1); if (x = 0x20FF, cntColl := cntColl + 1);
    if (x <= 0xFE, maxLevel := x);
end
Lettura livello
var x := 0; var rx := 0; var y := 0;
if Status = 0
    if minLevel = 0
        # an unread answer left in the gateway would be taken for this query: read it away and count it
        x := modbusr(SH, 511, uint16); if (x != 0x8000, cntStale := cntStale + 1);
        modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA2);
        sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
        x := modbusr(SH, 511, uint16);
        cntQ := cntQ + 1; if (x = 0x8000, cntNone := cntNone + 1); if (x = 0x20FF, cntColl := cntColl + 1);
        if (x <= 0xFE, minLevel := x);
    end
    x := modbusr(SH, 511, uint16); if (x != 0x8000, cntStale := cntStale + 1);
    modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA0);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    x := modbusr(SH, 511, uint16);
    cntQ := cntQ + 1; if (x = 0x8000, cntNone := cntNone + 1); if (x = 0x20FF, cntColl := cntColl + 1);
    if (x != 0x8000 or rx, checkStatus := 60);
    # 0xFF = MASK, 0x20FF = collision, 0x8000 = no answer: keep the last level instead of a phantom value
    if x > 0xFE
        return(Le);
    end
    # an actual level is 0 or between the gear's min and max: anything else is not this gear's answer
    if x > 0 and x < minLevel
        cntBad := cntBad + 1;
        return(Le);
    end
    # a changed level must be read twice the same before it is taken
    if x != lastRaw
        y := modbusr(SH, 511, uint16); if (y != 0x8000, cntStale := cntStale + 1);
        modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA0);
        sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
        y := modbusr(SH, 511, uint16);
        cntQ := cntQ + 1; if (y = 0x8000, cntNone := cntNone + 1); if (y = 0x20FF, cntColl := cntColl + 1);
        if y != x
            cntBad := cntBad + 1;
            return(Le);
        end
        lastRaw := x;
    end
    return(if(x = 0, 0, linear(x, minLevel, 0.01, maxLevel, 1)));
else
    return(NaN);
end
Scrittura livello
var level := 0;
if(Le > 0, level := round(linear(Le, 0.01, minLevel, 1, maxLevel)));
modbusw(SH, 510, uint16, (ShortAddress << 8) + level );
Attributi di servizio
${xml_short_address}
ShortAddress
${xml_device_type}
var x := 0; var y := 0; var rx := 0; var s := ""; var i := 0;
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x99);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    x := modbusr(SH, 511, uint16);
    if (x < 0xFF, return("DT" + x));
    if x = 0xFF
        while i < 8
            modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA7);
            sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
            y := modbusr(SH, 511, uint16);
            if y < 0xFE
                s := if(s = "", "DT" + y, s + ", DT" + y);
                i := i + 1;
            else
                i := 8;
            end
        loop
        return(if(s = "", "MASK", s));
    end
end

return("--")
Physical Min Level
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x9A);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if (x <= 0xFE, return(round((x / 0xFE) * 100) + " %"));
end

return("--")
Max Level
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA1);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if (x <= 0xFE, return(round((x / 0xFE) * 100) + " %"));
end

return("--")
Min Level
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA2);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if (x <= 0xFE, return(round((x / 0xFE) * 100) + " %"));
end

return("--")
Power Up Level
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA3);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if (x <= 0xFE, return(round((x / 0xFE) * 100) + " %"));
end

return("--")
System Failure Level
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA4);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if (x <= 0xFE, return(round((x / 0xFE) * 100) + " %"));
end

return("--")
${xml_groups}
var x := 0; var rx := 0;
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xC0);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var g1 := modbusr(SH, 511, uint16);
    if (g1 > 0xFF, return("--")); 

    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xC1);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var g2 := modbusr(SH, 511, uint16);
    if (g2 > 0xFF, return("--")); 

    var ret := "";

    if (getbit(g1, 0), ret := ret + "0");
    if (getbit(g1, 1), if (ret = "", ret := "1", ret := ret + ",1"));
    if (getbit(g1, 2), if (ret = "", ret := "2", ret := ret + ",2"));
    if (getbit(g1, 3), if (ret = "", ret := "3", ret := ret + ",3"));
    if (getbit(g1, 4), if (ret = "", ret := "4", ret := ret + ",4"));
    if (getbit(g1, 5), if (ret = "", ret := "5", ret := ret + ",5"));
    if (getbit(g1, 6), if (ret = "", ret := "6", ret := ret + ",6"));
    if (getbit(g1, 7), if (ret = "", ret := "7", ret := ret + ",7"));
    if (getbit(g2, 0), if (ret = "", ret := "8", ret := ret + ",8"));
    if (getbit(g2, 1), if (ret = "", ret := "9", ret := ret + ",9"));
    if (getbit(g2, 2), if (ret = "", ret := "10", ret := ret + ",10"));
    if (getbit(g2, 3), if (ret = "", ret := "11", ret := ret + ",11"));
    if (getbit(g2, 4), if (ret = "", ret := "12", ret := ret + ",12"));
    if (getbit(g2, 5), if (ret = "", ret := "13", ret := ret + ",13"));
    if (getbit(g2, 6), if (ret = "", ret := "14", ret := ret + ",14"));
    if (getbit(g2, 7), if (ret = "", ret := "15", ret := ret + ",15"));

    if (ret = "", return("None"), return(ret));
else
    return("--");
end
DALI Status
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x90);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if x <= 0xFF
        var s := "";
        if (getbit(x, 0), s := if(s = "", "gear failure", s + ", gear failure"));
        if (getbit(x, 1), s := if(s = "", "lamp failure", s + ", lamp failure"));
        if (getbit(x, 2), s := if(s = "", "lamp on", s + ", lamp on"));
        if (getbit(x, 3), s := if(s = "", "limit error", s + ", limit error"));
        if (getbit(x, 4), s := if(s = "", "fade running", s + ", fade running"));
        if (getbit(x, 5), s := if(s = "", "reset state", s + ", reset state"));
        if (getbit(x, 6), s := if(s = "", "missing short address", s + ", missing short address"));
        if (getbit(x, 7), s := if(s = "", "power cycle", s + ", power cycle"));
        var ign := if((ignGear = 1) and (ignLamp = 1), "gear and lamp failure", if(ignGear = 1, "gear failure", if(ignLamp = 1, "lamp failure", "")));
        return(if(s = "", "OK", s) + " (0x" + tostring(x, "X2") + ")" + if(ign = "", "", "; not raised: " + ign + " reported since start"));
    end
end

return("--")
Fade
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA5);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if x <= 0xFF
        var t := getbits(x, 4, 4);
        var ret := if(t = 0, "off", t + " (" + round(sqrt(power(2, t)) * 5) / 10 + " s)");
        modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA8);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
        var e := modbusr(SH, 511, uint16);
        if (t = 0 and e <= 0xFF and e != 0, ret := "extended 0x" + tostring(e, "X2"));
        return("fade time " + ret + ", fade rate " + getbits(x, 0, 4));
    end
end

return("--")
DALI Version
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x97);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if x <= 0xFF
        return(if(x >= 8, "DALI-2 " + getbits(x, 2, 6) + "." + getbits(x, 0, 2), "DALI-1") + " (" + x + ")");
    end
end

return("--")
Bus statistics
return("since start: queries " + cntQ + ", stale answers read away " + cntStale + ", no answer " + cntNone + ", collisions " + cntColl + ", rejected levels " + cntBad)
Azioni di servizio
${xml_add_to_group}
Parametri: Group ID (0–15 grp)
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x60 + grp);
${xml_remove_from_group}
Parametri: Group ID (0–15 grp)
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x70 + grp);
${xml_reset_to_default_settings}
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x20);
${xml_set_startup_levels}
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x21);
sleep(10);
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x2c);
sleep(10);
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x2d);
Disable fading
modbusw(SH, 541, uint16, 0xA300);
sleep(100);
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x2E);
sleep(100);
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x30);
Gear 18 Dimmer Lettura e scrittura

Dispositivo di controllo DALI all'indirizzo breve 18 — dimmer TapHome mappato su DALI arc power 0–100 % tramite H:510 LAMP LEVEL (scrittura) e QUERY ACTUAL LEVEL tramite H:511 (lettura), delimitato dai propri MIN / MAX LEVEL del gear.

Registro: H:511 → H:510 UInt16 Unità: % numeric
Attributi di servizio
Indirizzo breveIndirizzo breve DALI (0–63) target di questo dispositivo — fissato al momento dell'importazione del template e utilizzato nel byte alto di ogni scrittura Modbus.
Device TypeByte device-type DALI restituito da QUERY DEVICE TYPE (0x99) — riporta DT0 (fluorescente), DT6 (driver LED), DT8 (colore / tunable white) ecc., o -- quando non c'è risposta.
Physical Min LevelLivello minimo di dimmerazione imposto dall'hardware riportato dal gear — letto da QUERY PHYSICAL MIN LEVEL (0x9A), in percentuale.
Max LevelDALI MAX LEVEL configurato — letto da QUERY MAX LEVEL (0xA1); utilizzato come limite superiore durante la scalatura di TapHome 0–100 % su DALI arc power.
Min LevelDALI MIN LEVEL configurato — letto da QUERY MIN LEVEL (0xA2); utilizzato come limite inferiore durante la scalatura di TapHome 0–100 % su DALI arc power.
Power Up LevelLuminosità ripristinata dopo il ripristino dell'alimentazione del bus DALI — letta da QUERY POWER ON LEVEL (0xA3).
System Failure LevelLuminosità adottata quando il bus DALI perde la comunicazione per più di 500 ms — letta da QUERY SYSTEM FAILURE LEVEL (0xA4).
GruppiElenco separato da virgole dei gruppi DALI (0–15) a cui appartiene il gear — decodificato da QUERY GROUPS 0-7 (0xC0) e QUERY GROUPS 8-15 (0xC1); mostra None o ad es. 0,3,7.
Support Lamp FailureSe la lampada / driver supporta il rilevamento dei guasti della lampada — Yes / No / --. Gestisce l'errore Lamp failure! nel readscript periodico.
Support Power FailureSe la lampada / driver supporta il rilevamento dei guasti di alimentazione — Yes / No / --. Gestisce l'errore Power failure! nel readscript periodico.
DALI Version
Bus statistics
Azioni di servizio
Add to GroupAggiunge questo gear a un gruppo DALI (0–15) tramite ADD TO GROUP (0x60+grp) — auto-ripetuto entro 100 ms come richiesto per i comandi di configurazione DALI.
Remove from GroupRimuove questo gear da un gruppo DALI (0–15) tramite REMOVE FROM GROUP (0x70+grp).
Reset to Default SettingsInvia DALI RESET (0x20) — ripristina ogni parametro NVM del gear (livelli max / min / power-on / system-failure, appartenenza al gruppo, scene) al valore predefinito del produttore.
Set Startup LevelsCattura l'arc power corrente e la memorizza come Power On Level e System Failure Level — sequenza STORE ACTUAL LEVEL IN DTR (0x21) → STORE DTR AS POWER ON LEVEL (0x2C) → STORE DTR AS SYSTEM FAILURE LEVEL (0x2D).
Disable fading

Gear 18

Lettura (modulo)
var x := 0; var rx := 0; var y := 0;
if Status > 0
    Status := Status - 1;
    adderror(3, "Gear not responding!");
    return(0);
end

# checkStatus: ReadLevel resets it while the gear answers; statusPoll: QUERY STATUS at least once per 60 runs
checkStatus := checkStatus - 1;
statusPoll := statusPoll - 1;
if checkStatus < 1 or statusPoll < 1
    # an unread answer left in the gateway would be taken for this query: read it away and count it
    x := modbusr(SH, 511, uint16); if (x != 0x8000, cntStale := cntStale + 1);
    modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x90);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    x := modbusr(SH, 511, uint16);
    cntQ := cntQ + 1; if (x = 0x8000, cntNone := cntNone + 1); if (x = 0x20FF, cntColl := cntColl + 1);
    # a single lost answer happens on DALI: ask once more before declaring the gear missing
    if x = 0x8000
        x := modbusr(SH, 511, uint16); if (x != 0x8000, cntStale := cntStale + 1);
        modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x90);
        sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
        x := modbusr(SH, 511, uint16);
        cntQ := cntQ + 1; if (x = 0x8000, cntNone := cntNone + 1); if (x = 0x20FF, cntColl := cntColl + 1);
    end
    if x <= 0xFF
        # a changed failure bit must be read twice the same before it is taken
        if statusSeen = 1 and getbits(x, 0, 2) != getbits(gearStatus, 0, 2)
            y := modbusr(SH, 511, uint16); if (y != 0x8000, cntStale := cntStale + 1);
            modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x90);
            sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
            y := modbusr(SH, 511, uint16);
            cntQ := cntQ + 1; if (y = 0x8000, cntNone := cntNone + 1); if (y = 0x20FF, cntColl := cntColl + 1);
            if y != x
                cntBad := cntBad + 1;
                x := gearStatus;
            end
        end
        if statusSeen = 0
            ignGear := getbit(x, 0);
            ignLamp := getbit(x, 1);
            statusSeen := 1;
        end
        # a bit that clears ends its ignore, so a later failure is raised
        if (getbit(x, 0) = 0, ignGear := 0);
        if (getbit(x, 1) = 0, ignLamp := 0);
        gearStatus := x;
        checkStatus := 60;
        statusPoll := 60;
    else
        if x = 0x8000
            Status := RANDINT(10, 60);
            adderror(3, "Gear not responding!");
            return(0);
        end
    end
end

# messages last one run only, so they are raised from the stored status on every run
if ((getbit(gearStatus, 0) = 1) and (ignGear = 0), adderror(1, "Control gear failure!"));
if ((getbit(gearStatus, 1) = 1) and (ignLamp = 0), adderror(2, "Lamp failure!"));
Inizializzazione
var x := 0; var rx := 0;
# QUERY STATUS 0x90: every reply byte proves the gear is present; 0x8000 = no answer, 0x20FF = bus collision
# an unread answer left in the gateway would be taken for this query: read it away and count it
x := modbusr(SH, 511, uint16); if (x != 0x8000, cntStale := cntStale + 1);
modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x90);
sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
x := modbusr(SH, 511, uint16);
cntQ := cntQ + 1; if (x = 0x8000, cntNone := cntNone + 1); if (x = 0x20FF, cntColl := cntColl + 1);
statusSeen := 0;
if x <= 0xFF
    # failure bits a gear reports from its first answer are its permanent state, not an event: shown, not raised
    gearStatus := x;
    ignGear := getbit(x, 0);
    ignLamp := getbit(x, 1);
    statusSeen := 1;
    Status := 0;
else
    Status := RANDINT(1, 60);
end

if Status = 0
    x := modbusr(SH, 511, uint16); if (x != 0x8000, cntStale := cntStale + 1);
    modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA2);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    x := modbusr(SH, 511, uint16);
    cntQ := cntQ + 1; if (x = 0x8000, cntNone := cntNone + 1); if (x = 0x20FF, cntColl := cntColl + 1);
    if (x <= 0xFE, minLevel := x);

    x := modbusr(SH, 511, uint16); if (x != 0x8000, cntStale := cntStale + 1);
    modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA1);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    x := modbusr(SH, 511, uint16);
    cntQ := cntQ + 1; if (x = 0x8000, cntNone := cntNone + 1); if (x = 0x20FF, cntColl := cntColl + 1);
    if (x <= 0xFE, maxLevel := x);
end
Lettura livello
var x := 0; var rx := 0; var y := 0;
if Status = 0
    if minLevel = 0
        # an unread answer left in the gateway would be taken for this query: read it away and count it
        x := modbusr(SH, 511, uint16); if (x != 0x8000, cntStale := cntStale + 1);
        modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA2);
        sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
        x := modbusr(SH, 511, uint16);
        cntQ := cntQ + 1; if (x = 0x8000, cntNone := cntNone + 1); if (x = 0x20FF, cntColl := cntColl + 1);
        if (x <= 0xFE, minLevel := x);
    end
    x := modbusr(SH, 511, uint16); if (x != 0x8000, cntStale := cntStale + 1);
    modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA0);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    x := modbusr(SH, 511, uint16);
    cntQ := cntQ + 1; if (x = 0x8000, cntNone := cntNone + 1); if (x = 0x20FF, cntColl := cntColl + 1);
    if (x != 0x8000 or rx, checkStatus := 60);
    # 0xFF = MASK, 0x20FF = collision, 0x8000 = no answer: keep the last level instead of a phantom value
    if x > 0xFE
        return(Le);
    end
    # an actual level is 0 or between the gear's min and max: anything else is not this gear's answer
    if x > 0 and x < minLevel
        cntBad := cntBad + 1;
        return(Le);
    end
    # a changed level must be read twice the same before it is taken
    if x != lastRaw
        y := modbusr(SH, 511, uint16); if (y != 0x8000, cntStale := cntStale + 1);
        modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA0);
        sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
        y := modbusr(SH, 511, uint16);
        cntQ := cntQ + 1; if (y = 0x8000, cntNone := cntNone + 1); if (y = 0x20FF, cntColl := cntColl + 1);
        if y != x
            cntBad := cntBad + 1;
            return(Le);
        end
        lastRaw := x;
    end
    return(if(x = 0, 0, linear(x, minLevel, 0.01, maxLevel, 1)));
else
    return(NaN);
end
Scrittura livello
var level := 0;
if(Le > 0, level := round(linear(Le, 0.01, minLevel, 1, maxLevel)));
modbusw(SH, 510, uint16, (ShortAddress << 8) + level );
Attributi di servizio
${xml_short_address}
ShortAddress
${xml_device_type}
var x := 0; var y := 0; var rx := 0; var s := ""; var i := 0;
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x99);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    x := modbusr(SH, 511, uint16);
    if (x < 0xFF, return("DT" + x));
    if x = 0xFF
        while i < 8
            modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA7);
            sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
            y := modbusr(SH, 511, uint16);
            if y < 0xFE
                s := if(s = "", "DT" + y, s + ", DT" + y);
                i := i + 1;
            else
                i := 8;
            end
        loop
        return(if(s = "", "MASK", s));
    end
end

return("--")
Physical Min Level
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x9A);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if (x <= 0xFE, return(round((x / 0xFE) * 100) + " %"));
end

return("--")
Max Level
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA1);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if (x <= 0xFE, return(round((x / 0xFE) * 100) + " %"));
end

return("--")
Min Level
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA2);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if (x <= 0xFE, return(round((x / 0xFE) * 100) + " %"));
end

return("--")
Power Up Level
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA3);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if (x <= 0xFE, return(round((x / 0xFE) * 100) + " %"));
end

return("--")
System Failure Level
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA4);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if (x <= 0xFE, return(round((x / 0xFE) * 100) + " %"));
end

return("--")
${xml_groups}
var x := 0; var rx := 0;
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xC0);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var g1 := modbusr(SH, 511, uint16);
    if (g1 > 0xFF, return("--")); 

    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xC1);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var g2 := modbusr(SH, 511, uint16);
    if (g2 > 0xFF, return("--")); 

    var ret := "";

    if (getbit(g1, 0), ret := ret + "0");
    if (getbit(g1, 1), if (ret = "", ret := "1", ret := ret + ",1"));
    if (getbit(g1, 2), if (ret = "", ret := "2", ret := ret + ",2"));
    if (getbit(g1, 3), if (ret = "", ret := "3", ret := ret + ",3"));
    if (getbit(g1, 4), if (ret = "", ret := "4", ret := ret + ",4"));
    if (getbit(g1, 5), if (ret = "", ret := "5", ret := ret + ",5"));
    if (getbit(g1, 6), if (ret = "", ret := "6", ret := ret + ",6"));
    if (getbit(g1, 7), if (ret = "", ret := "7", ret := ret + ",7"));
    if (getbit(g2, 0), if (ret = "", ret := "8", ret := ret + ",8"));
    if (getbit(g2, 1), if (ret = "", ret := "9", ret := ret + ",9"));
    if (getbit(g2, 2), if (ret = "", ret := "10", ret := ret + ",10"));
    if (getbit(g2, 3), if (ret = "", ret := "11", ret := ret + ",11"));
    if (getbit(g2, 4), if (ret = "", ret := "12", ret := ret + ",12"));
    if (getbit(g2, 5), if (ret = "", ret := "13", ret := ret + ",13"));
    if (getbit(g2, 6), if (ret = "", ret := "14", ret := ret + ",14"));
    if (getbit(g2, 7), if (ret = "", ret := "15", ret := ret + ",15"));

    if (ret = "", return("None"), return(ret));
else
    return("--");
end
DALI Status
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x90);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if x <= 0xFF
        var s := "";
        if (getbit(x, 0), s := if(s = "", "gear failure", s + ", gear failure"));
        if (getbit(x, 1), s := if(s = "", "lamp failure", s + ", lamp failure"));
        if (getbit(x, 2), s := if(s = "", "lamp on", s + ", lamp on"));
        if (getbit(x, 3), s := if(s = "", "limit error", s + ", limit error"));
        if (getbit(x, 4), s := if(s = "", "fade running", s + ", fade running"));
        if (getbit(x, 5), s := if(s = "", "reset state", s + ", reset state"));
        if (getbit(x, 6), s := if(s = "", "missing short address", s + ", missing short address"));
        if (getbit(x, 7), s := if(s = "", "power cycle", s + ", power cycle"));
        var ign := if((ignGear = 1) and (ignLamp = 1), "gear and lamp failure", if(ignGear = 1, "gear failure", if(ignLamp = 1, "lamp failure", "")));
        return(if(s = "", "OK", s) + " (0x" + tostring(x, "X2") + ")" + if(ign = "", "", "; not raised: " + ign + " reported since start"));
    end
end

return("--")
Fade
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA5);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if x <= 0xFF
        var t := getbits(x, 4, 4);
        var ret := if(t = 0, "off", t + " (" + round(sqrt(power(2, t)) * 5) / 10 + " s)");
        modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA8);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
        var e := modbusr(SH, 511, uint16);
        if (t = 0 and e <= 0xFF and e != 0, ret := "extended 0x" + tostring(e, "X2"));
        return("fade time " + ret + ", fade rate " + getbits(x, 0, 4));
    end
end

return("--")
DALI Version
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x97);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if x <= 0xFF
        return(if(x >= 8, "DALI-2 " + getbits(x, 2, 6) + "." + getbits(x, 0, 2), "DALI-1") + " (" + x + ")");
    end
end

return("--")
Bus statistics
return("since start: queries " + cntQ + ", stale answers read away " + cntStale + ", no answer " + cntNone + ", collisions " + cntColl + ", rejected levels " + cntBad)
Azioni di servizio
${xml_add_to_group}
Parametri: Group ID (0–15 grp)
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x60 + grp);
${xml_remove_from_group}
Parametri: Group ID (0–15 grp)
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x70 + grp);
${xml_reset_to_default_settings}
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x20);
${xml_set_startup_levels}
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x21);
sleep(10);
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x2c);
sleep(10);
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x2d);
Disable fading
modbusw(SH, 541, uint16, 0xA300);
sleep(100);
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x2E);
sleep(100);
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x30);
Gear 19 Dimmer Lettura e scrittura

Dispositivo di controllo DALI all'indirizzo breve 19 — dimmer TapHome mappato su DALI arc power 0–100 % tramite H:510 LAMP LEVEL (scrittura) e QUERY ACTUAL LEVEL tramite H:511 (lettura), delimitato dai propri MIN / MAX LEVEL del gear.

Registro: H:511 → H:510 UInt16 Unità: % numeric
Attributi di servizio
Indirizzo breveIndirizzo breve DALI (0–63) target di questo dispositivo — fissato al momento dell'importazione del template e utilizzato nel byte alto di ogni scrittura Modbus.
Device TypeByte device-type DALI restituito da QUERY DEVICE TYPE (0x99) — riporta DT0 (fluorescente), DT6 (driver LED), DT8 (colore / tunable white) ecc., o -- quando non c'è risposta.
Physical Min LevelLivello minimo di dimmerazione imposto dall'hardware riportato dal gear — letto da QUERY PHYSICAL MIN LEVEL (0x9A), in percentuale.
Max LevelDALI MAX LEVEL configurato — letto da QUERY MAX LEVEL (0xA1); utilizzato come limite superiore durante la scalatura di TapHome 0–100 % su DALI arc power.
Min LevelDALI MIN LEVEL configurato — letto da QUERY MIN LEVEL (0xA2); utilizzato come limite inferiore durante la scalatura di TapHome 0–100 % su DALI arc power.
Power Up LevelLuminosità ripristinata dopo il ripristino dell'alimentazione del bus DALI — letta da QUERY POWER ON LEVEL (0xA3).
System Failure LevelLuminosità adottata quando il bus DALI perde la comunicazione per più di 500 ms — letta da QUERY SYSTEM FAILURE LEVEL (0xA4).
GruppiElenco separato da virgole dei gruppi DALI (0–15) a cui appartiene il gear — decodificato da QUERY GROUPS 0-7 (0xC0) e QUERY GROUPS 8-15 (0xC1); mostra None o ad es. 0,3,7.
Support Lamp FailureSe la lampada / driver supporta il rilevamento dei guasti della lampada — Yes / No / --. Gestisce l'errore Lamp failure! nel readscript periodico.
Support Power FailureSe la lampada / driver supporta il rilevamento dei guasti di alimentazione — Yes / No / --. Gestisce l'errore Power failure! nel readscript periodico.
DALI Version
Bus statistics
Azioni di servizio
Add to GroupAggiunge questo gear a un gruppo DALI (0–15) tramite ADD TO GROUP (0x60+grp) — auto-ripetuto entro 100 ms come richiesto per i comandi di configurazione DALI.
Remove from GroupRimuove questo gear da un gruppo DALI (0–15) tramite REMOVE FROM GROUP (0x70+grp).
Reset to Default SettingsInvia DALI RESET (0x20) — ripristina ogni parametro NVM del gear (livelli max / min / power-on / system-failure, appartenenza al gruppo, scene) al valore predefinito del produttore.
Set Startup LevelsCattura l'arc power corrente e la memorizza come Power On Level e System Failure Level — sequenza STORE ACTUAL LEVEL IN DTR (0x21) → STORE DTR AS POWER ON LEVEL (0x2C) → STORE DTR AS SYSTEM FAILURE LEVEL (0x2D).
Disable fading

Gear 19

Lettura (modulo)
var x := 0; var rx := 0; var y := 0;
if Status > 0
    Status := Status - 1;
    adderror(3, "Gear not responding!");
    return(0);
end

# checkStatus: ReadLevel resets it while the gear answers; statusPoll: QUERY STATUS at least once per 60 runs
checkStatus := checkStatus - 1;
statusPoll := statusPoll - 1;
if checkStatus < 1 or statusPoll < 1
    # an unread answer left in the gateway would be taken for this query: read it away and count it
    x := modbusr(SH, 511, uint16); if (x != 0x8000, cntStale := cntStale + 1);
    modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x90);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    x := modbusr(SH, 511, uint16);
    cntQ := cntQ + 1; if (x = 0x8000, cntNone := cntNone + 1); if (x = 0x20FF, cntColl := cntColl + 1);
    # a single lost answer happens on DALI: ask once more before declaring the gear missing
    if x = 0x8000
        x := modbusr(SH, 511, uint16); if (x != 0x8000, cntStale := cntStale + 1);
        modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x90);
        sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
        x := modbusr(SH, 511, uint16);
        cntQ := cntQ + 1; if (x = 0x8000, cntNone := cntNone + 1); if (x = 0x20FF, cntColl := cntColl + 1);
    end
    if x <= 0xFF
        # a changed failure bit must be read twice the same before it is taken
        if statusSeen = 1 and getbits(x, 0, 2) != getbits(gearStatus, 0, 2)
            y := modbusr(SH, 511, uint16); if (y != 0x8000, cntStale := cntStale + 1);
            modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x90);
            sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
            y := modbusr(SH, 511, uint16);
            cntQ := cntQ + 1; if (y = 0x8000, cntNone := cntNone + 1); if (y = 0x20FF, cntColl := cntColl + 1);
            if y != x
                cntBad := cntBad + 1;
                x := gearStatus;
            end
        end
        if statusSeen = 0
            ignGear := getbit(x, 0);
            ignLamp := getbit(x, 1);
            statusSeen := 1;
        end
        # a bit that clears ends its ignore, so a later failure is raised
        if (getbit(x, 0) = 0, ignGear := 0);
        if (getbit(x, 1) = 0, ignLamp := 0);
        gearStatus := x;
        checkStatus := 60;
        statusPoll := 60;
    else
        if x = 0x8000
            Status := RANDINT(10, 60);
            adderror(3, "Gear not responding!");
            return(0);
        end
    end
end

# messages last one run only, so they are raised from the stored status on every run
if ((getbit(gearStatus, 0) = 1) and (ignGear = 0), adderror(1, "Control gear failure!"));
if ((getbit(gearStatus, 1) = 1) and (ignLamp = 0), adderror(2, "Lamp failure!"));
Inizializzazione
var x := 0; var rx := 0;
# QUERY STATUS 0x90: every reply byte proves the gear is present; 0x8000 = no answer, 0x20FF = bus collision
# an unread answer left in the gateway would be taken for this query: read it away and count it
x := modbusr(SH, 511, uint16); if (x != 0x8000, cntStale := cntStale + 1);
modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x90);
sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
x := modbusr(SH, 511, uint16);
cntQ := cntQ + 1; if (x = 0x8000, cntNone := cntNone + 1); if (x = 0x20FF, cntColl := cntColl + 1);
statusSeen := 0;
if x <= 0xFF
    # failure bits a gear reports from its first answer are its permanent state, not an event: shown, not raised
    gearStatus := x;
    ignGear := getbit(x, 0);
    ignLamp := getbit(x, 1);
    statusSeen := 1;
    Status := 0;
else
    Status := RANDINT(1, 60);
end

if Status = 0
    x := modbusr(SH, 511, uint16); if (x != 0x8000, cntStale := cntStale + 1);
    modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA2);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    x := modbusr(SH, 511, uint16);
    cntQ := cntQ + 1; if (x = 0x8000, cntNone := cntNone + 1); if (x = 0x20FF, cntColl := cntColl + 1);
    if (x <= 0xFE, minLevel := x);

    x := modbusr(SH, 511, uint16); if (x != 0x8000, cntStale := cntStale + 1);
    modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA1);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    x := modbusr(SH, 511, uint16);
    cntQ := cntQ + 1; if (x = 0x8000, cntNone := cntNone + 1); if (x = 0x20FF, cntColl := cntColl + 1);
    if (x <= 0xFE, maxLevel := x);
end
Lettura livello
var x := 0; var rx := 0; var y := 0;
if Status = 0
    if minLevel = 0
        # an unread answer left in the gateway would be taken for this query: read it away and count it
        x := modbusr(SH, 511, uint16); if (x != 0x8000, cntStale := cntStale + 1);
        modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA2);
        sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
        x := modbusr(SH, 511, uint16);
        cntQ := cntQ + 1; if (x = 0x8000, cntNone := cntNone + 1); if (x = 0x20FF, cntColl := cntColl + 1);
        if (x <= 0xFE, minLevel := x);
    end
    x := modbusr(SH, 511, uint16); if (x != 0x8000, cntStale := cntStale + 1);
    modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA0);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    x := modbusr(SH, 511, uint16);
    cntQ := cntQ + 1; if (x = 0x8000, cntNone := cntNone + 1); if (x = 0x20FF, cntColl := cntColl + 1);
    if (x != 0x8000 or rx, checkStatus := 60);
    # 0xFF = MASK, 0x20FF = collision, 0x8000 = no answer: keep the last level instead of a phantom value
    if x > 0xFE
        return(Le);
    end
    # an actual level is 0 or between the gear's min and max: anything else is not this gear's answer
    if x > 0 and x < minLevel
        cntBad := cntBad + 1;
        return(Le);
    end
    # a changed level must be read twice the same before it is taken
    if x != lastRaw
        y := modbusr(SH, 511, uint16); if (y != 0x8000, cntStale := cntStale + 1);
        modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA0);
        sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
        y := modbusr(SH, 511, uint16);
        cntQ := cntQ + 1; if (y = 0x8000, cntNone := cntNone + 1); if (y = 0x20FF, cntColl := cntColl + 1);
        if y != x
            cntBad := cntBad + 1;
            return(Le);
        end
        lastRaw := x;
    end
    return(if(x = 0, 0, linear(x, minLevel, 0.01, maxLevel, 1)));
else
    return(NaN);
end
Scrittura livello
var level := 0;
if(Le > 0, level := round(linear(Le, 0.01, minLevel, 1, maxLevel)));
modbusw(SH, 510, uint16, (ShortAddress << 8) + level );
Attributi di servizio
${xml_short_address}
ShortAddress
${xml_device_type}
var x := 0; var y := 0; var rx := 0; var s := ""; var i := 0;
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x99);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    x := modbusr(SH, 511, uint16);
    if (x < 0xFF, return("DT" + x));
    if x = 0xFF
        while i < 8
            modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA7);
            sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
            y := modbusr(SH, 511, uint16);
            if y < 0xFE
                s := if(s = "", "DT" + y, s + ", DT" + y);
                i := i + 1;
            else
                i := 8;
            end
        loop
        return(if(s = "", "MASK", s));
    end
end

return("--")
Physical Min Level
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x9A);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if (x <= 0xFE, return(round((x / 0xFE) * 100) + " %"));
end

return("--")
Max Level
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA1);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if (x <= 0xFE, return(round((x / 0xFE) * 100) + " %"));
end

return("--")
Min Level
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA2);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if (x <= 0xFE, return(round((x / 0xFE) * 100) + " %"));
end

return("--")
Power Up Level
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA3);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if (x <= 0xFE, return(round((x / 0xFE) * 100) + " %"));
end

return("--")
System Failure Level
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA4);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if (x <= 0xFE, return(round((x / 0xFE) * 100) + " %"));
end

return("--")
${xml_groups}
var x := 0; var rx := 0;
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xC0);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var g1 := modbusr(SH, 511, uint16);
    if (g1 > 0xFF, return("--")); 

    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xC1);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var g2 := modbusr(SH, 511, uint16);
    if (g2 > 0xFF, return("--")); 

    var ret := "";

    if (getbit(g1, 0), ret := ret + "0");
    if (getbit(g1, 1), if (ret = "", ret := "1", ret := ret + ",1"));
    if (getbit(g1, 2), if (ret = "", ret := "2", ret := ret + ",2"));
    if (getbit(g1, 3), if (ret = "", ret := "3", ret := ret + ",3"));
    if (getbit(g1, 4), if (ret = "", ret := "4", ret := ret + ",4"));
    if (getbit(g1, 5), if (ret = "", ret := "5", ret := ret + ",5"));
    if (getbit(g1, 6), if (ret = "", ret := "6", ret := ret + ",6"));
    if (getbit(g1, 7), if (ret = "", ret := "7", ret := ret + ",7"));
    if (getbit(g2, 0), if (ret = "", ret := "8", ret := ret + ",8"));
    if (getbit(g2, 1), if (ret = "", ret := "9", ret := ret + ",9"));
    if (getbit(g2, 2), if (ret = "", ret := "10", ret := ret + ",10"));
    if (getbit(g2, 3), if (ret = "", ret := "11", ret := ret + ",11"));
    if (getbit(g2, 4), if (ret = "", ret := "12", ret := ret + ",12"));
    if (getbit(g2, 5), if (ret = "", ret := "13", ret := ret + ",13"));
    if (getbit(g2, 6), if (ret = "", ret := "14", ret := ret + ",14"));
    if (getbit(g2, 7), if (ret = "", ret := "15", ret := ret + ",15"));

    if (ret = "", return("None"), return(ret));
else
    return("--");
end
DALI Status
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x90);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if x <= 0xFF
        var s := "";
        if (getbit(x, 0), s := if(s = "", "gear failure", s + ", gear failure"));
        if (getbit(x, 1), s := if(s = "", "lamp failure", s + ", lamp failure"));
        if (getbit(x, 2), s := if(s = "", "lamp on", s + ", lamp on"));
        if (getbit(x, 3), s := if(s = "", "limit error", s + ", limit error"));
        if (getbit(x, 4), s := if(s = "", "fade running", s + ", fade running"));
        if (getbit(x, 5), s := if(s = "", "reset state", s + ", reset state"));
        if (getbit(x, 6), s := if(s = "", "missing short address", s + ", missing short address"));
        if (getbit(x, 7), s := if(s = "", "power cycle", s + ", power cycle"));
        var ign := if((ignGear = 1) and (ignLamp = 1), "gear and lamp failure", if(ignGear = 1, "gear failure", if(ignLamp = 1, "lamp failure", "")));
        return(if(s = "", "OK", s) + " (0x" + tostring(x, "X2") + ")" + if(ign = "", "", "; not raised: " + ign + " reported since start"));
    end
end

return("--")
Fade
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA5);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if x <= 0xFF
        var t := getbits(x, 4, 4);
        var ret := if(t = 0, "off", t + " (" + round(sqrt(power(2, t)) * 5) / 10 + " s)");
        modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA8);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
        var e := modbusr(SH, 511, uint16);
        if (t = 0 and e <= 0xFF and e != 0, ret := "extended 0x" + tostring(e, "X2"));
        return("fade time " + ret + ", fade rate " + getbits(x, 0, 4));
    end
end

return("--")
DALI Version
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x97);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if x <= 0xFF
        return(if(x >= 8, "DALI-2 " + getbits(x, 2, 6) + "." + getbits(x, 0, 2), "DALI-1") + " (" + x + ")");
    end
end

return("--")
Bus statistics
return("since start: queries " + cntQ + ", stale answers read away " + cntStale + ", no answer " + cntNone + ", collisions " + cntColl + ", rejected levels " + cntBad)
Azioni di servizio
${xml_add_to_group}
Parametri: Group ID (0–15 grp)
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x60 + grp);
${xml_remove_from_group}
Parametri: Group ID (0–15 grp)
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x70 + grp);
${xml_reset_to_default_settings}
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x20);
${xml_set_startup_levels}
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x21);
sleep(10);
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x2c);
sleep(10);
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x2d);
Disable fading
modbusw(SH, 541, uint16, 0xA300);
sleep(100);
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x2E);
sleep(100);
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x30);
Gear 20 Dimmer Lettura e scrittura

Dispositivo di controllo DALI all'indirizzo breve 20 — dimmer TapHome mappato su DALI arc power 0–100 % tramite H:510 LAMP LEVEL (scrittura) e QUERY ACTUAL LEVEL tramite H:511 (lettura), delimitato dai propri MIN / MAX LEVEL del gear.

Registro: H:511 → H:510 UInt16 Unità: % numeric
Attributi di servizio
Indirizzo breveIndirizzo breve DALI (0–63) target di questo dispositivo — fissato al momento dell'importazione del template e utilizzato nel byte alto di ogni scrittura Modbus.
Device TypeByte device-type DALI restituito da QUERY DEVICE TYPE (0x99) — riporta DT0 (fluorescente), DT6 (driver LED), DT8 (colore / tunable white) ecc., o -- quando non c'è risposta.
Physical Min LevelLivello minimo di dimmerazione imposto dall'hardware riportato dal gear — letto da QUERY PHYSICAL MIN LEVEL (0x9A), in percentuale.
Max LevelDALI MAX LEVEL configurato — letto da QUERY MAX LEVEL (0xA1); utilizzato come limite superiore durante la scalatura di TapHome 0–100 % su DALI arc power.
Min LevelDALI MIN LEVEL configurato — letto da QUERY MIN LEVEL (0xA2); utilizzato come limite inferiore durante la scalatura di TapHome 0–100 % su DALI arc power.
Power Up LevelLuminosità ripristinata dopo il ripristino dell'alimentazione del bus DALI — letta da QUERY POWER ON LEVEL (0xA3).
System Failure LevelLuminosità adottata quando il bus DALI perde la comunicazione per più di 500 ms — letta da QUERY SYSTEM FAILURE LEVEL (0xA4).
GruppiElenco separato da virgole dei gruppi DALI (0–15) a cui appartiene il gear — decodificato da QUERY GROUPS 0-7 (0xC0) e QUERY GROUPS 8-15 (0xC1); mostra None o ad es. 0,3,7.
Support Lamp FailureSe la lampada / driver supporta il rilevamento dei guasti della lampada — Yes / No / --. Gestisce l'errore Lamp failure! nel readscript periodico.
Support Power FailureSe la lampada / driver supporta il rilevamento dei guasti di alimentazione — Yes / No / --. Gestisce l'errore Power failure! nel readscript periodico.
DALI Version
Bus statistics
Azioni di servizio
Add to GroupAggiunge questo gear a un gruppo DALI (0–15) tramite ADD TO GROUP (0x60+grp) — auto-ripetuto entro 100 ms come richiesto per i comandi di configurazione DALI.
Remove from GroupRimuove questo gear da un gruppo DALI (0–15) tramite REMOVE FROM GROUP (0x70+grp).
Reset to Default SettingsInvia DALI RESET (0x20) — ripristina ogni parametro NVM del gear (livelli max / min / power-on / system-failure, appartenenza al gruppo, scene) al valore predefinito del produttore.
Set Startup LevelsCattura l'arc power corrente e la memorizza come Power On Level e System Failure Level — sequenza STORE ACTUAL LEVEL IN DTR (0x21) → STORE DTR AS POWER ON LEVEL (0x2C) → STORE DTR AS SYSTEM FAILURE LEVEL (0x2D).
Disable fading

Gear 20

Lettura (modulo)
var x := 0; var rx := 0; var y := 0;
if Status > 0
    Status := Status - 1;
    adderror(3, "Gear not responding!");
    return(0);
end

# checkStatus: ReadLevel resets it while the gear answers; statusPoll: QUERY STATUS at least once per 60 runs
checkStatus := checkStatus - 1;
statusPoll := statusPoll - 1;
if checkStatus < 1 or statusPoll < 1
    # an unread answer left in the gateway would be taken for this query: read it away and count it
    x := modbusr(SH, 511, uint16); if (x != 0x8000, cntStale := cntStale + 1);
    modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x90);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    x := modbusr(SH, 511, uint16);
    cntQ := cntQ + 1; if (x = 0x8000, cntNone := cntNone + 1); if (x = 0x20FF, cntColl := cntColl + 1);
    # a single lost answer happens on DALI: ask once more before declaring the gear missing
    if x = 0x8000
        x := modbusr(SH, 511, uint16); if (x != 0x8000, cntStale := cntStale + 1);
        modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x90);
        sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
        x := modbusr(SH, 511, uint16);
        cntQ := cntQ + 1; if (x = 0x8000, cntNone := cntNone + 1); if (x = 0x20FF, cntColl := cntColl + 1);
    end
    if x <= 0xFF
        # a changed failure bit must be read twice the same before it is taken
        if statusSeen = 1 and getbits(x, 0, 2) != getbits(gearStatus, 0, 2)
            y := modbusr(SH, 511, uint16); if (y != 0x8000, cntStale := cntStale + 1);
            modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x90);
            sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
            y := modbusr(SH, 511, uint16);
            cntQ := cntQ + 1; if (y = 0x8000, cntNone := cntNone + 1); if (y = 0x20FF, cntColl := cntColl + 1);
            if y != x
                cntBad := cntBad + 1;
                x := gearStatus;
            end
        end
        if statusSeen = 0
            ignGear := getbit(x, 0);
            ignLamp := getbit(x, 1);
            statusSeen := 1;
        end
        # a bit that clears ends its ignore, so a later failure is raised
        if (getbit(x, 0) = 0, ignGear := 0);
        if (getbit(x, 1) = 0, ignLamp := 0);
        gearStatus := x;
        checkStatus := 60;
        statusPoll := 60;
    else
        if x = 0x8000
            Status := RANDINT(10, 60);
            adderror(3, "Gear not responding!");
            return(0);
        end
    end
end

# messages last one run only, so they are raised from the stored status on every run
if ((getbit(gearStatus, 0) = 1) and (ignGear = 0), adderror(1, "Control gear failure!"));
if ((getbit(gearStatus, 1) = 1) and (ignLamp = 0), adderror(2, "Lamp failure!"));
Inizializzazione
var x := 0; var rx := 0;
# QUERY STATUS 0x90: every reply byte proves the gear is present; 0x8000 = no answer, 0x20FF = bus collision
# an unread answer left in the gateway would be taken for this query: read it away and count it
x := modbusr(SH, 511, uint16); if (x != 0x8000, cntStale := cntStale + 1);
modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x90);
sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
x := modbusr(SH, 511, uint16);
cntQ := cntQ + 1; if (x = 0x8000, cntNone := cntNone + 1); if (x = 0x20FF, cntColl := cntColl + 1);
statusSeen := 0;
if x <= 0xFF
    # failure bits a gear reports from its first answer are its permanent state, not an event: shown, not raised
    gearStatus := x;
    ignGear := getbit(x, 0);
    ignLamp := getbit(x, 1);
    statusSeen := 1;
    Status := 0;
else
    Status := RANDINT(1, 60);
end

if Status = 0
    x := modbusr(SH, 511, uint16); if (x != 0x8000, cntStale := cntStale + 1);
    modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA2);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    x := modbusr(SH, 511, uint16);
    cntQ := cntQ + 1; if (x = 0x8000, cntNone := cntNone + 1); if (x = 0x20FF, cntColl := cntColl + 1);
    if (x <= 0xFE, minLevel := x);

    x := modbusr(SH, 511, uint16); if (x != 0x8000, cntStale := cntStale + 1);
    modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA1);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    x := modbusr(SH, 511, uint16);
    cntQ := cntQ + 1; if (x = 0x8000, cntNone := cntNone + 1); if (x = 0x20FF, cntColl := cntColl + 1);
    if (x <= 0xFE, maxLevel := x);
end
Lettura livello
var x := 0; var rx := 0; var y := 0;
if Status = 0
    if minLevel = 0
        # an unread answer left in the gateway would be taken for this query: read it away and count it
        x := modbusr(SH, 511, uint16); if (x != 0x8000, cntStale := cntStale + 1);
        modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA2);
        sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
        x := modbusr(SH, 511, uint16);
        cntQ := cntQ + 1; if (x = 0x8000, cntNone := cntNone + 1); if (x = 0x20FF, cntColl := cntColl + 1);
        if (x <= 0xFE, minLevel := x);
    end
    x := modbusr(SH, 511, uint16); if (x != 0x8000, cntStale := cntStale + 1);
    modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA0);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    x := modbusr(SH, 511, uint16);
    cntQ := cntQ + 1; if (x = 0x8000, cntNone := cntNone + 1); if (x = 0x20FF, cntColl := cntColl + 1);
    if (x != 0x8000 or rx, checkStatus := 60);
    # 0xFF = MASK, 0x20FF = collision, 0x8000 = no answer: keep the last level instead of a phantom value
    if x > 0xFE
        return(Le);
    end
    # an actual level is 0 or between the gear's min and max: anything else is not this gear's answer
    if x > 0 and x < minLevel
        cntBad := cntBad + 1;
        return(Le);
    end
    # a changed level must be read twice the same before it is taken
    if x != lastRaw
        y := modbusr(SH, 511, uint16); if (y != 0x8000, cntStale := cntStale + 1);
        modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA0);
        sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
        y := modbusr(SH, 511, uint16);
        cntQ := cntQ + 1; if (y = 0x8000, cntNone := cntNone + 1); if (y = 0x20FF, cntColl := cntColl + 1);
        if y != x
            cntBad := cntBad + 1;
            return(Le);
        end
        lastRaw := x;
    end
    return(if(x = 0, 0, linear(x, minLevel, 0.01, maxLevel, 1)));
else
    return(NaN);
end
Scrittura livello
var level := 0;
if(Le > 0, level := round(linear(Le, 0.01, minLevel, 1, maxLevel)));
modbusw(SH, 510, uint16, (ShortAddress << 8) + level );
Attributi di servizio
${xml_short_address}
ShortAddress
${xml_device_type}
var x := 0; var y := 0; var rx := 0; var s := ""; var i := 0;
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x99);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    x := modbusr(SH, 511, uint16);
    if (x < 0xFF, return("DT" + x));
    if x = 0xFF
        while i < 8
            modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA7);
            sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
            y := modbusr(SH, 511, uint16);
            if y < 0xFE
                s := if(s = "", "DT" + y, s + ", DT" + y);
                i := i + 1;
            else
                i := 8;
            end
        loop
        return(if(s = "", "MASK", s));
    end
end

return("--")
Physical Min Level
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x9A);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if (x <= 0xFE, return(round((x / 0xFE) * 100) + " %"));
end

return("--")
Max Level
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA1);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if (x <= 0xFE, return(round((x / 0xFE) * 100) + " %"));
end

return("--")
Min Level
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA2);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if (x <= 0xFE, return(round((x / 0xFE) * 100) + " %"));
end

return("--")
Power Up Level
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA3);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if (x <= 0xFE, return(round((x / 0xFE) * 100) + " %"));
end

return("--")
System Failure Level
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA4);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if (x <= 0xFE, return(round((x / 0xFE) * 100) + " %"));
end

return("--")
${xml_groups}
var x := 0; var rx := 0;
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xC0);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var g1 := modbusr(SH, 511, uint16);
    if (g1 > 0xFF, return("--")); 

    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xC1);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var g2 := modbusr(SH, 511, uint16);
    if (g2 > 0xFF, return("--")); 

    var ret := "";

    if (getbit(g1, 0), ret := ret + "0");
    if (getbit(g1, 1), if (ret = "", ret := "1", ret := ret + ",1"));
    if (getbit(g1, 2), if (ret = "", ret := "2", ret := ret + ",2"));
    if (getbit(g1, 3), if (ret = "", ret := "3", ret := ret + ",3"));
    if (getbit(g1, 4), if (ret = "", ret := "4", ret := ret + ",4"));
    if (getbit(g1, 5), if (ret = "", ret := "5", ret := ret + ",5"));
    if (getbit(g1, 6), if (ret = "", ret := "6", ret := ret + ",6"));
    if (getbit(g1, 7), if (ret = "", ret := "7", ret := ret + ",7"));
    if (getbit(g2, 0), if (ret = "", ret := "8", ret := ret + ",8"));
    if (getbit(g2, 1), if (ret = "", ret := "9", ret := ret + ",9"));
    if (getbit(g2, 2), if (ret = "", ret := "10", ret := ret + ",10"));
    if (getbit(g2, 3), if (ret = "", ret := "11", ret := ret + ",11"));
    if (getbit(g2, 4), if (ret = "", ret := "12", ret := ret + ",12"));
    if (getbit(g2, 5), if (ret = "", ret := "13", ret := ret + ",13"));
    if (getbit(g2, 6), if (ret = "", ret := "14", ret := ret + ",14"));
    if (getbit(g2, 7), if (ret = "", ret := "15", ret := ret + ",15"));

    if (ret = "", return("None"), return(ret));
else
    return("--");
end
DALI Status
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x90);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if x <= 0xFF
        var s := "";
        if (getbit(x, 0), s := if(s = "", "gear failure", s + ", gear failure"));
        if (getbit(x, 1), s := if(s = "", "lamp failure", s + ", lamp failure"));
        if (getbit(x, 2), s := if(s = "", "lamp on", s + ", lamp on"));
        if (getbit(x, 3), s := if(s = "", "limit error", s + ", limit error"));
        if (getbit(x, 4), s := if(s = "", "fade running", s + ", fade running"));
        if (getbit(x, 5), s := if(s = "", "reset state", s + ", reset state"));
        if (getbit(x, 6), s := if(s = "", "missing short address", s + ", missing short address"));
        if (getbit(x, 7), s := if(s = "", "power cycle", s + ", power cycle"));
        var ign := if((ignGear = 1) and (ignLamp = 1), "gear and lamp failure", if(ignGear = 1, "gear failure", if(ignLamp = 1, "lamp failure", "")));
        return(if(s = "", "OK", s) + " (0x" + tostring(x, "X2") + ")" + if(ign = "", "", "; not raised: " + ign + " reported since start"));
    end
end

return("--")
Fade
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA5);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if x <= 0xFF
        var t := getbits(x, 4, 4);
        var ret := if(t = 0, "off", t + " (" + round(sqrt(power(2, t)) * 5) / 10 + " s)");
        modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA8);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
        var e := modbusr(SH, 511, uint16);
        if (t = 0 and e <= 0xFF and e != 0, ret := "extended 0x" + tostring(e, "X2"));
        return("fade time " + ret + ", fade rate " + getbits(x, 0, 4));
    end
end

return("--")
DALI Version
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x97);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if x <= 0xFF
        return(if(x >= 8, "DALI-2 " + getbits(x, 2, 6) + "." + getbits(x, 0, 2), "DALI-1") + " (" + x + ")");
    end
end

return("--")
Bus statistics
return("since start: queries " + cntQ + ", stale answers read away " + cntStale + ", no answer " + cntNone + ", collisions " + cntColl + ", rejected levels " + cntBad)
Azioni di servizio
${xml_add_to_group}
Parametri: Group ID (0–15 grp)
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x60 + grp);
${xml_remove_from_group}
Parametri: Group ID (0–15 grp)
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x70 + grp);
${xml_reset_to_default_settings}
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x20);
${xml_set_startup_levels}
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x21);
sleep(10);
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x2c);
sleep(10);
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x2d);
Disable fading
modbusw(SH, 541, uint16, 0xA300);
sleep(100);
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x2E);
sleep(100);
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x30);
Gear 21 Dimmer Lettura e scrittura

Dispositivo di controllo DALI all'indirizzo breve 21 — dimmer TapHome mappato su DALI arc power 0–100 % tramite H:510 LAMP LEVEL (scrittura) e QUERY ACTUAL LEVEL tramite H:511 (lettura), delimitato dai propri MIN / MAX LEVEL del gear.

Registro: H:511 → H:510 UInt16 Unità: % numeric
Attributi di servizio
Indirizzo breveIndirizzo breve DALI (0–63) target di questo dispositivo — fissato al momento dell'importazione del template e utilizzato nel byte alto di ogni scrittura Modbus.
Device TypeByte device-type DALI restituito da QUERY DEVICE TYPE (0x99) — riporta DT0 (fluorescente), DT6 (driver LED), DT8 (colore / tunable white) ecc., o -- quando non c'è risposta.
Physical Min LevelLivello minimo di dimmerazione imposto dall'hardware riportato dal gear — letto da QUERY PHYSICAL MIN LEVEL (0x9A), in percentuale.
Max LevelDALI MAX LEVEL configurato — letto da QUERY MAX LEVEL (0xA1); utilizzato come limite superiore durante la scalatura di TapHome 0–100 % su DALI arc power.
Min LevelDALI MIN LEVEL configurato — letto da QUERY MIN LEVEL (0xA2); utilizzato come limite inferiore durante la scalatura di TapHome 0–100 % su DALI arc power.
Power Up LevelLuminosità ripristinata dopo il ripristino dell'alimentazione del bus DALI — letta da QUERY POWER ON LEVEL (0xA3).
System Failure LevelLuminosità adottata quando il bus DALI perde la comunicazione per più di 500 ms — letta da QUERY SYSTEM FAILURE LEVEL (0xA4).
GruppiElenco separato da virgole dei gruppi DALI (0–15) a cui appartiene il gear — decodificato da QUERY GROUPS 0-7 (0xC0) e QUERY GROUPS 8-15 (0xC1); mostra None o ad es. 0,3,7.
Support Lamp FailureSe la lampada / driver supporta il rilevamento dei guasti della lampada — Yes / No / --. Gestisce l'errore Lamp failure! nel readscript periodico.
Support Power FailureSe la lampada / driver supporta il rilevamento dei guasti di alimentazione — Yes / No / --. Gestisce l'errore Power failure! nel readscript periodico.
DALI Version
Bus statistics
Azioni di servizio
Add to GroupAggiunge questo gear a un gruppo DALI (0–15) tramite ADD TO GROUP (0x60+grp) — auto-ripetuto entro 100 ms come richiesto per i comandi di configurazione DALI.
Remove from GroupRimuove questo gear da un gruppo DALI (0–15) tramite REMOVE FROM GROUP (0x70+grp).
Reset to Default SettingsInvia DALI RESET (0x20) — ripristina ogni parametro NVM del gear (livelli max / min / power-on / system-failure, appartenenza al gruppo, scene) al valore predefinito del produttore.
Set Startup LevelsCattura l'arc power corrente e la memorizza come Power On Level e System Failure Level — sequenza STORE ACTUAL LEVEL IN DTR (0x21) → STORE DTR AS POWER ON LEVEL (0x2C) → STORE DTR AS SYSTEM FAILURE LEVEL (0x2D).
Disable fading

Gear 21

Lettura (modulo)
var x := 0; var rx := 0; var y := 0;
if Status > 0
    Status := Status - 1;
    adderror(3, "Gear not responding!");
    return(0);
end

# checkStatus: ReadLevel resets it while the gear answers; statusPoll: QUERY STATUS at least once per 60 runs
checkStatus := checkStatus - 1;
statusPoll := statusPoll - 1;
if checkStatus < 1 or statusPoll < 1
    # an unread answer left in the gateway would be taken for this query: read it away and count it
    x := modbusr(SH, 511, uint16); if (x != 0x8000, cntStale := cntStale + 1);
    modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x90);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    x := modbusr(SH, 511, uint16);
    cntQ := cntQ + 1; if (x = 0x8000, cntNone := cntNone + 1); if (x = 0x20FF, cntColl := cntColl + 1);
    # a single lost answer happens on DALI: ask once more before declaring the gear missing
    if x = 0x8000
        x := modbusr(SH, 511, uint16); if (x != 0x8000, cntStale := cntStale + 1);
        modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x90);
        sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
        x := modbusr(SH, 511, uint16);
        cntQ := cntQ + 1; if (x = 0x8000, cntNone := cntNone + 1); if (x = 0x20FF, cntColl := cntColl + 1);
    end
    if x <= 0xFF
        # a changed failure bit must be read twice the same before it is taken
        if statusSeen = 1 and getbits(x, 0, 2) != getbits(gearStatus, 0, 2)
            y := modbusr(SH, 511, uint16); if (y != 0x8000, cntStale := cntStale + 1);
            modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x90);
            sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
            y := modbusr(SH, 511, uint16);
            cntQ := cntQ + 1; if (y = 0x8000, cntNone := cntNone + 1); if (y = 0x20FF, cntColl := cntColl + 1);
            if y != x
                cntBad := cntBad + 1;
                x := gearStatus;
            end
        end
        if statusSeen = 0
            ignGear := getbit(x, 0);
            ignLamp := getbit(x, 1);
            statusSeen := 1;
        end
        # a bit that clears ends its ignore, so a later failure is raised
        if (getbit(x, 0) = 0, ignGear := 0);
        if (getbit(x, 1) = 0, ignLamp := 0);
        gearStatus := x;
        checkStatus := 60;
        statusPoll := 60;
    else
        if x = 0x8000
            Status := RANDINT(10, 60);
            adderror(3, "Gear not responding!");
            return(0);
        end
    end
end

# messages last one run only, so they are raised from the stored status on every run
if ((getbit(gearStatus, 0) = 1) and (ignGear = 0), adderror(1, "Control gear failure!"));
if ((getbit(gearStatus, 1) = 1) and (ignLamp = 0), adderror(2, "Lamp failure!"));
Inizializzazione
var x := 0; var rx := 0;
# QUERY STATUS 0x90: every reply byte proves the gear is present; 0x8000 = no answer, 0x20FF = bus collision
# an unread answer left in the gateway would be taken for this query: read it away and count it
x := modbusr(SH, 511, uint16); if (x != 0x8000, cntStale := cntStale + 1);
modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x90);
sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
x := modbusr(SH, 511, uint16);
cntQ := cntQ + 1; if (x = 0x8000, cntNone := cntNone + 1); if (x = 0x20FF, cntColl := cntColl + 1);
statusSeen := 0;
if x <= 0xFF
    # failure bits a gear reports from its first answer are its permanent state, not an event: shown, not raised
    gearStatus := x;
    ignGear := getbit(x, 0);
    ignLamp := getbit(x, 1);
    statusSeen := 1;
    Status := 0;
else
    Status := RANDINT(1, 60);
end

if Status = 0
    x := modbusr(SH, 511, uint16); if (x != 0x8000, cntStale := cntStale + 1);
    modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA2);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    x := modbusr(SH, 511, uint16);
    cntQ := cntQ + 1; if (x = 0x8000, cntNone := cntNone + 1); if (x = 0x20FF, cntColl := cntColl + 1);
    if (x <= 0xFE, minLevel := x);

    x := modbusr(SH, 511, uint16); if (x != 0x8000, cntStale := cntStale + 1);
    modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA1);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    x := modbusr(SH, 511, uint16);
    cntQ := cntQ + 1; if (x = 0x8000, cntNone := cntNone + 1); if (x = 0x20FF, cntColl := cntColl + 1);
    if (x <= 0xFE, maxLevel := x);
end
Lettura livello
var x := 0; var rx := 0; var y := 0;
if Status = 0
    if minLevel = 0
        # an unread answer left in the gateway would be taken for this query: read it away and count it
        x := modbusr(SH, 511, uint16); if (x != 0x8000, cntStale := cntStale + 1);
        modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA2);
        sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
        x := modbusr(SH, 511, uint16);
        cntQ := cntQ + 1; if (x = 0x8000, cntNone := cntNone + 1); if (x = 0x20FF, cntColl := cntColl + 1);
        if (x <= 0xFE, minLevel := x);
    end
    x := modbusr(SH, 511, uint16); if (x != 0x8000, cntStale := cntStale + 1);
    modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA0);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    x := modbusr(SH, 511, uint16);
    cntQ := cntQ + 1; if (x = 0x8000, cntNone := cntNone + 1); if (x = 0x20FF, cntColl := cntColl + 1);
    if (x != 0x8000 or rx, checkStatus := 60);
    # 0xFF = MASK, 0x20FF = collision, 0x8000 = no answer: keep the last level instead of a phantom value
    if x > 0xFE
        return(Le);
    end
    # an actual level is 0 or between the gear's min and max: anything else is not this gear's answer
    if x > 0 and x < minLevel
        cntBad := cntBad + 1;
        return(Le);
    end
    # a changed level must be read twice the same before it is taken
    if x != lastRaw
        y := modbusr(SH, 511, uint16); if (y != 0x8000, cntStale := cntStale + 1);
        modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA0);
        sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
        y := modbusr(SH, 511, uint16);
        cntQ := cntQ + 1; if (y = 0x8000, cntNone := cntNone + 1); if (y = 0x20FF, cntColl := cntColl + 1);
        if y != x
            cntBad := cntBad + 1;
            return(Le);
        end
        lastRaw := x;
    end
    return(if(x = 0, 0, linear(x, minLevel, 0.01, maxLevel, 1)));
else
    return(NaN);
end
Scrittura livello
var level := 0;
if(Le > 0, level := round(linear(Le, 0.01, minLevel, 1, maxLevel)));
modbusw(SH, 510, uint16, (ShortAddress << 8) + level );
Attributi di servizio
${xml_short_address}
ShortAddress
${xml_device_type}
var x := 0; var y := 0; var rx := 0; var s := ""; var i := 0;
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x99);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    x := modbusr(SH, 511, uint16);
    if (x < 0xFF, return("DT" + x));
    if x = 0xFF
        while i < 8
            modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA7);
            sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
            y := modbusr(SH, 511, uint16);
            if y < 0xFE
                s := if(s = "", "DT" + y, s + ", DT" + y);
                i := i + 1;
            else
                i := 8;
            end
        loop
        return(if(s = "", "MASK", s));
    end
end

return("--")
Physical Min Level
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x9A);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if (x <= 0xFE, return(round((x / 0xFE) * 100) + " %"));
end

return("--")
Max Level
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA1);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if (x <= 0xFE, return(round((x / 0xFE) * 100) + " %"));
end

return("--")
Min Level
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA2);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if (x <= 0xFE, return(round((x / 0xFE) * 100) + " %"));
end

return("--")
Power Up Level
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA3);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if (x <= 0xFE, return(round((x / 0xFE) * 100) + " %"));
end

return("--")
System Failure Level
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA4);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if (x <= 0xFE, return(round((x / 0xFE) * 100) + " %"));
end

return("--")
${xml_groups}
var x := 0; var rx := 0;
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xC0);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var g1 := modbusr(SH, 511, uint16);
    if (g1 > 0xFF, return("--")); 

    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xC1);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var g2 := modbusr(SH, 511, uint16);
    if (g2 > 0xFF, return("--")); 

    var ret := "";

    if (getbit(g1, 0), ret := ret + "0");
    if (getbit(g1, 1), if (ret = "", ret := "1", ret := ret + ",1"));
    if (getbit(g1, 2), if (ret = "", ret := "2", ret := ret + ",2"));
    if (getbit(g1, 3), if (ret = "", ret := "3", ret := ret + ",3"));
    if (getbit(g1, 4), if (ret = "", ret := "4", ret := ret + ",4"));
    if (getbit(g1, 5), if (ret = "", ret := "5", ret := ret + ",5"));
    if (getbit(g1, 6), if (ret = "", ret := "6", ret := ret + ",6"));
    if (getbit(g1, 7), if (ret = "", ret := "7", ret := ret + ",7"));
    if (getbit(g2, 0), if (ret = "", ret := "8", ret := ret + ",8"));
    if (getbit(g2, 1), if (ret = "", ret := "9", ret := ret + ",9"));
    if (getbit(g2, 2), if (ret = "", ret := "10", ret := ret + ",10"));
    if (getbit(g2, 3), if (ret = "", ret := "11", ret := ret + ",11"));
    if (getbit(g2, 4), if (ret = "", ret := "12", ret := ret + ",12"));
    if (getbit(g2, 5), if (ret = "", ret := "13", ret := ret + ",13"));
    if (getbit(g2, 6), if (ret = "", ret := "14", ret := ret + ",14"));
    if (getbit(g2, 7), if (ret = "", ret := "15", ret := ret + ",15"));

    if (ret = "", return("None"), return(ret));
else
    return("--");
end
DALI Status
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x90);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if x <= 0xFF
        var s := "";
        if (getbit(x, 0), s := if(s = "", "gear failure", s + ", gear failure"));
        if (getbit(x, 1), s := if(s = "", "lamp failure", s + ", lamp failure"));
        if (getbit(x, 2), s := if(s = "", "lamp on", s + ", lamp on"));
        if (getbit(x, 3), s := if(s = "", "limit error", s + ", limit error"));
        if (getbit(x, 4), s := if(s = "", "fade running", s + ", fade running"));
        if (getbit(x, 5), s := if(s = "", "reset state", s + ", reset state"));
        if (getbit(x, 6), s := if(s = "", "missing short address", s + ", missing short address"));
        if (getbit(x, 7), s := if(s = "", "power cycle", s + ", power cycle"));
        var ign := if((ignGear = 1) and (ignLamp = 1), "gear and lamp failure", if(ignGear = 1, "gear failure", if(ignLamp = 1, "lamp failure", "")));
        return(if(s = "", "OK", s) + " (0x" + tostring(x, "X2") + ")" + if(ign = "", "", "; not raised: " + ign + " reported since start"));
    end
end

return("--")
Fade
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA5);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if x <= 0xFF
        var t := getbits(x, 4, 4);
        var ret := if(t = 0, "off", t + " (" + round(sqrt(power(2, t)) * 5) / 10 + " s)");
        modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA8);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
        var e := modbusr(SH, 511, uint16);
        if (t = 0 and e <= 0xFF and e != 0, ret := "extended 0x" + tostring(e, "X2"));
        return("fade time " + ret + ", fade rate " + getbits(x, 0, 4));
    end
end

return("--")
DALI Version
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x97);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if x <= 0xFF
        return(if(x >= 8, "DALI-2 " + getbits(x, 2, 6) + "." + getbits(x, 0, 2), "DALI-1") + " (" + x + ")");
    end
end

return("--")
Bus statistics
return("since start: queries " + cntQ + ", stale answers read away " + cntStale + ", no answer " + cntNone + ", collisions " + cntColl + ", rejected levels " + cntBad)
Azioni di servizio
${xml_add_to_group}
Parametri: Group ID (0–15 grp)
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x60 + grp);
${xml_remove_from_group}
Parametri: Group ID (0–15 grp)
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x70 + grp);
${xml_reset_to_default_settings}
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x20);
${xml_set_startup_levels}
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x21);
sleep(10);
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x2c);
sleep(10);
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x2d);
Disable fading
modbusw(SH, 541, uint16, 0xA300);
sleep(100);
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x2E);
sleep(100);
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x30);
Gear 22 Dimmer Lettura e scrittura

Dispositivo di controllo DALI all'indirizzo breve 22 — dimmer TapHome mappato su DALI arc power 0–100 % tramite H:510 LAMP LEVEL (scrittura) e QUERY ACTUAL LEVEL tramite H:511 (lettura), delimitato dai propri MIN / MAX LEVEL del gear.

Registro: H:511 → H:510 UInt16 Unità: % numeric
Attributi di servizio
Indirizzo breveIndirizzo breve DALI (0–63) target di questo dispositivo — fissato al momento dell'importazione del template e utilizzato nel byte alto di ogni scrittura Modbus.
Device TypeByte device-type DALI restituito da QUERY DEVICE TYPE (0x99) — riporta DT0 (fluorescente), DT6 (driver LED), DT8 (colore / tunable white) ecc., o -- quando non c'è risposta.
Physical Min LevelLivello minimo di dimmerazione imposto dall'hardware riportato dal gear — letto da QUERY PHYSICAL MIN LEVEL (0x9A), in percentuale.
Max LevelDALI MAX LEVEL configurato — letto da QUERY MAX LEVEL (0xA1); utilizzato come limite superiore durante la scalatura di TapHome 0–100 % su DALI arc power.
Min LevelDALI MIN LEVEL configurato — letto da QUERY MIN LEVEL (0xA2); utilizzato come limite inferiore durante la scalatura di TapHome 0–100 % su DALI arc power.
Power Up LevelLuminosità ripristinata dopo il ripristino dell'alimentazione del bus DALI — letta da QUERY POWER ON LEVEL (0xA3).
System Failure LevelLuminosità adottata quando il bus DALI perde la comunicazione per più di 500 ms — letta da QUERY SYSTEM FAILURE LEVEL (0xA4).
GruppiElenco separato da virgole dei gruppi DALI (0–15) a cui appartiene il gear — decodificato da QUERY GROUPS 0-7 (0xC0) e QUERY GROUPS 8-15 (0xC1); mostra None o ad es. 0,3,7.
Support Lamp FailureSe la lampada / driver supporta il rilevamento dei guasti della lampada — Yes / No / --. Gestisce l'errore Lamp failure! nel readscript periodico.
Support Power FailureSe la lampada / driver supporta il rilevamento dei guasti di alimentazione — Yes / No / --. Gestisce l'errore Power failure! nel readscript periodico.
DALI Version
Bus statistics
Azioni di servizio
Add to GroupAggiunge questo gear a un gruppo DALI (0–15) tramite ADD TO GROUP (0x60+grp) — auto-ripetuto entro 100 ms come richiesto per i comandi di configurazione DALI.
Remove from GroupRimuove questo gear da un gruppo DALI (0–15) tramite REMOVE FROM GROUP (0x70+grp).
Reset to Default SettingsInvia DALI RESET (0x20) — ripristina ogni parametro NVM del gear (livelli max / min / power-on / system-failure, appartenenza al gruppo, scene) al valore predefinito del produttore.
Set Startup LevelsCattura l'arc power corrente e la memorizza come Power On Level e System Failure Level — sequenza STORE ACTUAL LEVEL IN DTR (0x21) → STORE DTR AS POWER ON LEVEL (0x2C) → STORE DTR AS SYSTEM FAILURE LEVEL (0x2D).
Disable fading

Gear 22

Lettura (modulo)
var x := 0; var rx := 0; var y := 0;
if Status > 0
    Status := Status - 1;
    adderror(3, "Gear not responding!");
    return(0);
end

# checkStatus: ReadLevel resets it while the gear answers; statusPoll: QUERY STATUS at least once per 60 runs
checkStatus := checkStatus - 1;
statusPoll := statusPoll - 1;
if checkStatus < 1 or statusPoll < 1
    # an unread answer left in the gateway would be taken for this query: read it away and count it
    x := modbusr(SH, 511, uint16); if (x != 0x8000, cntStale := cntStale + 1);
    modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x90);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    x := modbusr(SH, 511, uint16);
    cntQ := cntQ + 1; if (x = 0x8000, cntNone := cntNone + 1); if (x = 0x20FF, cntColl := cntColl + 1);
    # a single lost answer happens on DALI: ask once more before declaring the gear missing
    if x = 0x8000
        x := modbusr(SH, 511, uint16); if (x != 0x8000, cntStale := cntStale + 1);
        modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x90);
        sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
        x := modbusr(SH, 511, uint16);
        cntQ := cntQ + 1; if (x = 0x8000, cntNone := cntNone + 1); if (x = 0x20FF, cntColl := cntColl + 1);
    end
    if x <= 0xFF
        # a changed failure bit must be read twice the same before it is taken
        if statusSeen = 1 and getbits(x, 0, 2) != getbits(gearStatus, 0, 2)
            y := modbusr(SH, 511, uint16); if (y != 0x8000, cntStale := cntStale + 1);
            modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x90);
            sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
            y := modbusr(SH, 511, uint16);
            cntQ := cntQ + 1; if (y = 0x8000, cntNone := cntNone + 1); if (y = 0x20FF, cntColl := cntColl + 1);
            if y != x
                cntBad := cntBad + 1;
                x := gearStatus;
            end
        end
        if statusSeen = 0
            ignGear := getbit(x, 0);
            ignLamp := getbit(x, 1);
            statusSeen := 1;
        end
        # a bit that clears ends its ignore, so a later failure is raised
        if (getbit(x, 0) = 0, ignGear := 0);
        if (getbit(x, 1) = 0, ignLamp := 0);
        gearStatus := x;
        checkStatus := 60;
        statusPoll := 60;
    else
        if x = 0x8000
            Status := RANDINT(10, 60);
            adderror(3, "Gear not responding!");
            return(0);
        end
    end
end

# messages last one run only, so they are raised from the stored status on every run
if ((getbit(gearStatus, 0) = 1) and (ignGear = 0), adderror(1, "Control gear failure!"));
if ((getbit(gearStatus, 1) = 1) and (ignLamp = 0), adderror(2, "Lamp failure!"));
Inizializzazione
var x := 0; var rx := 0;
# QUERY STATUS 0x90: every reply byte proves the gear is present; 0x8000 = no answer, 0x20FF = bus collision
# an unread answer left in the gateway would be taken for this query: read it away and count it
x := modbusr(SH, 511, uint16); if (x != 0x8000, cntStale := cntStale + 1);
modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x90);
sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
x := modbusr(SH, 511, uint16);
cntQ := cntQ + 1; if (x = 0x8000, cntNone := cntNone + 1); if (x = 0x20FF, cntColl := cntColl + 1);
statusSeen := 0;
if x <= 0xFF
    # failure bits a gear reports from its first answer are its permanent state, not an event: shown, not raised
    gearStatus := x;
    ignGear := getbit(x, 0);
    ignLamp := getbit(x, 1);
    statusSeen := 1;
    Status := 0;
else
    Status := RANDINT(1, 60);
end

if Status = 0
    x := modbusr(SH, 511, uint16); if (x != 0x8000, cntStale := cntStale + 1);
    modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA2);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    x := modbusr(SH, 511, uint16);
    cntQ := cntQ + 1; if (x = 0x8000, cntNone := cntNone + 1); if (x = 0x20FF, cntColl := cntColl + 1);
    if (x <= 0xFE, minLevel := x);

    x := modbusr(SH, 511, uint16); if (x != 0x8000, cntStale := cntStale + 1);
    modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA1);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    x := modbusr(SH, 511, uint16);
    cntQ := cntQ + 1; if (x = 0x8000, cntNone := cntNone + 1); if (x = 0x20FF, cntColl := cntColl + 1);
    if (x <= 0xFE, maxLevel := x);
end
Lettura livello
var x := 0; var rx := 0; var y := 0;
if Status = 0
    if minLevel = 0
        # an unread answer left in the gateway would be taken for this query: read it away and count it
        x := modbusr(SH, 511, uint16); if (x != 0x8000, cntStale := cntStale + 1);
        modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA2);
        sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
        x := modbusr(SH, 511, uint16);
        cntQ := cntQ + 1; if (x = 0x8000, cntNone := cntNone + 1); if (x = 0x20FF, cntColl := cntColl + 1);
        if (x <= 0xFE, minLevel := x);
    end
    x := modbusr(SH, 511, uint16); if (x != 0x8000, cntStale := cntStale + 1);
    modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA0);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    x := modbusr(SH, 511, uint16);
    cntQ := cntQ + 1; if (x = 0x8000, cntNone := cntNone + 1); if (x = 0x20FF, cntColl := cntColl + 1);
    if (x != 0x8000 or rx, checkStatus := 60);
    # 0xFF = MASK, 0x20FF = collision, 0x8000 = no answer: keep the last level instead of a phantom value
    if x > 0xFE
        return(Le);
    end
    # an actual level is 0 or between the gear's min and max: anything else is not this gear's answer
    if x > 0 and x < minLevel
        cntBad := cntBad + 1;
        return(Le);
    end
    # a changed level must be read twice the same before it is taken
    if x != lastRaw
        y := modbusr(SH, 511, uint16); if (y != 0x8000, cntStale := cntStale + 1);
        modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA0);
        sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
        y := modbusr(SH, 511, uint16);
        cntQ := cntQ + 1; if (y = 0x8000, cntNone := cntNone + 1); if (y = 0x20FF, cntColl := cntColl + 1);
        if y != x
            cntBad := cntBad + 1;
            return(Le);
        end
        lastRaw := x;
    end
    return(if(x = 0, 0, linear(x, minLevel, 0.01, maxLevel, 1)));
else
    return(NaN);
end
Scrittura livello
var level := 0;
if(Le > 0, level := round(linear(Le, 0.01, minLevel, 1, maxLevel)));
modbusw(SH, 510, uint16, (ShortAddress << 8) + level );
Attributi di servizio
${xml_short_address}
ShortAddress
${xml_device_type}
var x := 0; var y := 0; var rx := 0; var s := ""; var i := 0;
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x99);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    x := modbusr(SH, 511, uint16);
    if (x < 0xFF, return("DT" + x));
    if x = 0xFF
        while i < 8
            modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA7);
            sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
            y := modbusr(SH, 511, uint16);
            if y < 0xFE
                s := if(s = "", "DT" + y, s + ", DT" + y);
                i := i + 1;
            else
                i := 8;
            end
        loop
        return(if(s = "", "MASK", s));
    end
end

return("--")
Physical Min Level
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x9A);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if (x <= 0xFE, return(round((x / 0xFE) * 100) + " %"));
end

return("--")
Max Level
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA1);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if (x <= 0xFE, return(round((x / 0xFE) * 100) + " %"));
end

return("--")
Min Level
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA2);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if (x <= 0xFE, return(round((x / 0xFE) * 100) + " %"));
end

return("--")
Power Up Level
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA3);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if (x <= 0xFE, return(round((x / 0xFE) * 100) + " %"));
end

return("--")
System Failure Level
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA4);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if (x <= 0xFE, return(round((x / 0xFE) * 100) + " %"));
end

return("--")
${xml_groups}
var x := 0; var rx := 0;
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xC0);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var g1 := modbusr(SH, 511, uint16);
    if (g1 > 0xFF, return("--")); 

    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xC1);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var g2 := modbusr(SH, 511, uint16);
    if (g2 > 0xFF, return("--")); 

    var ret := "";

    if (getbit(g1, 0), ret := ret + "0");
    if (getbit(g1, 1), if (ret = "", ret := "1", ret := ret + ",1"));
    if (getbit(g1, 2), if (ret = "", ret := "2", ret := ret + ",2"));
    if (getbit(g1, 3), if (ret = "", ret := "3", ret := ret + ",3"));
    if (getbit(g1, 4), if (ret = "", ret := "4", ret := ret + ",4"));
    if (getbit(g1, 5), if (ret = "", ret := "5", ret := ret + ",5"));
    if (getbit(g1, 6), if (ret = "", ret := "6", ret := ret + ",6"));
    if (getbit(g1, 7), if (ret = "", ret := "7", ret := ret + ",7"));
    if (getbit(g2, 0), if (ret = "", ret := "8", ret := ret + ",8"));
    if (getbit(g2, 1), if (ret = "", ret := "9", ret := ret + ",9"));
    if (getbit(g2, 2), if (ret = "", ret := "10", ret := ret + ",10"));
    if (getbit(g2, 3), if (ret = "", ret := "11", ret := ret + ",11"));
    if (getbit(g2, 4), if (ret = "", ret := "12", ret := ret + ",12"));
    if (getbit(g2, 5), if (ret = "", ret := "13", ret := ret + ",13"));
    if (getbit(g2, 6), if (ret = "", ret := "14", ret := ret + ",14"));
    if (getbit(g2, 7), if (ret = "", ret := "15", ret := ret + ",15"));

    if (ret = "", return("None"), return(ret));
else
    return("--");
end
DALI Status
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x90);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if x <= 0xFF
        var s := "";
        if (getbit(x, 0), s := if(s = "", "gear failure", s + ", gear failure"));
        if (getbit(x, 1), s := if(s = "", "lamp failure", s + ", lamp failure"));
        if (getbit(x, 2), s := if(s = "", "lamp on", s + ", lamp on"));
        if (getbit(x, 3), s := if(s = "", "limit error", s + ", limit error"));
        if (getbit(x, 4), s := if(s = "", "fade running", s + ", fade running"));
        if (getbit(x, 5), s := if(s = "", "reset state", s + ", reset state"));
        if (getbit(x, 6), s := if(s = "", "missing short address", s + ", missing short address"));
        if (getbit(x, 7), s := if(s = "", "power cycle", s + ", power cycle"));
        var ign := if((ignGear = 1) and (ignLamp = 1), "gear and lamp failure", if(ignGear = 1, "gear failure", if(ignLamp = 1, "lamp failure", "")));
        return(if(s = "", "OK", s) + " (0x" + tostring(x, "X2") + ")" + if(ign = "", "", "; not raised: " + ign + " reported since start"));
    end
end

return("--")
Fade
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA5);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if x <= 0xFF
        var t := getbits(x, 4, 4);
        var ret := if(t = 0, "off", t + " (" + round(sqrt(power(2, t)) * 5) / 10 + " s)");
        modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA8);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
        var e := modbusr(SH, 511, uint16);
        if (t = 0 and e <= 0xFF and e != 0, ret := "extended 0x" + tostring(e, "X2"));
        return("fade time " + ret + ", fade rate " + getbits(x, 0, 4));
    end
end

return("--")
DALI Version
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x97);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if x <= 0xFF
        return(if(x >= 8, "DALI-2 " + getbits(x, 2, 6) + "." + getbits(x, 0, 2), "DALI-1") + " (" + x + ")");
    end
end

return("--")
Bus statistics
return("since start: queries " + cntQ + ", stale answers read away " + cntStale + ", no answer " + cntNone + ", collisions " + cntColl + ", rejected levels " + cntBad)
Azioni di servizio
${xml_add_to_group}
Parametri: Group ID (0–15 grp)
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x60 + grp);
${xml_remove_from_group}
Parametri: Group ID (0–15 grp)
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x70 + grp);
${xml_reset_to_default_settings}
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x20);
${xml_set_startup_levels}
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x21);
sleep(10);
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x2c);
sleep(10);
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x2d);
Disable fading
modbusw(SH, 541, uint16, 0xA300);
sleep(100);
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x2E);
sleep(100);
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x30);
Gear 23 Dimmer Lettura e scrittura

Dispositivo di controllo DALI all'indirizzo breve 23 — dimmer TapHome mappato su DALI arc power 0–100 % tramite H:510 LAMP LEVEL (scrittura) e QUERY ACTUAL LEVEL tramite H:511 (lettura), delimitato dai propri MIN / MAX LEVEL del gear.

Registro: H:511 → H:510 UInt16 Unità: % numeric
Attributi di servizio
Indirizzo breveIndirizzo breve DALI (0–63) target di questo dispositivo — fissato al momento dell'importazione del template e utilizzato nel byte alto di ogni scrittura Modbus.
Device TypeByte device-type DALI restituito da QUERY DEVICE TYPE (0x99) — riporta DT0 (fluorescente), DT6 (driver LED), DT8 (colore / tunable white) ecc., o -- quando non c'è risposta.
Physical Min LevelLivello minimo di dimmerazione imposto dall'hardware riportato dal gear — letto da QUERY PHYSICAL MIN LEVEL (0x9A), in percentuale.
Max LevelDALI MAX LEVEL configurato — letto da QUERY MAX LEVEL (0xA1); utilizzato come limite superiore durante la scalatura di TapHome 0–100 % su DALI arc power.
Min LevelDALI MIN LEVEL configurato — letto da QUERY MIN LEVEL (0xA2); utilizzato come limite inferiore durante la scalatura di TapHome 0–100 % su DALI arc power.
Power Up LevelLuminosità ripristinata dopo il ripristino dell'alimentazione del bus DALI — letta da QUERY POWER ON LEVEL (0xA3).
System Failure LevelLuminosità adottata quando il bus DALI perde la comunicazione per più di 500 ms — letta da QUERY SYSTEM FAILURE LEVEL (0xA4).
GruppiElenco separato da virgole dei gruppi DALI (0–15) a cui appartiene il gear — decodificato da QUERY GROUPS 0-7 (0xC0) e QUERY GROUPS 8-15 (0xC1); mostra None o ad es. 0,3,7.
Support Lamp FailureSe la lampada / driver supporta il rilevamento dei guasti della lampada — Yes / No / --. Gestisce l'errore Lamp failure! nel readscript periodico.
Support Power FailureSe la lampada / driver supporta il rilevamento dei guasti di alimentazione — Yes / No / --. Gestisce l'errore Power failure! nel readscript periodico.
DALI Version
Bus statistics
Azioni di servizio
Add to GroupAggiunge questo gear a un gruppo DALI (0–15) tramite ADD TO GROUP (0x60+grp) — auto-ripetuto entro 100 ms come richiesto per i comandi di configurazione DALI.
Remove from GroupRimuove questo gear da un gruppo DALI (0–15) tramite REMOVE FROM GROUP (0x70+grp).
Reset to Default SettingsInvia DALI RESET (0x20) — ripristina ogni parametro NVM del gear (livelli max / min / power-on / system-failure, appartenenza al gruppo, scene) al valore predefinito del produttore.
Set Startup LevelsCattura l'arc power corrente e la memorizza come Power On Level e System Failure Level — sequenza STORE ACTUAL LEVEL IN DTR (0x21) → STORE DTR AS POWER ON LEVEL (0x2C) → STORE DTR AS SYSTEM FAILURE LEVEL (0x2D).
Disable fading

Gear 23

Lettura (modulo)
var x := 0; var rx := 0; var y := 0;
if Status > 0
    Status := Status - 1;
    adderror(3, "Gear not responding!");
    return(0);
end

# checkStatus: ReadLevel resets it while the gear answers; statusPoll: QUERY STATUS at least once per 60 runs
checkStatus := checkStatus - 1;
statusPoll := statusPoll - 1;
if checkStatus < 1 or statusPoll < 1
    # an unread answer left in the gateway would be taken for this query: read it away and count it
    x := modbusr(SH, 511, uint16); if (x != 0x8000, cntStale := cntStale + 1);
    modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x90);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    x := modbusr(SH, 511, uint16);
    cntQ := cntQ + 1; if (x = 0x8000, cntNone := cntNone + 1); if (x = 0x20FF, cntColl := cntColl + 1);
    # a single lost answer happens on DALI: ask once more before declaring the gear missing
    if x = 0x8000
        x := modbusr(SH, 511, uint16); if (x != 0x8000, cntStale := cntStale + 1);
        modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x90);
        sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
        x := modbusr(SH, 511, uint16);
        cntQ := cntQ + 1; if (x = 0x8000, cntNone := cntNone + 1); if (x = 0x20FF, cntColl := cntColl + 1);
    end
    if x <= 0xFF
        # a changed failure bit must be read twice the same before it is taken
        if statusSeen = 1 and getbits(x, 0, 2) != getbits(gearStatus, 0, 2)
            y := modbusr(SH, 511, uint16); if (y != 0x8000, cntStale := cntStale + 1);
            modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x90);
            sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
            y := modbusr(SH, 511, uint16);
            cntQ := cntQ + 1; if (y = 0x8000, cntNone := cntNone + 1); if (y = 0x20FF, cntColl := cntColl + 1);
            if y != x
                cntBad := cntBad + 1;
                x := gearStatus;
            end
        end
        if statusSeen = 0
            ignGear := getbit(x, 0);
            ignLamp := getbit(x, 1);
            statusSeen := 1;
        end
        # a bit that clears ends its ignore, so a later failure is raised
        if (getbit(x, 0) = 0, ignGear := 0);
        if (getbit(x, 1) = 0, ignLamp := 0);
        gearStatus := x;
        checkStatus := 60;
        statusPoll := 60;
    else
        if x = 0x8000
            Status := RANDINT(10, 60);
            adderror(3, "Gear not responding!");
            return(0);
        end
    end
end

# messages last one run only, so they are raised from the stored status on every run
if ((getbit(gearStatus, 0) = 1) and (ignGear = 0), adderror(1, "Control gear failure!"));
if ((getbit(gearStatus, 1) = 1) and (ignLamp = 0), adderror(2, "Lamp failure!"));
Inizializzazione
var x := 0; var rx := 0;
# QUERY STATUS 0x90: every reply byte proves the gear is present; 0x8000 = no answer, 0x20FF = bus collision
# an unread answer left in the gateway would be taken for this query: read it away and count it
x := modbusr(SH, 511, uint16); if (x != 0x8000, cntStale := cntStale + 1);
modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x90);
sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
x := modbusr(SH, 511, uint16);
cntQ := cntQ + 1; if (x = 0x8000, cntNone := cntNone + 1); if (x = 0x20FF, cntColl := cntColl + 1);
statusSeen := 0;
if x <= 0xFF
    # failure bits a gear reports from its first answer are its permanent state, not an event: shown, not raised
    gearStatus := x;
    ignGear := getbit(x, 0);
    ignLamp := getbit(x, 1);
    statusSeen := 1;
    Status := 0;
else
    Status := RANDINT(1, 60);
end

if Status = 0
    x := modbusr(SH, 511, uint16); if (x != 0x8000, cntStale := cntStale + 1);
    modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA2);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    x := modbusr(SH, 511, uint16);
    cntQ := cntQ + 1; if (x = 0x8000, cntNone := cntNone + 1); if (x = 0x20FF, cntColl := cntColl + 1);
    if (x <= 0xFE, minLevel := x);

    x := modbusr(SH, 511, uint16); if (x != 0x8000, cntStale := cntStale + 1);
    modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA1);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    x := modbusr(SH, 511, uint16);
    cntQ := cntQ + 1; if (x = 0x8000, cntNone := cntNone + 1); if (x = 0x20FF, cntColl := cntColl + 1);
    if (x <= 0xFE, maxLevel := x);
end
Lettura livello
var x := 0; var rx := 0; var y := 0;
if Status = 0
    if minLevel = 0
        # an unread answer left in the gateway would be taken for this query: read it away and count it
        x := modbusr(SH, 511, uint16); if (x != 0x8000, cntStale := cntStale + 1);
        modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA2);
        sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
        x := modbusr(SH, 511, uint16);
        cntQ := cntQ + 1; if (x = 0x8000, cntNone := cntNone + 1); if (x = 0x20FF, cntColl := cntColl + 1);
        if (x <= 0xFE, minLevel := x);
    end
    x := modbusr(SH, 511, uint16); if (x != 0x8000, cntStale := cntStale + 1);
    modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA0);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    x := modbusr(SH, 511, uint16);
    cntQ := cntQ + 1; if (x = 0x8000, cntNone := cntNone + 1); if (x = 0x20FF, cntColl := cntColl + 1);
    if (x != 0x8000 or rx, checkStatus := 60);
    # 0xFF = MASK, 0x20FF = collision, 0x8000 = no answer: keep the last level instead of a phantom value
    if x > 0xFE
        return(Le);
    end
    # an actual level is 0 or between the gear's min and max: anything else is not this gear's answer
    if x > 0 and x < minLevel
        cntBad := cntBad + 1;
        return(Le);
    end
    # a changed level must be read twice the same before it is taken
    if x != lastRaw
        y := modbusr(SH, 511, uint16); if (y != 0x8000, cntStale := cntStale + 1);
        modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA0);
        sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
        y := modbusr(SH, 511, uint16);
        cntQ := cntQ + 1; if (y = 0x8000, cntNone := cntNone + 1); if (y = 0x20FF, cntColl := cntColl + 1);
        if y != x
            cntBad := cntBad + 1;
            return(Le);
        end
        lastRaw := x;
    end
    return(if(x = 0, 0, linear(x, minLevel, 0.01, maxLevel, 1)));
else
    return(NaN);
end
Scrittura livello
var level := 0;
if(Le > 0, level := round(linear(Le, 0.01, minLevel, 1, maxLevel)));
modbusw(SH, 510, uint16, (ShortAddress << 8) + level );
Attributi di servizio
${xml_short_address}
ShortAddress
${xml_device_type}
var x := 0; var y := 0; var rx := 0; var s := ""; var i := 0;
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x99);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    x := modbusr(SH, 511, uint16);
    if (x < 0xFF, return("DT" + x));
    if x = 0xFF
        while i < 8
            modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA7);
            sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
            y := modbusr(SH, 511, uint16);
            if y < 0xFE
                s := if(s = "", "DT" + y, s + ", DT" + y);
                i := i + 1;
            else
                i := 8;
            end
        loop
        return(if(s = "", "MASK", s));
    end
end

return("--")
Physical Min Level
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x9A);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if (x <= 0xFE, return(round((x / 0xFE) * 100) + " %"));
end

return("--")
Max Level
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA1);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if (x <= 0xFE, return(round((x / 0xFE) * 100) + " %"));
end

return("--")
Min Level
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA2);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if (x <= 0xFE, return(round((x / 0xFE) * 100) + " %"));
end

return("--")
Power Up Level
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA3);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if (x <= 0xFE, return(round((x / 0xFE) * 100) + " %"));
end

return("--")
System Failure Level
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA4);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if (x <= 0xFE, return(round((x / 0xFE) * 100) + " %"));
end

return("--")
${xml_groups}
var x := 0; var rx := 0;
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xC0);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var g1 := modbusr(SH, 511, uint16);
    if (g1 > 0xFF, return("--")); 

    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xC1);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var g2 := modbusr(SH, 511, uint16);
    if (g2 > 0xFF, return("--")); 

    var ret := "";

    if (getbit(g1, 0), ret := ret + "0");
    if (getbit(g1, 1), if (ret = "", ret := "1", ret := ret + ",1"));
    if (getbit(g1, 2), if (ret = "", ret := "2", ret := ret + ",2"));
    if (getbit(g1, 3), if (ret = "", ret := "3", ret := ret + ",3"));
    if (getbit(g1, 4), if (ret = "", ret := "4", ret := ret + ",4"));
    if (getbit(g1, 5), if (ret = "", ret := "5", ret := ret + ",5"));
    if (getbit(g1, 6), if (ret = "", ret := "6", ret := ret + ",6"));
    if (getbit(g1, 7), if (ret = "", ret := "7", ret := ret + ",7"));
    if (getbit(g2, 0), if (ret = "", ret := "8", ret := ret + ",8"));
    if (getbit(g2, 1), if (ret = "", ret := "9", ret := ret + ",9"));
    if (getbit(g2, 2), if (ret = "", ret := "10", ret := ret + ",10"));
    if (getbit(g2, 3), if (ret = "", ret := "11", ret := ret + ",11"));
    if (getbit(g2, 4), if (ret = "", ret := "12", ret := ret + ",12"));
    if (getbit(g2, 5), if (ret = "", ret := "13", ret := ret + ",13"));
    if (getbit(g2, 6), if (ret = "", ret := "14", ret := ret + ",14"));
    if (getbit(g2, 7), if (ret = "", ret := "15", ret := ret + ",15"));

    if (ret = "", return("None"), return(ret));
else
    return("--");
end
DALI Status
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x90);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if x <= 0xFF
        var s := "";
        if (getbit(x, 0), s := if(s = "", "gear failure", s + ", gear failure"));
        if (getbit(x, 1), s := if(s = "", "lamp failure", s + ", lamp failure"));
        if (getbit(x, 2), s := if(s = "", "lamp on", s + ", lamp on"));
        if (getbit(x, 3), s := if(s = "", "limit error", s + ", limit error"));
        if (getbit(x, 4), s := if(s = "", "fade running", s + ", fade running"));
        if (getbit(x, 5), s := if(s = "", "reset state", s + ", reset state"));
        if (getbit(x, 6), s := if(s = "", "missing short address", s + ", missing short address"));
        if (getbit(x, 7), s := if(s = "", "power cycle", s + ", power cycle"));
        var ign := if((ignGear = 1) and (ignLamp = 1), "gear and lamp failure", if(ignGear = 1, "gear failure", if(ignLamp = 1, "lamp failure", "")));
        return(if(s = "", "OK", s) + " (0x" + tostring(x, "X2") + ")" + if(ign = "", "", "; not raised: " + ign + " reported since start"));
    end
end

return("--")
Fade
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA5);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if x <= 0xFF
        var t := getbits(x, 4, 4);
        var ret := if(t = 0, "off", t + " (" + round(sqrt(power(2, t)) * 5) / 10 + " s)");
        modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA8);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
        var e := modbusr(SH, 511, uint16);
        if (t = 0 and e <= 0xFF and e != 0, ret := "extended 0x" + tostring(e, "X2"));
        return("fade time " + ret + ", fade rate " + getbits(x, 0, 4));
    end
end

return("--")
DALI Version
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x97);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if x <= 0xFF
        return(if(x >= 8, "DALI-2 " + getbits(x, 2, 6) + "." + getbits(x, 0, 2), "DALI-1") + " (" + x + ")");
    end
end

return("--")
Bus statistics
return("since start: queries " + cntQ + ", stale answers read away " + cntStale + ", no answer " + cntNone + ", collisions " + cntColl + ", rejected levels " + cntBad)
Azioni di servizio
${xml_add_to_group}
Parametri: Group ID (0–15 grp)
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x60 + grp);
${xml_remove_from_group}
Parametri: Group ID (0–15 grp)
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x70 + grp);
${xml_reset_to_default_settings}
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x20);
${xml_set_startup_levels}
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x21);
sleep(10);
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x2c);
sleep(10);
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x2d);
Disable fading
modbusw(SH, 541, uint16, 0xA300);
sleep(100);
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x2E);
sleep(100);
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x30);
Gear 24 Dimmer Lettura e scrittura

Dispositivo di controllo DALI all'indirizzo breve 24 — dimmer TapHome mappato su DALI arc power 0–100 % tramite H:510 LAMP LEVEL (scrittura) e QUERY ACTUAL LEVEL tramite H:511 (lettura), delimitato dai propri MIN / MAX LEVEL del gear.

Registro: H:511 → H:510 UInt16 Unità: % numeric
Attributi di servizio
Indirizzo breveIndirizzo breve DALI (0–63) target di questo dispositivo — fissato al momento dell'importazione del template e utilizzato nel byte alto di ogni scrittura Modbus.
Device TypeByte device-type DALI restituito da QUERY DEVICE TYPE (0x99) — riporta DT0 (fluorescente), DT6 (driver LED), DT8 (colore / tunable white) ecc., o -- quando non c'è risposta.
Physical Min LevelLivello minimo di dimmerazione imposto dall'hardware riportato dal gear — letto da QUERY PHYSICAL MIN LEVEL (0x9A), in percentuale.
Max LevelDALI MAX LEVEL configurato — letto da QUERY MAX LEVEL (0xA1); utilizzato come limite superiore durante la scalatura di TapHome 0–100 % su DALI arc power.
Min LevelDALI MIN LEVEL configurato — letto da QUERY MIN LEVEL (0xA2); utilizzato come limite inferiore durante la scalatura di TapHome 0–100 % su DALI arc power.
Power Up LevelLuminosità ripristinata dopo il ripristino dell'alimentazione del bus DALI — letta da QUERY POWER ON LEVEL (0xA3).
System Failure LevelLuminosità adottata quando il bus DALI perde la comunicazione per più di 500 ms — letta da QUERY SYSTEM FAILURE LEVEL (0xA4).
GruppiElenco separato da virgole dei gruppi DALI (0–15) a cui appartiene il gear — decodificato da QUERY GROUPS 0-7 (0xC0) e QUERY GROUPS 8-15 (0xC1); mostra None o ad es. 0,3,7.
Support Lamp FailureSe la lampada / driver supporta il rilevamento dei guasti della lampada — Yes / No / --. Gestisce l'errore Lamp failure! nel readscript periodico.
Support Power FailureSe la lampada / driver supporta il rilevamento dei guasti di alimentazione — Yes / No / --. Gestisce l'errore Power failure! nel readscript periodico.
DALI Version
Bus statistics
Azioni di servizio
Add to GroupAggiunge questo gear a un gruppo DALI (0–15) tramite ADD TO GROUP (0x60+grp) — auto-ripetuto entro 100 ms come richiesto per i comandi di configurazione DALI.
Remove from GroupRimuove questo gear da un gruppo DALI (0–15) tramite REMOVE FROM GROUP (0x70+grp).
Reset to Default SettingsInvia DALI RESET (0x20) — ripristina ogni parametro NVM del gear (livelli max / min / power-on / system-failure, appartenenza al gruppo, scene) al valore predefinito del produttore.
Set Startup LevelsCattura l'arc power corrente e la memorizza come Power On Level e System Failure Level — sequenza STORE ACTUAL LEVEL IN DTR (0x21) → STORE DTR AS POWER ON LEVEL (0x2C) → STORE DTR AS SYSTEM FAILURE LEVEL (0x2D).
Disable fading

Gear 24

Lettura (modulo)
var x := 0; var rx := 0; var y := 0;
if Status > 0
    Status := Status - 1;
    adderror(3, "Gear not responding!");
    return(0);
end

# checkStatus: ReadLevel resets it while the gear answers; statusPoll: QUERY STATUS at least once per 60 runs
checkStatus := checkStatus - 1;
statusPoll := statusPoll - 1;
if checkStatus < 1 or statusPoll < 1
    # an unread answer left in the gateway would be taken for this query: read it away and count it
    x := modbusr(SH, 511, uint16); if (x != 0x8000, cntStale := cntStale + 1);
    modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x90);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    x := modbusr(SH, 511, uint16);
    cntQ := cntQ + 1; if (x = 0x8000, cntNone := cntNone + 1); if (x = 0x20FF, cntColl := cntColl + 1);
    # a single lost answer happens on DALI: ask once more before declaring the gear missing
    if x = 0x8000
        x := modbusr(SH, 511, uint16); if (x != 0x8000, cntStale := cntStale + 1);
        modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x90);
        sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
        x := modbusr(SH, 511, uint16);
        cntQ := cntQ + 1; if (x = 0x8000, cntNone := cntNone + 1); if (x = 0x20FF, cntColl := cntColl + 1);
    end
    if x <= 0xFF
        # a changed failure bit must be read twice the same before it is taken
        if statusSeen = 1 and getbits(x, 0, 2) != getbits(gearStatus, 0, 2)
            y := modbusr(SH, 511, uint16); if (y != 0x8000, cntStale := cntStale + 1);
            modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x90);
            sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
            y := modbusr(SH, 511, uint16);
            cntQ := cntQ + 1; if (y = 0x8000, cntNone := cntNone + 1); if (y = 0x20FF, cntColl := cntColl + 1);
            if y != x
                cntBad := cntBad + 1;
                x := gearStatus;
            end
        end
        if statusSeen = 0
            ignGear := getbit(x, 0);
            ignLamp := getbit(x, 1);
            statusSeen := 1;
        end
        # a bit that clears ends its ignore, so a later failure is raised
        if (getbit(x, 0) = 0, ignGear := 0);
        if (getbit(x, 1) = 0, ignLamp := 0);
        gearStatus := x;
        checkStatus := 60;
        statusPoll := 60;
    else
        if x = 0x8000
            Status := RANDINT(10, 60);
            adderror(3, "Gear not responding!");
            return(0);
        end
    end
end

# messages last one run only, so they are raised from the stored status on every run
if ((getbit(gearStatus, 0) = 1) and (ignGear = 0), adderror(1, "Control gear failure!"));
if ((getbit(gearStatus, 1) = 1) and (ignLamp = 0), adderror(2, "Lamp failure!"));
Inizializzazione
var x := 0; var rx := 0;
# QUERY STATUS 0x90: every reply byte proves the gear is present; 0x8000 = no answer, 0x20FF = bus collision
# an unread answer left in the gateway would be taken for this query: read it away and count it
x := modbusr(SH, 511, uint16); if (x != 0x8000, cntStale := cntStale + 1);
modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x90);
sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
x := modbusr(SH, 511, uint16);
cntQ := cntQ + 1; if (x = 0x8000, cntNone := cntNone + 1); if (x = 0x20FF, cntColl := cntColl + 1);
statusSeen := 0;
if x <= 0xFF
    # failure bits a gear reports from its first answer are its permanent state, not an event: shown, not raised
    gearStatus := x;
    ignGear := getbit(x, 0);
    ignLamp := getbit(x, 1);
    statusSeen := 1;
    Status := 0;
else
    Status := RANDINT(1, 60);
end

if Status = 0
    x := modbusr(SH, 511, uint16); if (x != 0x8000, cntStale := cntStale + 1);
    modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA2);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    x := modbusr(SH, 511, uint16);
    cntQ := cntQ + 1; if (x = 0x8000, cntNone := cntNone + 1); if (x = 0x20FF, cntColl := cntColl + 1);
    if (x <= 0xFE, minLevel := x);

    x := modbusr(SH, 511, uint16); if (x != 0x8000, cntStale := cntStale + 1);
    modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA1);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    x := modbusr(SH, 511, uint16);
    cntQ := cntQ + 1; if (x = 0x8000, cntNone := cntNone + 1); if (x = 0x20FF, cntColl := cntColl + 1);
    if (x <= 0xFE, maxLevel := x);
end
Lettura livello
var x := 0; var rx := 0; var y := 0;
if Status = 0
    if minLevel = 0
        # an unread answer left in the gateway would be taken for this query: read it away and count it
        x := modbusr(SH, 511, uint16); if (x != 0x8000, cntStale := cntStale + 1);
        modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA2);
        sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
        x := modbusr(SH, 511, uint16);
        cntQ := cntQ + 1; if (x = 0x8000, cntNone := cntNone + 1); if (x = 0x20FF, cntColl := cntColl + 1);
        if (x <= 0xFE, minLevel := x);
    end
    x := modbusr(SH, 511, uint16); if (x != 0x8000, cntStale := cntStale + 1);
    modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA0);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    x := modbusr(SH, 511, uint16);
    cntQ := cntQ + 1; if (x = 0x8000, cntNone := cntNone + 1); if (x = 0x20FF, cntColl := cntColl + 1);
    if (x != 0x8000 or rx, checkStatus := 60);
    # 0xFF = MASK, 0x20FF = collision, 0x8000 = no answer: keep the last level instead of a phantom value
    if x > 0xFE
        return(Le);
    end
    # an actual level is 0 or between the gear's min and max: anything else is not this gear's answer
    if x > 0 and x < minLevel
        cntBad := cntBad + 1;
        return(Le);
    end
    # a changed level must be read twice the same before it is taken
    if x != lastRaw
        y := modbusr(SH, 511, uint16); if (y != 0x8000, cntStale := cntStale + 1);
        modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA0);
        sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
        y := modbusr(SH, 511, uint16);
        cntQ := cntQ + 1; if (y = 0x8000, cntNone := cntNone + 1); if (y = 0x20FF, cntColl := cntColl + 1);
        if y != x
            cntBad := cntBad + 1;
            return(Le);
        end
        lastRaw := x;
    end
    return(if(x = 0, 0, linear(x, minLevel, 0.01, maxLevel, 1)));
else
    return(NaN);
end
Scrittura livello
var level := 0;
if(Le > 0, level := round(linear(Le, 0.01, minLevel, 1, maxLevel)));
modbusw(SH, 510, uint16, (ShortAddress << 8) + level );
Attributi di servizio
${xml_short_address}
ShortAddress
${xml_device_type}
var x := 0; var y := 0; var rx := 0; var s := ""; var i := 0;
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x99);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    x := modbusr(SH, 511, uint16);
    if (x < 0xFF, return("DT" + x));
    if x = 0xFF
        while i < 8
            modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA7);
            sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
            y := modbusr(SH, 511, uint16);
            if y < 0xFE
                s := if(s = "", "DT" + y, s + ", DT" + y);
                i := i + 1;
            else
                i := 8;
            end
        loop
        return(if(s = "", "MASK", s));
    end
end

return("--")
Physical Min Level
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x9A);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if (x <= 0xFE, return(round((x / 0xFE) * 100) + " %"));
end

return("--")
Max Level
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA1);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if (x <= 0xFE, return(round((x / 0xFE) * 100) + " %"));
end

return("--")
Min Level
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA2);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if (x <= 0xFE, return(round((x / 0xFE) * 100) + " %"));
end

return("--")
Power Up Level
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA3);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if (x <= 0xFE, return(round((x / 0xFE) * 100) + " %"));
end

return("--")
System Failure Level
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA4);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if (x <= 0xFE, return(round((x / 0xFE) * 100) + " %"));
end

return("--")
${xml_groups}
var x := 0; var rx := 0;
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xC0);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var g1 := modbusr(SH, 511, uint16);
    if (g1 > 0xFF, return("--")); 

    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xC1);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var g2 := modbusr(SH, 511, uint16);
    if (g2 > 0xFF, return("--")); 

    var ret := "";

    if (getbit(g1, 0), ret := ret + "0");
    if (getbit(g1, 1), if (ret = "", ret := "1", ret := ret + ",1"));
    if (getbit(g1, 2), if (ret = "", ret := "2", ret := ret + ",2"));
    if (getbit(g1, 3), if (ret = "", ret := "3", ret := ret + ",3"));
    if (getbit(g1, 4), if (ret = "", ret := "4", ret := ret + ",4"));
    if (getbit(g1, 5), if (ret = "", ret := "5", ret := ret + ",5"));
    if (getbit(g1, 6), if (ret = "", ret := "6", ret := ret + ",6"));
    if (getbit(g1, 7), if (ret = "", ret := "7", ret := ret + ",7"));
    if (getbit(g2, 0), if (ret = "", ret := "8", ret := ret + ",8"));
    if (getbit(g2, 1), if (ret = "", ret := "9", ret := ret + ",9"));
    if (getbit(g2, 2), if (ret = "", ret := "10", ret := ret + ",10"));
    if (getbit(g2, 3), if (ret = "", ret := "11", ret := ret + ",11"));
    if (getbit(g2, 4), if (ret = "", ret := "12", ret := ret + ",12"));
    if (getbit(g2, 5), if (ret = "", ret := "13", ret := ret + ",13"));
    if (getbit(g2, 6), if (ret = "", ret := "14", ret := ret + ",14"));
    if (getbit(g2, 7), if (ret = "", ret := "15", ret := ret + ",15"));

    if (ret = "", return("None"), return(ret));
else
    return("--");
end
DALI Status
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x90);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if x <= 0xFF
        var s := "";
        if (getbit(x, 0), s := if(s = "", "gear failure", s + ", gear failure"));
        if (getbit(x, 1), s := if(s = "", "lamp failure", s + ", lamp failure"));
        if (getbit(x, 2), s := if(s = "", "lamp on", s + ", lamp on"));
        if (getbit(x, 3), s := if(s = "", "limit error", s + ", limit error"));
        if (getbit(x, 4), s := if(s = "", "fade running", s + ", fade running"));
        if (getbit(x, 5), s := if(s = "", "reset state", s + ", reset state"));
        if (getbit(x, 6), s := if(s = "", "missing short address", s + ", missing short address"));
        if (getbit(x, 7), s := if(s = "", "power cycle", s + ", power cycle"));
        var ign := if((ignGear = 1) and (ignLamp = 1), "gear and lamp failure", if(ignGear = 1, "gear failure", if(ignLamp = 1, "lamp failure", "")));
        return(if(s = "", "OK", s) + " (0x" + tostring(x, "X2") + ")" + if(ign = "", "", "; not raised: " + ign + " reported since start"));
    end
end

return("--")
Fade
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA5);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if x <= 0xFF
        var t := getbits(x, 4, 4);
        var ret := if(t = 0, "off", t + " (" + round(sqrt(power(2, t)) * 5) / 10 + " s)");
        modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA8);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
        var e := modbusr(SH, 511, uint16);
        if (t = 0 and e <= 0xFF and e != 0, ret := "extended 0x" + tostring(e, "X2"));
        return("fade time " + ret + ", fade rate " + getbits(x, 0, 4));
    end
end

return("--")
DALI Version
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x97);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if x <= 0xFF
        return(if(x >= 8, "DALI-2 " + getbits(x, 2, 6) + "." + getbits(x, 0, 2), "DALI-1") + " (" + x + ")");
    end
end

return("--")
Bus statistics
return("since start: queries " + cntQ + ", stale answers read away " + cntStale + ", no answer " + cntNone + ", collisions " + cntColl + ", rejected levels " + cntBad)
Azioni di servizio
${xml_add_to_group}
Parametri: Group ID (0–15 grp)
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x60 + grp);
${xml_remove_from_group}
Parametri: Group ID (0–15 grp)
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x70 + grp);
${xml_reset_to_default_settings}
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x20);
${xml_set_startup_levels}
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x21);
sleep(10);
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x2c);
sleep(10);
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x2d);
Disable fading
modbusw(SH, 541, uint16, 0xA300);
sleep(100);
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x2E);
sleep(100);
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x30);
Gear 25 Dimmer Lettura e scrittura

Dispositivo di controllo DALI all'indirizzo breve 25 — dimmer TapHome mappato su DALI arc power 0–100 % tramite H:510 LAMP LEVEL (scrittura) e QUERY ACTUAL LEVEL tramite H:511 (lettura), delimitato dai propri MIN / MAX LEVEL del gear.

Registro: H:511 → H:510 UInt16 Unità: % numeric
Attributi di servizio
Indirizzo breveIndirizzo breve DALI (0–63) target di questo dispositivo — fissato al momento dell'importazione del template e utilizzato nel byte alto di ogni scrittura Modbus.
Device TypeByte device-type DALI restituito da QUERY DEVICE TYPE (0x99) — riporta DT0 (fluorescente), DT6 (driver LED), DT8 (colore / tunable white) ecc., o -- quando non c'è risposta.
Physical Min LevelLivello minimo di dimmerazione imposto dall'hardware riportato dal gear — letto da QUERY PHYSICAL MIN LEVEL (0x9A), in percentuale.
Max LevelDALI MAX LEVEL configurato — letto da QUERY MAX LEVEL (0xA1); utilizzato come limite superiore durante la scalatura di TapHome 0–100 % su DALI arc power.
Min LevelDALI MIN LEVEL configurato — letto da QUERY MIN LEVEL (0xA2); utilizzato come limite inferiore durante la scalatura di TapHome 0–100 % su DALI arc power.
Power Up LevelLuminosità ripristinata dopo il ripristino dell'alimentazione del bus DALI — letta da QUERY POWER ON LEVEL (0xA3).
System Failure LevelLuminosità adottata quando il bus DALI perde la comunicazione per più di 500 ms — letta da QUERY SYSTEM FAILURE LEVEL (0xA4).
GruppiElenco separato da virgole dei gruppi DALI (0–15) a cui appartiene il gear — decodificato da QUERY GROUPS 0-7 (0xC0) e QUERY GROUPS 8-15 (0xC1); mostra None o ad es. 0,3,7.
Support Lamp FailureSe la lampada / driver supporta il rilevamento dei guasti della lampada — Yes / No / --. Gestisce l'errore Lamp failure! nel readscript periodico.
Support Power FailureSe la lampada / driver supporta il rilevamento dei guasti di alimentazione — Yes / No / --. Gestisce l'errore Power failure! nel readscript periodico.
DALI Version
Bus statistics
Azioni di servizio
Add to GroupAggiunge questo gear a un gruppo DALI (0–15) tramite ADD TO GROUP (0x60+grp) — auto-ripetuto entro 100 ms come richiesto per i comandi di configurazione DALI.
Remove from GroupRimuove questo gear da un gruppo DALI (0–15) tramite REMOVE FROM GROUP (0x70+grp).
Reset to Default SettingsInvia DALI RESET (0x20) — ripristina ogni parametro NVM del gear (livelli max / min / power-on / system-failure, appartenenza al gruppo, scene) al valore predefinito del produttore.
Set Startup LevelsCattura l'arc power corrente e la memorizza come Power On Level e System Failure Level — sequenza STORE ACTUAL LEVEL IN DTR (0x21) → STORE DTR AS POWER ON LEVEL (0x2C) → STORE DTR AS SYSTEM FAILURE LEVEL (0x2D).
Disable fading

Gear 25

Lettura (modulo)
var x := 0; var rx := 0; var y := 0;
if Status > 0
    Status := Status - 1;
    adderror(3, "Gear not responding!");
    return(0);
end

# checkStatus: ReadLevel resets it while the gear answers; statusPoll: QUERY STATUS at least once per 60 runs
checkStatus := checkStatus - 1;
statusPoll := statusPoll - 1;
if checkStatus < 1 or statusPoll < 1
    # an unread answer left in the gateway would be taken for this query: read it away and count it
    x := modbusr(SH, 511, uint16); if (x != 0x8000, cntStale := cntStale + 1);
    modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x90);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    x := modbusr(SH, 511, uint16);
    cntQ := cntQ + 1; if (x = 0x8000, cntNone := cntNone + 1); if (x = 0x20FF, cntColl := cntColl + 1);
    # a single lost answer happens on DALI: ask once more before declaring the gear missing
    if x = 0x8000
        x := modbusr(SH, 511, uint16); if (x != 0x8000, cntStale := cntStale + 1);
        modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x90);
        sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
        x := modbusr(SH, 511, uint16);
        cntQ := cntQ + 1; if (x = 0x8000, cntNone := cntNone + 1); if (x = 0x20FF, cntColl := cntColl + 1);
    end
    if x <= 0xFF
        # a changed failure bit must be read twice the same before it is taken
        if statusSeen = 1 and getbits(x, 0, 2) != getbits(gearStatus, 0, 2)
            y := modbusr(SH, 511, uint16); if (y != 0x8000, cntStale := cntStale + 1);
            modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x90);
            sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
            y := modbusr(SH, 511, uint16);
            cntQ := cntQ + 1; if (y = 0x8000, cntNone := cntNone + 1); if (y = 0x20FF, cntColl := cntColl + 1);
            if y != x
                cntBad := cntBad + 1;
                x := gearStatus;
            end
        end
        if statusSeen = 0
            ignGear := getbit(x, 0);
            ignLamp := getbit(x, 1);
            statusSeen := 1;
        end
        # a bit that clears ends its ignore, so a later failure is raised
        if (getbit(x, 0) = 0, ignGear := 0);
        if (getbit(x, 1) = 0, ignLamp := 0);
        gearStatus := x;
        checkStatus := 60;
        statusPoll := 60;
    else
        if x = 0x8000
            Status := RANDINT(10, 60);
            adderror(3, "Gear not responding!");
            return(0);
        end
    end
end

# messages last one run only, so they are raised from the stored status on every run
if ((getbit(gearStatus, 0) = 1) and (ignGear = 0), adderror(1, "Control gear failure!"));
if ((getbit(gearStatus, 1) = 1) and (ignLamp = 0), adderror(2, "Lamp failure!"));
Inizializzazione
var x := 0; var rx := 0;
# QUERY STATUS 0x90: every reply byte proves the gear is present; 0x8000 = no answer, 0x20FF = bus collision
# an unread answer left in the gateway would be taken for this query: read it away and count it
x := modbusr(SH, 511, uint16); if (x != 0x8000, cntStale := cntStale + 1);
modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x90);
sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
x := modbusr(SH, 511, uint16);
cntQ := cntQ + 1; if (x = 0x8000, cntNone := cntNone + 1); if (x = 0x20FF, cntColl := cntColl + 1);
statusSeen := 0;
if x <= 0xFF
    # failure bits a gear reports from its first answer are its permanent state, not an event: shown, not raised
    gearStatus := x;
    ignGear := getbit(x, 0);
    ignLamp := getbit(x, 1);
    statusSeen := 1;
    Status := 0;
else
    Status := RANDINT(1, 60);
end

if Status = 0
    x := modbusr(SH, 511, uint16); if (x != 0x8000, cntStale := cntStale + 1);
    modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA2);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    x := modbusr(SH, 511, uint16);
    cntQ := cntQ + 1; if (x = 0x8000, cntNone := cntNone + 1); if (x = 0x20FF, cntColl := cntColl + 1);
    if (x <= 0xFE, minLevel := x);

    x := modbusr(SH, 511, uint16); if (x != 0x8000, cntStale := cntStale + 1);
    modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA1);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    x := modbusr(SH, 511, uint16);
    cntQ := cntQ + 1; if (x = 0x8000, cntNone := cntNone + 1); if (x = 0x20FF, cntColl := cntColl + 1);
    if (x <= 0xFE, maxLevel := x);
end
Lettura livello
var x := 0; var rx := 0; var y := 0;
if Status = 0
    if minLevel = 0
        # an unread answer left in the gateway would be taken for this query: read it away and count it
        x := modbusr(SH, 511, uint16); if (x != 0x8000, cntStale := cntStale + 1);
        modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA2);
        sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
        x := modbusr(SH, 511, uint16);
        cntQ := cntQ + 1; if (x = 0x8000, cntNone := cntNone + 1); if (x = 0x20FF, cntColl := cntColl + 1);
        if (x <= 0xFE, minLevel := x);
    end
    x := modbusr(SH, 511, uint16); if (x != 0x8000, cntStale := cntStale + 1);
    modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA0);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    x := modbusr(SH, 511, uint16);
    cntQ := cntQ + 1; if (x = 0x8000, cntNone := cntNone + 1); if (x = 0x20FF, cntColl := cntColl + 1);
    if (x != 0x8000 or rx, checkStatus := 60);
    # 0xFF = MASK, 0x20FF = collision, 0x8000 = no answer: keep the last level instead of a phantom value
    if x > 0xFE
        return(Le);
    end
    # an actual level is 0 or between the gear's min and max: anything else is not this gear's answer
    if x > 0 and x < minLevel
        cntBad := cntBad + 1;
        return(Le);
    end
    # a changed level must be read twice the same before it is taken
    if x != lastRaw
        y := modbusr(SH, 511, uint16); if (y != 0x8000, cntStale := cntStale + 1);
        modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA0);
        sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
        y := modbusr(SH, 511, uint16);
        cntQ := cntQ + 1; if (y = 0x8000, cntNone := cntNone + 1); if (y = 0x20FF, cntColl := cntColl + 1);
        if y != x
            cntBad := cntBad + 1;
            return(Le);
        end
        lastRaw := x;
    end
    return(if(x = 0, 0, linear(x, minLevel, 0.01, maxLevel, 1)));
else
    return(NaN);
end
Scrittura livello
var level := 0;
if(Le > 0, level := round(linear(Le, 0.01, minLevel, 1, maxLevel)));
modbusw(SH, 510, uint16, (ShortAddress << 8) + level );
Attributi di servizio
${xml_short_address}
ShortAddress
${xml_device_type}
var x := 0; var y := 0; var rx := 0; var s := ""; var i := 0;
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x99);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    x := modbusr(SH, 511, uint16);
    if (x < 0xFF, return("DT" + x));
    if x = 0xFF
        while i < 8
            modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA7);
            sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
            y := modbusr(SH, 511, uint16);
            if y < 0xFE
                s := if(s = "", "DT" + y, s + ", DT" + y);
                i := i + 1;
            else
                i := 8;
            end
        loop
        return(if(s = "", "MASK", s));
    end
end

return("--")
Physical Min Level
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x9A);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if (x <= 0xFE, return(round((x / 0xFE) * 100) + " %"));
end

return("--")
Max Level
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA1);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if (x <= 0xFE, return(round((x / 0xFE) * 100) + " %"));
end

return("--")
Min Level
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA2);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if (x <= 0xFE, return(round((x / 0xFE) * 100) + " %"));
end

return("--")
Power Up Level
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA3);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if (x <= 0xFE, return(round((x / 0xFE) * 100) + " %"));
end

return("--")
System Failure Level
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA4);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if (x <= 0xFE, return(round((x / 0xFE) * 100) + " %"));
end

return("--")
${xml_groups}
var x := 0; var rx := 0;
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xC0);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var g1 := modbusr(SH, 511, uint16);
    if (g1 > 0xFF, return("--")); 

    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xC1);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var g2 := modbusr(SH, 511, uint16);
    if (g2 > 0xFF, return("--")); 

    var ret := "";

    if (getbit(g1, 0), ret := ret + "0");
    if (getbit(g1, 1), if (ret = "", ret := "1", ret := ret + ",1"));
    if (getbit(g1, 2), if (ret = "", ret := "2", ret := ret + ",2"));
    if (getbit(g1, 3), if (ret = "", ret := "3", ret := ret + ",3"));
    if (getbit(g1, 4), if (ret = "", ret := "4", ret := ret + ",4"));
    if (getbit(g1, 5), if (ret = "", ret := "5", ret := ret + ",5"));
    if (getbit(g1, 6), if (ret = "", ret := "6", ret := ret + ",6"));
    if (getbit(g1, 7), if (ret = "", ret := "7", ret := ret + ",7"));
    if (getbit(g2, 0), if (ret = "", ret := "8", ret := ret + ",8"));
    if (getbit(g2, 1), if (ret = "", ret := "9", ret := ret + ",9"));
    if (getbit(g2, 2), if (ret = "", ret := "10", ret := ret + ",10"));
    if (getbit(g2, 3), if (ret = "", ret := "11", ret := ret + ",11"));
    if (getbit(g2, 4), if (ret = "", ret := "12", ret := ret + ",12"));
    if (getbit(g2, 5), if (ret = "", ret := "13", ret := ret + ",13"));
    if (getbit(g2, 6), if (ret = "", ret := "14", ret := ret + ",14"));
    if (getbit(g2, 7), if (ret = "", ret := "15", ret := ret + ",15"));

    if (ret = "", return("None"), return(ret));
else
    return("--");
end
DALI Status
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x90);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if x <= 0xFF
        var s := "";
        if (getbit(x, 0), s := if(s = "", "gear failure", s + ", gear failure"));
        if (getbit(x, 1), s := if(s = "", "lamp failure", s + ", lamp failure"));
        if (getbit(x, 2), s := if(s = "", "lamp on", s + ", lamp on"));
        if (getbit(x, 3), s := if(s = "", "limit error", s + ", limit error"));
        if (getbit(x, 4), s := if(s = "", "fade running", s + ", fade running"));
        if (getbit(x, 5), s := if(s = "", "reset state", s + ", reset state"));
        if (getbit(x, 6), s := if(s = "", "missing short address", s + ", missing short address"));
        if (getbit(x, 7), s := if(s = "", "power cycle", s + ", power cycle"));
        var ign := if((ignGear = 1) and (ignLamp = 1), "gear and lamp failure", if(ignGear = 1, "gear failure", if(ignLamp = 1, "lamp failure", "")));
        return(if(s = "", "OK", s) + " (0x" + tostring(x, "X2") + ")" + if(ign = "", "", "; not raised: " + ign + " reported since start"));
    end
end

return("--")
Fade
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA5);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if x <= 0xFF
        var t := getbits(x, 4, 4);
        var ret := if(t = 0, "off", t + " (" + round(sqrt(power(2, t)) * 5) / 10 + " s)");
        modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA8);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
        var e := modbusr(SH, 511, uint16);
        if (t = 0 and e <= 0xFF and e != 0, ret := "extended 0x" + tostring(e, "X2"));
        return("fade time " + ret + ", fade rate " + getbits(x, 0, 4));
    end
end

return("--")
DALI Version
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x97);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if x <= 0xFF
        return(if(x >= 8, "DALI-2 " + getbits(x, 2, 6) + "." + getbits(x, 0, 2), "DALI-1") + " (" + x + ")");
    end
end

return("--")
Bus statistics
return("since start: queries " + cntQ + ", stale answers read away " + cntStale + ", no answer " + cntNone + ", collisions " + cntColl + ", rejected levels " + cntBad)
Azioni di servizio
${xml_add_to_group}
Parametri: Group ID (0–15 grp)
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x60 + grp);
${xml_remove_from_group}
Parametri: Group ID (0–15 grp)
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x70 + grp);
${xml_reset_to_default_settings}
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x20);
${xml_set_startup_levels}
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x21);
sleep(10);
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x2c);
sleep(10);
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x2d);
Disable fading
modbusw(SH, 541, uint16, 0xA300);
sleep(100);
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x2E);
sleep(100);
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x30);
Gear 26 Dimmer Lettura e scrittura

Dispositivo di controllo DALI all'indirizzo breve 26 — dimmer TapHome mappato su DALI arc power 0–100 % tramite H:510 LAMP LEVEL (scrittura) e QUERY ACTUAL LEVEL tramite H:511 (lettura), delimitato dai propri MIN / MAX LEVEL del gear.

Registro: H:511 → H:510 UInt16 Unità: % numeric
Attributi di servizio
Indirizzo breveIndirizzo breve DALI (0–63) target di questo dispositivo — fissato al momento dell'importazione del template e utilizzato nel byte alto di ogni scrittura Modbus.
Device TypeByte device-type DALI restituito da QUERY DEVICE TYPE (0x99) — riporta DT0 (fluorescente), DT6 (driver LED), DT8 (colore / tunable white) ecc., o -- quando non c'è risposta.
Physical Min LevelLivello minimo di dimmerazione imposto dall'hardware riportato dal gear — letto da QUERY PHYSICAL MIN LEVEL (0x9A), in percentuale.
Max LevelDALI MAX LEVEL configurato — letto da QUERY MAX LEVEL (0xA1); utilizzato come limite superiore durante la scalatura di TapHome 0–100 % su DALI arc power.
Min LevelDALI MIN LEVEL configurato — letto da QUERY MIN LEVEL (0xA2); utilizzato come limite inferiore durante la scalatura di TapHome 0–100 % su DALI arc power.
Power Up LevelLuminosità ripristinata dopo il ripristino dell'alimentazione del bus DALI — letta da QUERY POWER ON LEVEL (0xA3).
System Failure LevelLuminosità adottata quando il bus DALI perde la comunicazione per più di 500 ms — letta da QUERY SYSTEM FAILURE LEVEL (0xA4).
GruppiElenco separato da virgole dei gruppi DALI (0–15) a cui appartiene il gear — decodificato da QUERY GROUPS 0-7 (0xC0) e QUERY GROUPS 8-15 (0xC1); mostra None o ad es. 0,3,7.
Support Lamp FailureSe la lampada / driver supporta il rilevamento dei guasti della lampada — Yes / No / --. Gestisce l'errore Lamp failure! nel readscript periodico.
Support Power FailureSe la lampada / driver supporta il rilevamento dei guasti di alimentazione — Yes / No / --. Gestisce l'errore Power failure! nel readscript periodico.
DALI Version
Bus statistics
Azioni di servizio
Add to GroupAggiunge questo gear a un gruppo DALI (0–15) tramite ADD TO GROUP (0x60+grp) — auto-ripetuto entro 100 ms come richiesto per i comandi di configurazione DALI.
Remove from GroupRimuove questo gear da un gruppo DALI (0–15) tramite REMOVE FROM GROUP (0x70+grp).
Reset to Default SettingsInvia DALI RESET (0x20) — ripristina ogni parametro NVM del gear (livelli max / min / power-on / system-failure, appartenenza al gruppo, scene) al valore predefinito del produttore.
Set Startup LevelsCattura l'arc power corrente e la memorizza come Power On Level e System Failure Level — sequenza STORE ACTUAL LEVEL IN DTR (0x21) → STORE DTR AS POWER ON LEVEL (0x2C) → STORE DTR AS SYSTEM FAILURE LEVEL (0x2D).
Disable fading

Gear 26

Lettura (modulo)
var x := 0; var rx := 0; var y := 0;
if Status > 0
    Status := Status - 1;
    adderror(3, "Gear not responding!");
    return(0);
end

# checkStatus: ReadLevel resets it while the gear answers; statusPoll: QUERY STATUS at least once per 60 runs
checkStatus := checkStatus - 1;
statusPoll := statusPoll - 1;
if checkStatus < 1 or statusPoll < 1
    # an unread answer left in the gateway would be taken for this query: read it away and count it
    x := modbusr(SH, 511, uint16); if (x != 0x8000, cntStale := cntStale + 1);
    modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x90);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    x := modbusr(SH, 511, uint16);
    cntQ := cntQ + 1; if (x = 0x8000, cntNone := cntNone + 1); if (x = 0x20FF, cntColl := cntColl + 1);
    # a single lost answer happens on DALI: ask once more before declaring the gear missing
    if x = 0x8000
        x := modbusr(SH, 511, uint16); if (x != 0x8000, cntStale := cntStale + 1);
        modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x90);
        sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
        x := modbusr(SH, 511, uint16);
        cntQ := cntQ + 1; if (x = 0x8000, cntNone := cntNone + 1); if (x = 0x20FF, cntColl := cntColl + 1);
    end
    if x <= 0xFF
        # a changed failure bit must be read twice the same before it is taken
        if statusSeen = 1 and getbits(x, 0, 2) != getbits(gearStatus, 0, 2)
            y := modbusr(SH, 511, uint16); if (y != 0x8000, cntStale := cntStale + 1);
            modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x90);
            sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
            y := modbusr(SH, 511, uint16);
            cntQ := cntQ + 1; if (y = 0x8000, cntNone := cntNone + 1); if (y = 0x20FF, cntColl := cntColl + 1);
            if y != x
                cntBad := cntBad + 1;
                x := gearStatus;
            end
        end
        if statusSeen = 0
            ignGear := getbit(x, 0);
            ignLamp := getbit(x, 1);
            statusSeen := 1;
        end
        # a bit that clears ends its ignore, so a later failure is raised
        if (getbit(x, 0) = 0, ignGear := 0);
        if (getbit(x, 1) = 0, ignLamp := 0);
        gearStatus := x;
        checkStatus := 60;
        statusPoll := 60;
    else
        if x = 0x8000
            Status := RANDINT(10, 60);
            adderror(3, "Gear not responding!");
            return(0);
        end
    end
end

# messages last one run only, so they are raised from the stored status on every run
if ((getbit(gearStatus, 0) = 1) and (ignGear = 0), adderror(1, "Control gear failure!"));
if ((getbit(gearStatus, 1) = 1) and (ignLamp = 0), adderror(2, "Lamp failure!"));
Inizializzazione
var x := 0; var rx := 0;
# QUERY STATUS 0x90: every reply byte proves the gear is present; 0x8000 = no answer, 0x20FF = bus collision
# an unread answer left in the gateway would be taken for this query: read it away and count it
x := modbusr(SH, 511, uint16); if (x != 0x8000, cntStale := cntStale + 1);
modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x90);
sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
x := modbusr(SH, 511, uint16);
cntQ := cntQ + 1; if (x = 0x8000, cntNone := cntNone + 1); if (x = 0x20FF, cntColl := cntColl + 1);
statusSeen := 0;
if x <= 0xFF
    # failure bits a gear reports from its first answer are its permanent state, not an event: shown, not raised
    gearStatus := x;
    ignGear := getbit(x, 0);
    ignLamp := getbit(x, 1);
    statusSeen := 1;
    Status := 0;
else
    Status := RANDINT(1, 60);
end

if Status = 0
    x := modbusr(SH, 511, uint16); if (x != 0x8000, cntStale := cntStale + 1);
    modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA2);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    x := modbusr(SH, 511, uint16);
    cntQ := cntQ + 1; if (x = 0x8000, cntNone := cntNone + 1); if (x = 0x20FF, cntColl := cntColl + 1);
    if (x <= 0xFE, minLevel := x);

    x := modbusr(SH, 511, uint16); if (x != 0x8000, cntStale := cntStale + 1);
    modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA1);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    x := modbusr(SH, 511, uint16);
    cntQ := cntQ + 1; if (x = 0x8000, cntNone := cntNone + 1); if (x = 0x20FF, cntColl := cntColl + 1);
    if (x <= 0xFE, maxLevel := x);
end
Lettura livello
var x := 0; var rx := 0; var y := 0;
if Status = 0
    if minLevel = 0
        # an unread answer left in the gateway would be taken for this query: read it away and count it
        x := modbusr(SH, 511, uint16); if (x != 0x8000, cntStale := cntStale + 1);
        modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA2);
        sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
        x := modbusr(SH, 511, uint16);
        cntQ := cntQ + 1; if (x = 0x8000, cntNone := cntNone + 1); if (x = 0x20FF, cntColl := cntColl + 1);
        if (x <= 0xFE, minLevel := x);
    end
    x := modbusr(SH, 511, uint16); if (x != 0x8000, cntStale := cntStale + 1);
    modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA0);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    x := modbusr(SH, 511, uint16);
    cntQ := cntQ + 1; if (x = 0x8000, cntNone := cntNone + 1); if (x = 0x20FF, cntColl := cntColl + 1);
    if (x != 0x8000 or rx, checkStatus := 60);
    # 0xFF = MASK, 0x20FF = collision, 0x8000 = no answer: keep the last level instead of a phantom value
    if x > 0xFE
        return(Le);
    end
    # an actual level is 0 or between the gear's min and max: anything else is not this gear's answer
    if x > 0 and x < minLevel
        cntBad := cntBad + 1;
        return(Le);
    end
    # a changed level must be read twice the same before it is taken
    if x != lastRaw
        y := modbusr(SH, 511, uint16); if (y != 0x8000, cntStale := cntStale + 1);
        modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA0);
        sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
        y := modbusr(SH, 511, uint16);
        cntQ := cntQ + 1; if (y = 0x8000, cntNone := cntNone + 1); if (y = 0x20FF, cntColl := cntColl + 1);
        if y != x
            cntBad := cntBad + 1;
            return(Le);
        end
        lastRaw := x;
    end
    return(if(x = 0, 0, linear(x, minLevel, 0.01, maxLevel, 1)));
else
    return(NaN);
end
Scrittura livello
var level := 0;
if(Le > 0, level := round(linear(Le, 0.01, minLevel, 1, maxLevel)));
modbusw(SH, 510, uint16, (ShortAddress << 8) + level );
Attributi di servizio
${xml_short_address}
ShortAddress
${xml_device_type}
var x := 0; var y := 0; var rx := 0; var s := ""; var i := 0;
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x99);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    x := modbusr(SH, 511, uint16);
    if (x < 0xFF, return("DT" + x));
    if x = 0xFF
        while i < 8
            modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA7);
            sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
            y := modbusr(SH, 511, uint16);
            if y < 0xFE
                s := if(s = "", "DT" + y, s + ", DT" + y);
                i := i + 1;
            else
                i := 8;
            end
        loop
        return(if(s = "", "MASK", s));
    end
end

return("--")
Physical Min Level
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x9A);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if (x <= 0xFE, return(round((x / 0xFE) * 100) + " %"));
end

return("--")
Max Level
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA1);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if (x <= 0xFE, return(round((x / 0xFE) * 100) + " %"));
end

return("--")
Min Level
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA2);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if (x <= 0xFE, return(round((x / 0xFE) * 100) + " %"));
end

return("--")
Power Up Level
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA3);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if (x <= 0xFE, return(round((x / 0xFE) * 100) + " %"));
end

return("--")
System Failure Level
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA4);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if (x <= 0xFE, return(round((x / 0xFE) * 100) + " %"));
end

return("--")
${xml_groups}
var x := 0; var rx := 0;
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xC0);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var g1 := modbusr(SH, 511, uint16);
    if (g1 > 0xFF, return("--")); 

    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xC1);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var g2 := modbusr(SH, 511, uint16);
    if (g2 > 0xFF, return("--")); 

    var ret := "";

    if (getbit(g1, 0), ret := ret + "0");
    if (getbit(g1, 1), if (ret = "", ret := "1", ret := ret + ",1"));
    if (getbit(g1, 2), if (ret = "", ret := "2", ret := ret + ",2"));
    if (getbit(g1, 3), if (ret = "", ret := "3", ret := ret + ",3"));
    if (getbit(g1, 4), if (ret = "", ret := "4", ret := ret + ",4"));
    if (getbit(g1, 5), if (ret = "", ret := "5", ret := ret + ",5"));
    if (getbit(g1, 6), if (ret = "", ret := "6", ret := ret + ",6"));
    if (getbit(g1, 7), if (ret = "", ret := "7", ret := ret + ",7"));
    if (getbit(g2, 0), if (ret = "", ret := "8", ret := ret + ",8"));
    if (getbit(g2, 1), if (ret = "", ret := "9", ret := ret + ",9"));
    if (getbit(g2, 2), if (ret = "", ret := "10", ret := ret + ",10"));
    if (getbit(g2, 3), if (ret = "", ret := "11", ret := ret + ",11"));
    if (getbit(g2, 4), if (ret = "", ret := "12", ret := ret + ",12"));
    if (getbit(g2, 5), if (ret = "", ret := "13", ret := ret + ",13"));
    if (getbit(g2, 6), if (ret = "", ret := "14", ret := ret + ",14"));
    if (getbit(g2, 7), if (ret = "", ret := "15", ret := ret + ",15"));

    if (ret = "", return("None"), return(ret));
else
    return("--");
end
DALI Status
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x90);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if x <= 0xFF
        var s := "";
        if (getbit(x, 0), s := if(s = "", "gear failure", s + ", gear failure"));
        if (getbit(x, 1), s := if(s = "", "lamp failure", s + ", lamp failure"));
        if (getbit(x, 2), s := if(s = "", "lamp on", s + ", lamp on"));
        if (getbit(x, 3), s := if(s = "", "limit error", s + ", limit error"));
        if (getbit(x, 4), s := if(s = "", "fade running", s + ", fade running"));
        if (getbit(x, 5), s := if(s = "", "reset state", s + ", reset state"));
        if (getbit(x, 6), s := if(s = "", "missing short address", s + ", missing short address"));
        if (getbit(x, 7), s := if(s = "", "power cycle", s + ", power cycle"));
        var ign := if((ignGear = 1) and (ignLamp = 1), "gear and lamp failure", if(ignGear = 1, "gear failure", if(ignLamp = 1, "lamp failure", "")));
        return(if(s = "", "OK", s) + " (0x" + tostring(x, "X2") + ")" + if(ign = "", "", "; not raised: " + ign + " reported since start"));
    end
end

return("--")
Fade
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA5);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if x <= 0xFF
        var t := getbits(x, 4, 4);
        var ret := if(t = 0, "off", t + " (" + round(sqrt(power(2, t)) * 5) / 10 + " s)");
        modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA8);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
        var e := modbusr(SH, 511, uint16);
        if (t = 0 and e <= 0xFF and e != 0, ret := "extended 0x" + tostring(e, "X2"));
        return("fade time " + ret + ", fade rate " + getbits(x, 0, 4));
    end
end

return("--")
DALI Version
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x97);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if x <= 0xFF
        return(if(x >= 8, "DALI-2 " + getbits(x, 2, 6) + "." + getbits(x, 0, 2), "DALI-1") + " (" + x + ")");
    end
end

return("--")
Bus statistics
return("since start: queries " + cntQ + ", stale answers read away " + cntStale + ", no answer " + cntNone + ", collisions " + cntColl + ", rejected levels " + cntBad)
Azioni di servizio
${xml_add_to_group}
Parametri: Group ID (0–15 grp)
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x60 + grp);
${xml_remove_from_group}
Parametri: Group ID (0–15 grp)
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x70 + grp);
${xml_reset_to_default_settings}
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x20);
${xml_set_startup_levels}
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x21);
sleep(10);
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x2c);
sleep(10);
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x2d);
Disable fading
modbusw(SH, 541, uint16, 0xA300);
sleep(100);
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x2E);
sleep(100);
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x30);
Gear 27 Dimmer Lettura e scrittura

Dispositivo di controllo DALI all'indirizzo breve 27 — dimmer TapHome mappato su DALI arc power 0–100 % tramite H:510 LAMP LEVEL (scrittura) e QUERY ACTUAL LEVEL tramite H:511 (lettura), delimitato dai propri MIN / MAX LEVEL del gear.

Registro: H:511 → H:510 UInt16 Unità: % numeric
Attributi di servizio
Indirizzo breveIndirizzo breve DALI (0–63) target di questo dispositivo — fissato al momento dell'importazione del template e utilizzato nel byte alto di ogni scrittura Modbus.
Device TypeByte device-type DALI restituito da QUERY DEVICE TYPE (0x99) — riporta DT0 (fluorescente), DT6 (driver LED), DT8 (colore / tunable white) ecc., o -- quando non c'è risposta.
Physical Min LevelLivello minimo di dimmerazione imposto dall'hardware riportato dal gear — letto da QUERY PHYSICAL MIN LEVEL (0x9A), in percentuale.
Max LevelDALI MAX LEVEL configurato — letto da QUERY MAX LEVEL (0xA1); utilizzato come limite superiore durante la scalatura di TapHome 0–100 % su DALI arc power.
Min LevelDALI MIN LEVEL configurato — letto da QUERY MIN LEVEL (0xA2); utilizzato come limite inferiore durante la scalatura di TapHome 0–100 % su DALI arc power.
Power Up LevelLuminosità ripristinata dopo il ripristino dell'alimentazione del bus DALI — letta da QUERY POWER ON LEVEL (0xA3).
System Failure LevelLuminosità adottata quando il bus DALI perde la comunicazione per più di 500 ms — letta da QUERY SYSTEM FAILURE LEVEL (0xA4).
GruppiElenco separato da virgole dei gruppi DALI (0–15) a cui appartiene il gear — decodificato da QUERY GROUPS 0-7 (0xC0) e QUERY GROUPS 8-15 (0xC1); mostra None o ad es. 0,3,7.
Support Lamp FailureSe la lampada / driver supporta il rilevamento dei guasti della lampada — Yes / No / --. Gestisce l'errore Lamp failure! nel readscript periodico.
Support Power FailureSe la lampada / driver supporta il rilevamento dei guasti di alimentazione — Yes / No / --. Gestisce l'errore Power failure! nel readscript periodico.
DALI Version
Bus statistics
Azioni di servizio
Add to GroupAggiunge questo gear a un gruppo DALI (0–15) tramite ADD TO GROUP (0x60+grp) — auto-ripetuto entro 100 ms come richiesto per i comandi di configurazione DALI.
Remove from GroupRimuove questo gear da un gruppo DALI (0–15) tramite REMOVE FROM GROUP (0x70+grp).
Reset to Default SettingsInvia DALI RESET (0x20) — ripristina ogni parametro NVM del gear (livelli max / min / power-on / system-failure, appartenenza al gruppo, scene) al valore predefinito del produttore.
Set Startup LevelsCattura l'arc power corrente e la memorizza come Power On Level e System Failure Level — sequenza STORE ACTUAL LEVEL IN DTR (0x21) → STORE DTR AS POWER ON LEVEL (0x2C) → STORE DTR AS SYSTEM FAILURE LEVEL (0x2D).
Disable fading

Gear 27

Lettura (modulo)
var x := 0; var rx := 0; var y := 0;
if Status > 0
    Status := Status - 1;
    adderror(3, "Gear not responding!");
    return(0);
end

# checkStatus: ReadLevel resets it while the gear answers; statusPoll: QUERY STATUS at least once per 60 runs
checkStatus := checkStatus - 1;
statusPoll := statusPoll - 1;
if checkStatus < 1 or statusPoll < 1
    # an unread answer left in the gateway would be taken for this query: read it away and count it
    x := modbusr(SH, 511, uint16); if (x != 0x8000, cntStale := cntStale + 1);
    modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x90);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    x := modbusr(SH, 511, uint16);
    cntQ := cntQ + 1; if (x = 0x8000, cntNone := cntNone + 1); if (x = 0x20FF, cntColl := cntColl + 1);
    # a single lost answer happens on DALI: ask once more before declaring the gear missing
    if x = 0x8000
        x := modbusr(SH, 511, uint16); if (x != 0x8000, cntStale := cntStale + 1);
        modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x90);
        sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
        x := modbusr(SH, 511, uint16);
        cntQ := cntQ + 1; if (x = 0x8000, cntNone := cntNone + 1); if (x = 0x20FF, cntColl := cntColl + 1);
    end
    if x <= 0xFF
        # a changed failure bit must be read twice the same before it is taken
        if statusSeen = 1 and getbits(x, 0, 2) != getbits(gearStatus, 0, 2)
            y := modbusr(SH, 511, uint16); if (y != 0x8000, cntStale := cntStale + 1);
            modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x90);
            sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
            y := modbusr(SH, 511, uint16);
            cntQ := cntQ + 1; if (y = 0x8000, cntNone := cntNone + 1); if (y = 0x20FF, cntColl := cntColl + 1);
            if y != x
                cntBad := cntBad + 1;
                x := gearStatus;
            end
        end
        if statusSeen = 0
            ignGear := getbit(x, 0);
            ignLamp := getbit(x, 1);
            statusSeen := 1;
        end
        # a bit that clears ends its ignore, so a later failure is raised
        if (getbit(x, 0) = 0, ignGear := 0);
        if (getbit(x, 1) = 0, ignLamp := 0);
        gearStatus := x;
        checkStatus := 60;
        statusPoll := 60;
    else
        if x = 0x8000
            Status := RANDINT(10, 60);
            adderror(3, "Gear not responding!");
            return(0);
        end
    end
end

# messages last one run only, so they are raised from the stored status on every run
if ((getbit(gearStatus, 0) = 1) and (ignGear = 0), adderror(1, "Control gear failure!"));
if ((getbit(gearStatus, 1) = 1) and (ignLamp = 0), adderror(2, "Lamp failure!"));
Inizializzazione
var x := 0; var rx := 0;
# QUERY STATUS 0x90: every reply byte proves the gear is present; 0x8000 = no answer, 0x20FF = bus collision
# an unread answer left in the gateway would be taken for this query: read it away and count it
x := modbusr(SH, 511, uint16); if (x != 0x8000, cntStale := cntStale + 1);
modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x90);
sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
x := modbusr(SH, 511, uint16);
cntQ := cntQ + 1; if (x = 0x8000, cntNone := cntNone + 1); if (x = 0x20FF, cntColl := cntColl + 1);
statusSeen := 0;
if x <= 0xFF
    # failure bits a gear reports from its first answer are its permanent state, not an event: shown, not raised
    gearStatus := x;
    ignGear := getbit(x, 0);
    ignLamp := getbit(x, 1);
    statusSeen := 1;
    Status := 0;
else
    Status := RANDINT(1, 60);
end

if Status = 0
    x := modbusr(SH, 511, uint16); if (x != 0x8000, cntStale := cntStale + 1);
    modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA2);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    x := modbusr(SH, 511, uint16);
    cntQ := cntQ + 1; if (x = 0x8000, cntNone := cntNone + 1); if (x = 0x20FF, cntColl := cntColl + 1);
    if (x <= 0xFE, minLevel := x);

    x := modbusr(SH, 511, uint16); if (x != 0x8000, cntStale := cntStale + 1);
    modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA1);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    x := modbusr(SH, 511, uint16);
    cntQ := cntQ + 1; if (x = 0x8000, cntNone := cntNone + 1); if (x = 0x20FF, cntColl := cntColl + 1);
    if (x <= 0xFE, maxLevel := x);
end
Lettura livello
var x := 0; var rx := 0; var y := 0;
if Status = 0
    if minLevel = 0
        # an unread answer left in the gateway would be taken for this query: read it away and count it
        x := modbusr(SH, 511, uint16); if (x != 0x8000, cntStale := cntStale + 1);
        modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA2);
        sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
        x := modbusr(SH, 511, uint16);
        cntQ := cntQ + 1; if (x = 0x8000, cntNone := cntNone + 1); if (x = 0x20FF, cntColl := cntColl + 1);
        if (x <= 0xFE, minLevel := x);
    end
    x := modbusr(SH, 511, uint16); if (x != 0x8000, cntStale := cntStale + 1);
    modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA0);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    x := modbusr(SH, 511, uint16);
    cntQ := cntQ + 1; if (x = 0x8000, cntNone := cntNone + 1); if (x = 0x20FF, cntColl := cntColl + 1);
    if (x != 0x8000 or rx, checkStatus := 60);
    # 0xFF = MASK, 0x20FF = collision, 0x8000 = no answer: keep the last level instead of a phantom value
    if x > 0xFE
        return(Le);
    end
    # an actual level is 0 or between the gear's min and max: anything else is not this gear's answer
    if x > 0 and x < minLevel
        cntBad := cntBad + 1;
        return(Le);
    end
    # a changed level must be read twice the same before it is taken
    if x != lastRaw
        y := modbusr(SH, 511, uint16); if (y != 0x8000, cntStale := cntStale + 1);
        modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA0);
        sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
        y := modbusr(SH, 511, uint16);
        cntQ := cntQ + 1; if (y = 0x8000, cntNone := cntNone + 1); if (y = 0x20FF, cntColl := cntColl + 1);
        if y != x
            cntBad := cntBad + 1;
            return(Le);
        end
        lastRaw := x;
    end
    return(if(x = 0, 0, linear(x, minLevel, 0.01, maxLevel, 1)));
else
    return(NaN);
end
Scrittura livello
var level := 0;
if(Le > 0, level := round(linear(Le, 0.01, minLevel, 1, maxLevel)));
modbusw(SH, 510, uint16, (ShortAddress << 8) + level );
Attributi di servizio
${xml_short_address}
ShortAddress
${xml_device_type}
var x := 0; var y := 0; var rx := 0; var s := ""; var i := 0;
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x99);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    x := modbusr(SH, 511, uint16);
    if (x < 0xFF, return("DT" + x));
    if x = 0xFF
        while i < 8
            modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA7);
            sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
            y := modbusr(SH, 511, uint16);
            if y < 0xFE
                s := if(s = "", "DT" + y, s + ", DT" + y);
                i := i + 1;
            else
                i := 8;
            end
        loop
        return(if(s = "", "MASK", s));
    end
end

return("--")
Physical Min Level
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x9A);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if (x <= 0xFE, return(round((x / 0xFE) * 100) + " %"));
end

return("--")
Max Level
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA1);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if (x <= 0xFE, return(round((x / 0xFE) * 100) + " %"));
end

return("--")
Min Level
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA2);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if (x <= 0xFE, return(round((x / 0xFE) * 100) + " %"));
end

return("--")
Power Up Level
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA3);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if (x <= 0xFE, return(round((x / 0xFE) * 100) + " %"));
end

return("--")
System Failure Level
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA4);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if (x <= 0xFE, return(round((x / 0xFE) * 100) + " %"));
end

return("--")
${xml_groups}
var x := 0; var rx := 0;
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xC0);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var g1 := modbusr(SH, 511, uint16);
    if (g1 > 0xFF, return("--")); 

    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xC1);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var g2 := modbusr(SH, 511, uint16);
    if (g2 > 0xFF, return("--")); 

    var ret := "";

    if (getbit(g1, 0), ret := ret + "0");
    if (getbit(g1, 1), if (ret = "", ret := "1", ret := ret + ",1"));
    if (getbit(g1, 2), if (ret = "", ret := "2", ret := ret + ",2"));
    if (getbit(g1, 3), if (ret = "", ret := "3", ret := ret + ",3"));
    if (getbit(g1, 4), if (ret = "", ret := "4", ret := ret + ",4"));
    if (getbit(g1, 5), if (ret = "", ret := "5", ret := ret + ",5"));
    if (getbit(g1, 6), if (ret = "", ret := "6", ret := ret + ",6"));
    if (getbit(g1, 7), if (ret = "", ret := "7", ret := ret + ",7"));
    if (getbit(g2, 0), if (ret = "", ret := "8", ret := ret + ",8"));
    if (getbit(g2, 1), if (ret = "", ret := "9", ret := ret + ",9"));
    if (getbit(g2, 2), if (ret = "", ret := "10", ret := ret + ",10"));
    if (getbit(g2, 3), if (ret = "", ret := "11", ret := ret + ",11"));
    if (getbit(g2, 4), if (ret = "", ret := "12", ret := ret + ",12"));
    if (getbit(g2, 5), if (ret = "", ret := "13", ret := ret + ",13"));
    if (getbit(g2, 6), if (ret = "", ret := "14", ret := ret + ",14"));
    if (getbit(g2, 7), if (ret = "", ret := "15", ret := ret + ",15"));

    if (ret = "", return("None"), return(ret));
else
    return("--");
end
DALI Status
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x90);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if x <= 0xFF
        var s := "";
        if (getbit(x, 0), s := if(s = "", "gear failure", s + ", gear failure"));
        if (getbit(x, 1), s := if(s = "", "lamp failure", s + ", lamp failure"));
        if (getbit(x, 2), s := if(s = "", "lamp on", s + ", lamp on"));
        if (getbit(x, 3), s := if(s = "", "limit error", s + ", limit error"));
        if (getbit(x, 4), s := if(s = "", "fade running", s + ", fade running"));
        if (getbit(x, 5), s := if(s = "", "reset state", s + ", reset state"));
        if (getbit(x, 6), s := if(s = "", "missing short address", s + ", missing short address"));
        if (getbit(x, 7), s := if(s = "", "power cycle", s + ", power cycle"));
        var ign := if((ignGear = 1) and (ignLamp = 1), "gear and lamp failure", if(ignGear = 1, "gear failure", if(ignLamp = 1, "lamp failure", "")));
        return(if(s = "", "OK", s) + " (0x" + tostring(x, "X2") + ")" + if(ign = "", "", "; not raised: " + ign + " reported since start"));
    end
end

return("--")
Fade
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA5);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if x <= 0xFF
        var t := getbits(x, 4, 4);
        var ret := if(t = 0, "off", t + " (" + round(sqrt(power(2, t)) * 5) / 10 + " s)");
        modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA8);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
        var e := modbusr(SH, 511, uint16);
        if (t = 0 and e <= 0xFF and e != 0, ret := "extended 0x" + tostring(e, "X2"));
        return("fade time " + ret + ", fade rate " + getbits(x, 0, 4));
    end
end

return("--")
DALI Version
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x97);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if x <= 0xFF
        return(if(x >= 8, "DALI-2 " + getbits(x, 2, 6) + "." + getbits(x, 0, 2), "DALI-1") + " (" + x + ")");
    end
end

return("--")
Bus statistics
return("since start: queries " + cntQ + ", stale answers read away " + cntStale + ", no answer " + cntNone + ", collisions " + cntColl + ", rejected levels " + cntBad)
Azioni di servizio
${xml_add_to_group}
Parametri: Group ID (0–15 grp)
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x60 + grp);
${xml_remove_from_group}
Parametri: Group ID (0–15 grp)
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x70 + grp);
${xml_reset_to_default_settings}
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x20);
${xml_set_startup_levels}
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x21);
sleep(10);
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x2c);
sleep(10);
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x2d);
Disable fading
modbusw(SH, 541, uint16, 0xA300);
sleep(100);
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x2E);
sleep(100);
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x30);
Gear 28 Dimmer Lettura e scrittura

Dispositivo di controllo DALI all'indirizzo breve 28 — dimmer TapHome mappato su DALI arc power 0–100 % tramite H:510 LAMP LEVEL (scrittura) e QUERY ACTUAL LEVEL tramite H:511 (lettura), delimitato dai propri MIN / MAX LEVEL del gear.

Registro: H:511 → H:510 UInt16 Unità: % numeric
Attributi di servizio
Indirizzo breveIndirizzo breve DALI (0–63) target di questo dispositivo — fissato al momento dell'importazione del template e utilizzato nel byte alto di ogni scrittura Modbus.
Device TypeByte device-type DALI restituito da QUERY DEVICE TYPE (0x99) — riporta DT0 (fluorescente), DT6 (driver LED), DT8 (colore / tunable white) ecc., o -- quando non c'è risposta.
Physical Min LevelLivello minimo di dimmerazione imposto dall'hardware riportato dal gear — letto da QUERY PHYSICAL MIN LEVEL (0x9A), in percentuale.
Max LevelDALI MAX LEVEL configurato — letto da QUERY MAX LEVEL (0xA1); utilizzato come limite superiore durante la scalatura di TapHome 0–100 % su DALI arc power.
Min LevelDALI MIN LEVEL configurato — letto da QUERY MIN LEVEL (0xA2); utilizzato come limite inferiore durante la scalatura di TapHome 0–100 % su DALI arc power.
Power Up LevelLuminosità ripristinata dopo il ripristino dell'alimentazione del bus DALI — letta da QUERY POWER ON LEVEL (0xA3).
System Failure LevelLuminosità adottata quando il bus DALI perde la comunicazione per più di 500 ms — letta da QUERY SYSTEM FAILURE LEVEL (0xA4).
GruppiElenco separato da virgole dei gruppi DALI (0–15) a cui appartiene il gear — decodificato da QUERY GROUPS 0-7 (0xC0) e QUERY GROUPS 8-15 (0xC1); mostra None o ad es. 0,3,7.
Support Lamp FailureSe la lampada / driver supporta il rilevamento dei guasti della lampada — Yes / No / --. Gestisce l'errore Lamp failure! nel readscript periodico.
Support Power FailureSe la lampada / driver supporta il rilevamento dei guasti di alimentazione — Yes / No / --. Gestisce l'errore Power failure! nel readscript periodico.
DALI Version
Bus statistics
Azioni di servizio
Add to GroupAggiunge questo gear a un gruppo DALI (0–15) tramite ADD TO GROUP (0x60+grp) — auto-ripetuto entro 100 ms come richiesto per i comandi di configurazione DALI.
Remove from GroupRimuove questo gear da un gruppo DALI (0–15) tramite REMOVE FROM GROUP (0x70+grp).
Reset to Default SettingsInvia DALI RESET (0x20) — ripristina ogni parametro NVM del gear (livelli max / min / power-on / system-failure, appartenenza al gruppo, scene) al valore predefinito del produttore.
Set Startup LevelsCattura l'arc power corrente e la memorizza come Power On Level e System Failure Level — sequenza STORE ACTUAL LEVEL IN DTR (0x21) → STORE DTR AS POWER ON LEVEL (0x2C) → STORE DTR AS SYSTEM FAILURE LEVEL (0x2D).
Disable fading

Gear 28

Lettura (modulo)
var x := 0; var rx := 0; var y := 0;
if Status > 0
    Status := Status - 1;
    adderror(3, "Gear not responding!");
    return(0);
end

# checkStatus: ReadLevel resets it while the gear answers; statusPoll: QUERY STATUS at least once per 60 runs
checkStatus := checkStatus - 1;
statusPoll := statusPoll - 1;
if checkStatus < 1 or statusPoll < 1
    # an unread answer left in the gateway would be taken for this query: read it away and count it
    x := modbusr(SH, 511, uint16); if (x != 0x8000, cntStale := cntStale + 1);
    modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x90);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    x := modbusr(SH, 511, uint16);
    cntQ := cntQ + 1; if (x = 0x8000, cntNone := cntNone + 1); if (x = 0x20FF, cntColl := cntColl + 1);
    # a single lost answer happens on DALI: ask once more before declaring the gear missing
    if x = 0x8000
        x := modbusr(SH, 511, uint16); if (x != 0x8000, cntStale := cntStale + 1);
        modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x90);
        sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
        x := modbusr(SH, 511, uint16);
        cntQ := cntQ + 1; if (x = 0x8000, cntNone := cntNone + 1); if (x = 0x20FF, cntColl := cntColl + 1);
    end
    if x <= 0xFF
        # a changed failure bit must be read twice the same before it is taken
        if statusSeen = 1 and getbits(x, 0, 2) != getbits(gearStatus, 0, 2)
            y := modbusr(SH, 511, uint16); if (y != 0x8000, cntStale := cntStale + 1);
            modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x90);
            sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
            y := modbusr(SH, 511, uint16);
            cntQ := cntQ + 1; if (y = 0x8000, cntNone := cntNone + 1); if (y = 0x20FF, cntColl := cntColl + 1);
            if y != x
                cntBad := cntBad + 1;
                x := gearStatus;
            end
        end
        if statusSeen = 0
            ignGear := getbit(x, 0);
            ignLamp := getbit(x, 1);
            statusSeen := 1;
        end
        # a bit that clears ends its ignore, so a later failure is raised
        if (getbit(x, 0) = 0, ignGear := 0);
        if (getbit(x, 1) = 0, ignLamp := 0);
        gearStatus := x;
        checkStatus := 60;
        statusPoll := 60;
    else
        if x = 0x8000
            Status := RANDINT(10, 60);
            adderror(3, "Gear not responding!");
            return(0);
        end
    end
end

# messages last one run only, so they are raised from the stored status on every run
if ((getbit(gearStatus, 0) = 1) and (ignGear = 0), adderror(1, "Control gear failure!"));
if ((getbit(gearStatus, 1) = 1) and (ignLamp = 0), adderror(2, "Lamp failure!"));
Inizializzazione
var x := 0; var rx := 0;
# QUERY STATUS 0x90: every reply byte proves the gear is present; 0x8000 = no answer, 0x20FF = bus collision
# an unread answer left in the gateway would be taken for this query: read it away and count it
x := modbusr(SH, 511, uint16); if (x != 0x8000, cntStale := cntStale + 1);
modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x90);
sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
x := modbusr(SH, 511, uint16);
cntQ := cntQ + 1; if (x = 0x8000, cntNone := cntNone + 1); if (x = 0x20FF, cntColl := cntColl + 1);
statusSeen := 0;
if x <= 0xFF
    # failure bits a gear reports from its first answer are its permanent state, not an event: shown, not raised
    gearStatus := x;
    ignGear := getbit(x, 0);
    ignLamp := getbit(x, 1);
    statusSeen := 1;
    Status := 0;
else
    Status := RANDINT(1, 60);
end

if Status = 0
    x := modbusr(SH, 511, uint16); if (x != 0x8000, cntStale := cntStale + 1);
    modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA2);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    x := modbusr(SH, 511, uint16);
    cntQ := cntQ + 1; if (x = 0x8000, cntNone := cntNone + 1); if (x = 0x20FF, cntColl := cntColl + 1);
    if (x <= 0xFE, minLevel := x);

    x := modbusr(SH, 511, uint16); if (x != 0x8000, cntStale := cntStale + 1);
    modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA1);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    x := modbusr(SH, 511, uint16);
    cntQ := cntQ + 1; if (x = 0x8000, cntNone := cntNone + 1); if (x = 0x20FF, cntColl := cntColl + 1);
    if (x <= 0xFE, maxLevel := x);
end
Lettura livello
var x := 0; var rx := 0; var y := 0;
if Status = 0
    if minLevel = 0
        # an unread answer left in the gateway would be taken for this query: read it away and count it
        x := modbusr(SH, 511, uint16); if (x != 0x8000, cntStale := cntStale + 1);
        modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA2);
        sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
        x := modbusr(SH, 511, uint16);
        cntQ := cntQ + 1; if (x = 0x8000, cntNone := cntNone + 1); if (x = 0x20FF, cntColl := cntColl + 1);
        if (x <= 0xFE, minLevel := x);
    end
    x := modbusr(SH, 511, uint16); if (x != 0x8000, cntStale := cntStale + 1);
    modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA0);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    x := modbusr(SH, 511, uint16);
    cntQ := cntQ + 1; if (x = 0x8000, cntNone := cntNone + 1); if (x = 0x20FF, cntColl := cntColl + 1);
    if (x != 0x8000 or rx, checkStatus := 60);
    # 0xFF = MASK, 0x20FF = collision, 0x8000 = no answer: keep the last level instead of a phantom value
    if x > 0xFE
        return(Le);
    end
    # an actual level is 0 or between the gear's min and max: anything else is not this gear's answer
    if x > 0 and x < minLevel
        cntBad := cntBad + 1;
        return(Le);
    end
    # a changed level must be read twice the same before it is taken
    if x != lastRaw
        y := modbusr(SH, 511, uint16); if (y != 0x8000, cntStale := cntStale + 1);
        modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA0);
        sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
        y := modbusr(SH, 511, uint16);
        cntQ := cntQ + 1; if (y = 0x8000, cntNone := cntNone + 1); if (y = 0x20FF, cntColl := cntColl + 1);
        if y != x
            cntBad := cntBad + 1;
            return(Le);
        end
        lastRaw := x;
    end
    return(if(x = 0, 0, linear(x, minLevel, 0.01, maxLevel, 1)));
else
    return(NaN);
end
Scrittura livello
var level := 0;
if(Le > 0, level := round(linear(Le, 0.01, minLevel, 1, maxLevel)));
modbusw(SH, 510, uint16, (ShortAddress << 8) + level );
Attributi di servizio
${xml_short_address}
ShortAddress
${xml_device_type}
var x := 0; var y := 0; var rx := 0; var s := ""; var i := 0;
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x99);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    x := modbusr(SH, 511, uint16);
    if (x < 0xFF, return("DT" + x));
    if x = 0xFF
        while i < 8
            modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA7);
            sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
            y := modbusr(SH, 511, uint16);
            if y < 0xFE
                s := if(s = "", "DT" + y, s + ", DT" + y);
                i := i + 1;
            else
                i := 8;
            end
        loop
        return(if(s = "", "MASK", s));
    end
end

return("--")
Physical Min Level
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x9A);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if (x <= 0xFE, return(round((x / 0xFE) * 100) + " %"));
end

return("--")
Max Level
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA1);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if (x <= 0xFE, return(round((x / 0xFE) * 100) + " %"));
end

return("--")
Min Level
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA2);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if (x <= 0xFE, return(round((x / 0xFE) * 100) + " %"));
end

return("--")
Power Up Level
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA3);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if (x <= 0xFE, return(round((x / 0xFE) * 100) + " %"));
end

return("--")
System Failure Level
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA4);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if (x <= 0xFE, return(round((x / 0xFE) * 100) + " %"));
end

return("--")
${xml_groups}
var x := 0; var rx := 0;
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xC0);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var g1 := modbusr(SH, 511, uint16);
    if (g1 > 0xFF, return("--")); 

    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xC1);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var g2 := modbusr(SH, 511, uint16);
    if (g2 > 0xFF, return("--")); 

    var ret := "";

    if (getbit(g1, 0), ret := ret + "0");
    if (getbit(g1, 1), if (ret = "", ret := "1", ret := ret + ",1"));
    if (getbit(g1, 2), if (ret = "", ret := "2", ret := ret + ",2"));
    if (getbit(g1, 3), if (ret = "", ret := "3", ret := ret + ",3"));
    if (getbit(g1, 4), if (ret = "", ret := "4", ret := ret + ",4"));
    if (getbit(g1, 5), if (ret = "", ret := "5", ret := ret + ",5"));
    if (getbit(g1, 6), if (ret = "", ret := "6", ret := ret + ",6"));
    if (getbit(g1, 7), if (ret = "", ret := "7", ret := ret + ",7"));
    if (getbit(g2, 0), if (ret = "", ret := "8", ret := ret + ",8"));
    if (getbit(g2, 1), if (ret = "", ret := "9", ret := ret + ",9"));
    if (getbit(g2, 2), if (ret = "", ret := "10", ret := ret + ",10"));
    if (getbit(g2, 3), if (ret = "", ret := "11", ret := ret + ",11"));
    if (getbit(g2, 4), if (ret = "", ret := "12", ret := ret + ",12"));
    if (getbit(g2, 5), if (ret = "", ret := "13", ret := ret + ",13"));
    if (getbit(g2, 6), if (ret = "", ret := "14", ret := ret + ",14"));
    if (getbit(g2, 7), if (ret = "", ret := "15", ret := ret + ",15"));

    if (ret = "", return("None"), return(ret));
else
    return("--");
end
DALI Status
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x90);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if x <= 0xFF
        var s := "";
        if (getbit(x, 0), s := if(s = "", "gear failure", s + ", gear failure"));
        if (getbit(x, 1), s := if(s = "", "lamp failure", s + ", lamp failure"));
        if (getbit(x, 2), s := if(s = "", "lamp on", s + ", lamp on"));
        if (getbit(x, 3), s := if(s = "", "limit error", s + ", limit error"));
        if (getbit(x, 4), s := if(s = "", "fade running", s + ", fade running"));
        if (getbit(x, 5), s := if(s = "", "reset state", s + ", reset state"));
        if (getbit(x, 6), s := if(s = "", "missing short address", s + ", missing short address"));
        if (getbit(x, 7), s := if(s = "", "power cycle", s + ", power cycle"));
        var ign := if((ignGear = 1) and (ignLamp = 1), "gear and lamp failure", if(ignGear = 1, "gear failure", if(ignLamp = 1, "lamp failure", "")));
        return(if(s = "", "OK", s) + " (0x" + tostring(x, "X2") + ")" + if(ign = "", "", "; not raised: " + ign + " reported since start"));
    end
end

return("--")
Fade
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA5);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if x <= 0xFF
        var t := getbits(x, 4, 4);
        var ret := if(t = 0, "off", t + " (" + round(sqrt(power(2, t)) * 5) / 10 + " s)");
        modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA8);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
        var e := modbusr(SH, 511, uint16);
        if (t = 0 and e <= 0xFF and e != 0, ret := "extended 0x" + tostring(e, "X2"));
        return("fade time " + ret + ", fade rate " + getbits(x, 0, 4));
    end
end

return("--")
DALI Version
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x97);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if x <= 0xFF
        return(if(x >= 8, "DALI-2 " + getbits(x, 2, 6) + "." + getbits(x, 0, 2), "DALI-1") + " (" + x + ")");
    end
end

return("--")
Bus statistics
return("since start: queries " + cntQ + ", stale answers read away " + cntStale + ", no answer " + cntNone + ", collisions " + cntColl + ", rejected levels " + cntBad)
Azioni di servizio
${xml_add_to_group}
Parametri: Group ID (0–15 grp)
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x60 + grp);
${xml_remove_from_group}
Parametri: Group ID (0–15 grp)
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x70 + grp);
${xml_reset_to_default_settings}
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x20);
${xml_set_startup_levels}
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x21);
sleep(10);
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x2c);
sleep(10);
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x2d);
Disable fading
modbusw(SH, 541, uint16, 0xA300);
sleep(100);
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x2E);
sleep(100);
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x30);
Gear 29 Dimmer Lettura e scrittura

Dispositivo di controllo DALI all'indirizzo breve 29 — dimmer TapHome mappato su DALI arc power 0–100 % tramite H:510 LAMP LEVEL (scrittura) e QUERY ACTUAL LEVEL tramite H:511 (lettura), delimitato dai propri MIN / MAX LEVEL del gear.

Registro: H:511 → H:510 UInt16 Unità: % numeric
Attributi di servizio
Indirizzo breveIndirizzo breve DALI (0–63) target di questo dispositivo — fissato al momento dell'importazione del template e utilizzato nel byte alto di ogni scrittura Modbus.
Device TypeByte device-type DALI restituito da QUERY DEVICE TYPE (0x99) — riporta DT0 (fluorescente), DT6 (driver LED), DT8 (colore / tunable white) ecc., o -- quando non c'è risposta.
Physical Min LevelLivello minimo di dimmerazione imposto dall'hardware riportato dal gear — letto da QUERY PHYSICAL MIN LEVEL (0x9A), in percentuale.
Max LevelDALI MAX LEVEL configurato — letto da QUERY MAX LEVEL (0xA1); utilizzato come limite superiore durante la scalatura di TapHome 0–100 % su DALI arc power.
Min LevelDALI MIN LEVEL configurato — letto da QUERY MIN LEVEL (0xA2); utilizzato come limite inferiore durante la scalatura di TapHome 0–100 % su DALI arc power.
Power Up LevelLuminosità ripristinata dopo il ripristino dell'alimentazione del bus DALI — letta da QUERY POWER ON LEVEL (0xA3).
System Failure LevelLuminosità adottata quando il bus DALI perde la comunicazione per più di 500 ms — letta da QUERY SYSTEM FAILURE LEVEL (0xA4).
GruppiElenco separato da virgole dei gruppi DALI (0–15) a cui appartiene il gear — decodificato da QUERY GROUPS 0-7 (0xC0) e QUERY GROUPS 8-15 (0xC1); mostra None o ad es. 0,3,7.
Support Lamp FailureSe la lampada / driver supporta il rilevamento dei guasti della lampada — Yes / No / --. Gestisce l'errore Lamp failure! nel readscript periodico.
Support Power FailureSe la lampada / driver supporta il rilevamento dei guasti di alimentazione — Yes / No / --. Gestisce l'errore Power failure! nel readscript periodico.
DALI Version
Bus statistics
Azioni di servizio
Add to GroupAggiunge questo gear a un gruppo DALI (0–15) tramite ADD TO GROUP (0x60+grp) — auto-ripetuto entro 100 ms come richiesto per i comandi di configurazione DALI.
Remove from GroupRimuove questo gear da un gruppo DALI (0–15) tramite REMOVE FROM GROUP (0x70+grp).
Reset to Default SettingsInvia DALI RESET (0x20) — ripristina ogni parametro NVM del gear (livelli max / min / power-on / system-failure, appartenenza al gruppo, scene) al valore predefinito del produttore.
Set Startup LevelsCattura l'arc power corrente e la memorizza come Power On Level e System Failure Level — sequenza STORE ACTUAL LEVEL IN DTR (0x21) → STORE DTR AS POWER ON LEVEL (0x2C) → STORE DTR AS SYSTEM FAILURE LEVEL (0x2D).
Disable fading

Gear 29

Lettura (modulo)
var x := 0; var rx := 0; var y := 0;
if Status > 0
    Status := Status - 1;
    adderror(3, "Gear not responding!");
    return(0);
end

# checkStatus: ReadLevel resets it while the gear answers; statusPoll: QUERY STATUS at least once per 60 runs
checkStatus := checkStatus - 1;
statusPoll := statusPoll - 1;
if checkStatus < 1 or statusPoll < 1
    # an unread answer left in the gateway would be taken for this query: read it away and count it
    x := modbusr(SH, 511, uint16); if (x != 0x8000, cntStale := cntStale + 1);
    modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x90);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    x := modbusr(SH, 511, uint16);
    cntQ := cntQ + 1; if (x = 0x8000, cntNone := cntNone + 1); if (x = 0x20FF, cntColl := cntColl + 1);
    # a single lost answer happens on DALI: ask once more before declaring the gear missing
    if x = 0x8000
        x := modbusr(SH, 511, uint16); if (x != 0x8000, cntStale := cntStale + 1);
        modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x90);
        sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
        x := modbusr(SH, 511, uint16);
        cntQ := cntQ + 1; if (x = 0x8000, cntNone := cntNone + 1); if (x = 0x20FF, cntColl := cntColl + 1);
    end
    if x <= 0xFF
        # a changed failure bit must be read twice the same before it is taken
        if statusSeen = 1 and getbits(x, 0, 2) != getbits(gearStatus, 0, 2)
            y := modbusr(SH, 511, uint16); if (y != 0x8000, cntStale := cntStale + 1);
            modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x90);
            sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
            y := modbusr(SH, 511, uint16);
            cntQ := cntQ + 1; if (y = 0x8000, cntNone := cntNone + 1); if (y = 0x20FF, cntColl := cntColl + 1);
            if y != x
                cntBad := cntBad + 1;
                x := gearStatus;
            end
        end
        if statusSeen = 0
            ignGear := getbit(x, 0);
            ignLamp := getbit(x, 1);
            statusSeen := 1;
        end
        # a bit that clears ends its ignore, so a later failure is raised
        if (getbit(x, 0) = 0, ignGear := 0);
        if (getbit(x, 1) = 0, ignLamp := 0);
        gearStatus := x;
        checkStatus := 60;
        statusPoll := 60;
    else
        if x = 0x8000
            Status := RANDINT(10, 60);
            adderror(3, "Gear not responding!");
            return(0);
        end
    end
end

# messages last one run only, so they are raised from the stored status on every run
if ((getbit(gearStatus, 0) = 1) and (ignGear = 0), adderror(1, "Control gear failure!"));
if ((getbit(gearStatus, 1) = 1) and (ignLamp = 0), adderror(2, "Lamp failure!"));
Inizializzazione
var x := 0; var rx := 0;
# QUERY STATUS 0x90: every reply byte proves the gear is present; 0x8000 = no answer, 0x20FF = bus collision
# an unread answer left in the gateway would be taken for this query: read it away and count it
x := modbusr(SH, 511, uint16); if (x != 0x8000, cntStale := cntStale + 1);
modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x90);
sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
x := modbusr(SH, 511, uint16);
cntQ := cntQ + 1; if (x = 0x8000, cntNone := cntNone + 1); if (x = 0x20FF, cntColl := cntColl + 1);
statusSeen := 0;
if x <= 0xFF
    # failure bits a gear reports from its first answer are its permanent state, not an event: shown, not raised
    gearStatus := x;
    ignGear := getbit(x, 0);
    ignLamp := getbit(x, 1);
    statusSeen := 1;
    Status := 0;
else
    Status := RANDINT(1, 60);
end

if Status = 0
    x := modbusr(SH, 511, uint16); if (x != 0x8000, cntStale := cntStale + 1);
    modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA2);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    x := modbusr(SH, 511, uint16);
    cntQ := cntQ + 1; if (x = 0x8000, cntNone := cntNone + 1); if (x = 0x20FF, cntColl := cntColl + 1);
    if (x <= 0xFE, minLevel := x);

    x := modbusr(SH, 511, uint16); if (x != 0x8000, cntStale := cntStale + 1);
    modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA1);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    x := modbusr(SH, 511, uint16);
    cntQ := cntQ + 1; if (x = 0x8000, cntNone := cntNone + 1); if (x = 0x20FF, cntColl := cntColl + 1);
    if (x <= 0xFE, maxLevel := x);
end
Lettura livello
var x := 0; var rx := 0; var y := 0;
if Status = 0
    if minLevel = 0
        # an unread answer left in the gateway would be taken for this query: read it away and count it
        x := modbusr(SH, 511, uint16); if (x != 0x8000, cntStale := cntStale + 1);
        modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA2);
        sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
        x := modbusr(SH, 511, uint16);
        cntQ := cntQ + 1; if (x = 0x8000, cntNone := cntNone + 1); if (x = 0x20FF, cntColl := cntColl + 1);
        if (x <= 0xFE, minLevel := x);
    end
    x := modbusr(SH, 511, uint16); if (x != 0x8000, cntStale := cntStale + 1);
    modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA0);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    x := modbusr(SH, 511, uint16);
    cntQ := cntQ + 1; if (x = 0x8000, cntNone := cntNone + 1); if (x = 0x20FF, cntColl := cntColl + 1);
    if (x != 0x8000 or rx, checkStatus := 60);
    # 0xFF = MASK, 0x20FF = collision, 0x8000 = no answer: keep the last level instead of a phantom value
    if x > 0xFE
        return(Le);
    end
    # an actual level is 0 or between the gear's min and max: anything else is not this gear's answer
    if x > 0 and x < minLevel
        cntBad := cntBad + 1;
        return(Le);
    end
    # a changed level must be read twice the same before it is taken
    if x != lastRaw
        y := modbusr(SH, 511, uint16); if (y != 0x8000, cntStale := cntStale + 1);
        modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA0);
        sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
        y := modbusr(SH, 511, uint16);
        cntQ := cntQ + 1; if (y = 0x8000, cntNone := cntNone + 1); if (y = 0x20FF, cntColl := cntColl + 1);
        if y != x
            cntBad := cntBad + 1;
            return(Le);
        end
        lastRaw := x;
    end
    return(if(x = 0, 0, linear(x, minLevel, 0.01, maxLevel, 1)));
else
    return(NaN);
end
Scrittura livello
var level := 0;
if(Le > 0, level := round(linear(Le, 0.01, minLevel, 1, maxLevel)));
modbusw(SH, 510, uint16, (ShortAddress << 8) + level );
Attributi di servizio
${xml_short_address}
ShortAddress
${xml_device_type}
var x := 0; var y := 0; var rx := 0; var s := ""; var i := 0;
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x99);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    x := modbusr(SH, 511, uint16);
    if (x < 0xFF, return("DT" + x));
    if x = 0xFF
        while i < 8
            modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA7);
            sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
            y := modbusr(SH, 511, uint16);
            if y < 0xFE
                s := if(s = "", "DT" + y, s + ", DT" + y);
                i := i + 1;
            else
                i := 8;
            end
        loop
        return(if(s = "", "MASK", s));
    end
end

return("--")
Physical Min Level
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x9A);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if (x <= 0xFE, return(round((x / 0xFE) * 100) + " %"));
end

return("--")
Max Level
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA1);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if (x <= 0xFE, return(round((x / 0xFE) * 100) + " %"));
end

return("--")
Min Level
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA2);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if (x <= 0xFE, return(round((x / 0xFE) * 100) + " %"));
end

return("--")
Power Up Level
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA3);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if (x <= 0xFE, return(round((x / 0xFE) * 100) + " %"));
end

return("--")
System Failure Level
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA4);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if (x <= 0xFE, return(round((x / 0xFE) * 100) + " %"));
end

return("--")
${xml_groups}
var x := 0; var rx := 0;
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xC0);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var g1 := modbusr(SH, 511, uint16);
    if (g1 > 0xFF, return("--")); 

    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xC1);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var g2 := modbusr(SH, 511, uint16);
    if (g2 > 0xFF, return("--")); 

    var ret := "";

    if (getbit(g1, 0), ret := ret + "0");
    if (getbit(g1, 1), if (ret = "", ret := "1", ret := ret + ",1"));
    if (getbit(g1, 2), if (ret = "", ret := "2", ret := ret + ",2"));
    if (getbit(g1, 3), if (ret = "", ret := "3", ret := ret + ",3"));
    if (getbit(g1, 4), if (ret = "", ret := "4", ret := ret + ",4"));
    if (getbit(g1, 5), if (ret = "", ret := "5", ret := ret + ",5"));
    if (getbit(g1, 6), if (ret = "", ret := "6", ret := ret + ",6"));
    if (getbit(g1, 7), if (ret = "", ret := "7", ret := ret + ",7"));
    if (getbit(g2, 0), if (ret = "", ret := "8", ret := ret + ",8"));
    if (getbit(g2, 1), if (ret = "", ret := "9", ret := ret + ",9"));
    if (getbit(g2, 2), if (ret = "", ret := "10", ret := ret + ",10"));
    if (getbit(g2, 3), if (ret = "", ret := "11", ret := ret + ",11"));
    if (getbit(g2, 4), if (ret = "", ret := "12", ret := ret + ",12"));
    if (getbit(g2, 5), if (ret = "", ret := "13", ret := ret + ",13"));
    if (getbit(g2, 6), if (ret = "", ret := "14", ret := ret + ",14"));
    if (getbit(g2, 7), if (ret = "", ret := "15", ret := ret + ",15"));

    if (ret = "", return("None"), return(ret));
else
    return("--");
end
DALI Status
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x90);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if x <= 0xFF
        var s := "";
        if (getbit(x, 0), s := if(s = "", "gear failure", s + ", gear failure"));
        if (getbit(x, 1), s := if(s = "", "lamp failure", s + ", lamp failure"));
        if (getbit(x, 2), s := if(s = "", "lamp on", s + ", lamp on"));
        if (getbit(x, 3), s := if(s = "", "limit error", s + ", limit error"));
        if (getbit(x, 4), s := if(s = "", "fade running", s + ", fade running"));
        if (getbit(x, 5), s := if(s = "", "reset state", s + ", reset state"));
        if (getbit(x, 6), s := if(s = "", "missing short address", s + ", missing short address"));
        if (getbit(x, 7), s := if(s = "", "power cycle", s + ", power cycle"));
        var ign := if((ignGear = 1) and (ignLamp = 1), "gear and lamp failure", if(ignGear = 1, "gear failure", if(ignLamp = 1, "lamp failure", "")));
        return(if(s = "", "OK", s) + " (0x" + tostring(x, "X2") + ")" + if(ign = "", "", "; not raised: " + ign + " reported since start"));
    end
end

return("--")
Fade
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA5);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if x <= 0xFF
        var t := getbits(x, 4, 4);
        var ret := if(t = 0, "off", t + " (" + round(sqrt(power(2, t)) * 5) / 10 + " s)");
        modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA8);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
        var e := modbusr(SH, 511, uint16);
        if (t = 0 and e <= 0xFF and e != 0, ret := "extended 0x" + tostring(e, "X2"));
        return("fade time " + ret + ", fade rate " + getbits(x, 0, 4));
    end
end

return("--")
DALI Version
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x97);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if x <= 0xFF
        return(if(x >= 8, "DALI-2 " + getbits(x, 2, 6) + "." + getbits(x, 0, 2), "DALI-1") + " (" + x + ")");
    end
end

return("--")
Bus statistics
return("since start: queries " + cntQ + ", stale answers read away " + cntStale + ", no answer " + cntNone + ", collisions " + cntColl + ", rejected levels " + cntBad)
Azioni di servizio
${xml_add_to_group}
Parametri: Group ID (0–15 grp)
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x60 + grp);
${xml_remove_from_group}
Parametri: Group ID (0–15 grp)
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x70 + grp);
${xml_reset_to_default_settings}
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x20);
${xml_set_startup_levels}
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x21);
sleep(10);
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x2c);
sleep(10);
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x2d);
Disable fading
modbusw(SH, 541, uint16, 0xA300);
sleep(100);
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x2E);
sleep(100);
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x30);
Gear 30 Dimmer Lettura e scrittura

Dispositivo di controllo DALI all'indirizzo breve 30 — dimmer TapHome mappato su DALI arc power 0–100 % tramite H:510 LAMP LEVEL (scrittura) e QUERY ACTUAL LEVEL tramite H:511 (lettura), delimitato dai propri MIN / MAX LEVEL del gear.

Registro: H:511 → H:510 UInt16 Unità: % numeric
Attributi di servizio
Indirizzo breveIndirizzo breve DALI (0–63) target di questo dispositivo — fissato al momento dell'importazione del template e utilizzato nel byte alto di ogni scrittura Modbus.
Device TypeByte device-type DALI restituito da QUERY DEVICE TYPE (0x99) — riporta DT0 (fluorescente), DT6 (driver LED), DT8 (colore / tunable white) ecc., o -- quando non c'è risposta.
Physical Min LevelLivello minimo di dimmerazione imposto dall'hardware riportato dal gear — letto da QUERY PHYSICAL MIN LEVEL (0x9A), in percentuale.
Max LevelDALI MAX LEVEL configurato — letto da QUERY MAX LEVEL (0xA1); utilizzato come limite superiore durante la scalatura di TapHome 0–100 % su DALI arc power.
Min LevelDALI MIN LEVEL configurato — letto da QUERY MIN LEVEL (0xA2); utilizzato come limite inferiore durante la scalatura di TapHome 0–100 % su DALI arc power.
Power Up LevelLuminosità ripristinata dopo il ripristino dell'alimentazione del bus DALI — letta da QUERY POWER ON LEVEL (0xA3).
System Failure LevelLuminosità adottata quando il bus DALI perde la comunicazione per più di 500 ms — letta da QUERY SYSTEM FAILURE LEVEL (0xA4).
GruppiElenco separato da virgole dei gruppi DALI (0–15) a cui appartiene il gear — decodificato da QUERY GROUPS 0-7 (0xC0) e QUERY GROUPS 8-15 (0xC1); mostra None o ad es. 0,3,7.
Support Lamp FailureSe la lampada / driver supporta il rilevamento dei guasti della lampada — Yes / No / --. Gestisce l'errore Lamp failure! nel readscript periodico.
Support Power FailureSe la lampada / driver supporta il rilevamento dei guasti di alimentazione — Yes / No / --. Gestisce l'errore Power failure! nel readscript periodico.
DALI Version
Bus statistics
Azioni di servizio
Add to GroupAggiunge questo gear a un gruppo DALI (0–15) tramite ADD TO GROUP (0x60+grp) — auto-ripetuto entro 100 ms come richiesto per i comandi di configurazione DALI.
Remove from GroupRimuove questo gear da un gruppo DALI (0–15) tramite REMOVE FROM GROUP (0x70+grp).
Reset to Default SettingsInvia DALI RESET (0x20) — ripristina ogni parametro NVM del gear (livelli max / min / power-on / system-failure, appartenenza al gruppo, scene) al valore predefinito del produttore.
Set Startup LevelsCattura l'arc power corrente e la memorizza come Power On Level e System Failure Level — sequenza STORE ACTUAL LEVEL IN DTR (0x21) → STORE DTR AS POWER ON LEVEL (0x2C) → STORE DTR AS SYSTEM FAILURE LEVEL (0x2D).
Disable fading

Gear 30

Lettura (modulo)
var x := 0; var rx := 0; var y := 0;
if Status > 0
    Status := Status - 1;
    adderror(3, "Gear not responding!");
    return(0);
end

# checkStatus: ReadLevel resets it while the gear answers; statusPoll: QUERY STATUS at least once per 60 runs
checkStatus := checkStatus - 1;
statusPoll := statusPoll - 1;
if checkStatus < 1 or statusPoll < 1
    # an unread answer left in the gateway would be taken for this query: read it away and count it
    x := modbusr(SH, 511, uint16); if (x != 0x8000, cntStale := cntStale + 1);
    modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x90);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    x := modbusr(SH, 511, uint16);
    cntQ := cntQ + 1; if (x = 0x8000, cntNone := cntNone + 1); if (x = 0x20FF, cntColl := cntColl + 1);
    # a single lost answer happens on DALI: ask once more before declaring the gear missing
    if x = 0x8000
        x := modbusr(SH, 511, uint16); if (x != 0x8000, cntStale := cntStale + 1);
        modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x90);
        sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
        x := modbusr(SH, 511, uint16);
        cntQ := cntQ + 1; if (x = 0x8000, cntNone := cntNone + 1); if (x = 0x20FF, cntColl := cntColl + 1);
    end
    if x <= 0xFF
        # a changed failure bit must be read twice the same before it is taken
        if statusSeen = 1 and getbits(x, 0, 2) != getbits(gearStatus, 0, 2)
            y := modbusr(SH, 511, uint16); if (y != 0x8000, cntStale := cntStale + 1);
            modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x90);
            sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
            y := modbusr(SH, 511, uint16);
            cntQ := cntQ + 1; if (y = 0x8000, cntNone := cntNone + 1); if (y = 0x20FF, cntColl := cntColl + 1);
            if y != x
                cntBad := cntBad + 1;
                x := gearStatus;
            end
        end
        if statusSeen = 0
            ignGear := getbit(x, 0);
            ignLamp := getbit(x, 1);
            statusSeen := 1;
        end
        # a bit that clears ends its ignore, so a later failure is raised
        if (getbit(x, 0) = 0, ignGear := 0);
        if (getbit(x, 1) = 0, ignLamp := 0);
        gearStatus := x;
        checkStatus := 60;
        statusPoll := 60;
    else
        if x = 0x8000
            Status := RANDINT(10, 60);
            adderror(3, "Gear not responding!");
            return(0);
        end
    end
end

# messages last one run only, so they are raised from the stored status on every run
if ((getbit(gearStatus, 0) = 1) and (ignGear = 0), adderror(1, "Control gear failure!"));
if ((getbit(gearStatus, 1) = 1) and (ignLamp = 0), adderror(2, "Lamp failure!"));
Inizializzazione
var x := 0; var rx := 0;
# QUERY STATUS 0x90: every reply byte proves the gear is present; 0x8000 = no answer, 0x20FF = bus collision
# an unread answer left in the gateway would be taken for this query: read it away and count it
x := modbusr(SH, 511, uint16); if (x != 0x8000, cntStale := cntStale + 1);
modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x90);
sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
x := modbusr(SH, 511, uint16);
cntQ := cntQ + 1; if (x = 0x8000, cntNone := cntNone + 1); if (x = 0x20FF, cntColl := cntColl + 1);
statusSeen := 0;
if x <= 0xFF
    # failure bits a gear reports from its first answer are its permanent state, not an event: shown, not raised
    gearStatus := x;
    ignGear := getbit(x, 0);
    ignLamp := getbit(x, 1);
    statusSeen := 1;
    Status := 0;
else
    Status := RANDINT(1, 60);
end

if Status = 0
    x := modbusr(SH, 511, uint16); if (x != 0x8000, cntStale := cntStale + 1);
    modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA2);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    x := modbusr(SH, 511, uint16);
    cntQ := cntQ + 1; if (x = 0x8000, cntNone := cntNone + 1); if (x = 0x20FF, cntColl := cntColl + 1);
    if (x <= 0xFE, minLevel := x);

    x := modbusr(SH, 511, uint16); if (x != 0x8000, cntStale := cntStale + 1);
    modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA1);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    x := modbusr(SH, 511, uint16);
    cntQ := cntQ + 1; if (x = 0x8000, cntNone := cntNone + 1); if (x = 0x20FF, cntColl := cntColl + 1);
    if (x <= 0xFE, maxLevel := x);
end
Lettura livello
var x := 0; var rx := 0; var y := 0;
if Status = 0
    if minLevel = 0
        # an unread answer left in the gateway would be taken for this query: read it away and count it
        x := modbusr(SH, 511, uint16); if (x != 0x8000, cntStale := cntStale + 1);
        modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA2);
        sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
        x := modbusr(SH, 511, uint16);
        cntQ := cntQ + 1; if (x = 0x8000, cntNone := cntNone + 1); if (x = 0x20FF, cntColl := cntColl + 1);
        if (x <= 0xFE, minLevel := x);
    end
    x := modbusr(SH, 511, uint16); if (x != 0x8000, cntStale := cntStale + 1);
    modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA0);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    x := modbusr(SH, 511, uint16);
    cntQ := cntQ + 1; if (x = 0x8000, cntNone := cntNone + 1); if (x = 0x20FF, cntColl := cntColl + 1);
    if (x != 0x8000 or rx, checkStatus := 60);
    # 0xFF = MASK, 0x20FF = collision, 0x8000 = no answer: keep the last level instead of a phantom value
    if x > 0xFE
        return(Le);
    end
    # an actual level is 0 or between the gear's min and max: anything else is not this gear's answer
    if x > 0 and x < minLevel
        cntBad := cntBad + 1;
        return(Le);
    end
    # a changed level must be read twice the same before it is taken
    if x != lastRaw
        y := modbusr(SH, 511, uint16); if (y != 0x8000, cntStale := cntStale + 1);
        modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA0);
        sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
        y := modbusr(SH, 511, uint16);
        cntQ := cntQ + 1; if (y = 0x8000, cntNone := cntNone + 1); if (y = 0x20FF, cntColl := cntColl + 1);
        if y != x
            cntBad := cntBad + 1;
            return(Le);
        end
        lastRaw := x;
    end
    return(if(x = 0, 0, linear(x, minLevel, 0.01, maxLevel, 1)));
else
    return(NaN);
end
Scrittura livello
var level := 0;
if(Le > 0, level := round(linear(Le, 0.01, minLevel, 1, maxLevel)));
modbusw(SH, 510, uint16, (ShortAddress << 8) + level );
Attributi di servizio
${xml_short_address}
ShortAddress
${xml_device_type}
var x := 0; var y := 0; var rx := 0; var s := ""; var i := 0;
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x99);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    x := modbusr(SH, 511, uint16);
    if (x < 0xFF, return("DT" + x));
    if x = 0xFF
        while i < 8
            modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA7);
            sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
            y := modbusr(SH, 511, uint16);
            if y < 0xFE
                s := if(s = "", "DT" + y, s + ", DT" + y);
                i := i + 1;
            else
                i := 8;
            end
        loop
        return(if(s = "", "MASK", s));
    end
end

return("--")
Physical Min Level
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x9A);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if (x <= 0xFE, return(round((x / 0xFE) * 100) + " %"));
end

return("--")
Max Level
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA1);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if (x <= 0xFE, return(round((x / 0xFE) * 100) + " %"));
end

return("--")
Min Level
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA2);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if (x <= 0xFE, return(round((x / 0xFE) * 100) + " %"));
end

return("--")
Power Up Level
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA3);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if (x <= 0xFE, return(round((x / 0xFE) * 100) + " %"));
end

return("--")
System Failure Level
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA4);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if (x <= 0xFE, return(round((x / 0xFE) * 100) + " %"));
end

return("--")
${xml_groups}
var x := 0; var rx := 0;
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xC0);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var g1 := modbusr(SH, 511, uint16);
    if (g1 > 0xFF, return("--")); 

    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xC1);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var g2 := modbusr(SH, 511, uint16);
    if (g2 > 0xFF, return("--")); 

    var ret := "";

    if (getbit(g1, 0), ret := ret + "0");
    if (getbit(g1, 1), if (ret = "", ret := "1", ret := ret + ",1"));
    if (getbit(g1, 2), if (ret = "", ret := "2", ret := ret + ",2"));
    if (getbit(g1, 3), if (ret = "", ret := "3", ret := ret + ",3"));
    if (getbit(g1, 4), if (ret = "", ret := "4", ret := ret + ",4"));
    if (getbit(g1, 5), if (ret = "", ret := "5", ret := ret + ",5"));
    if (getbit(g1, 6), if (ret = "", ret := "6", ret := ret + ",6"));
    if (getbit(g1, 7), if (ret = "", ret := "7", ret := ret + ",7"));
    if (getbit(g2, 0), if (ret = "", ret := "8", ret := ret + ",8"));
    if (getbit(g2, 1), if (ret = "", ret := "9", ret := ret + ",9"));
    if (getbit(g2, 2), if (ret = "", ret := "10", ret := ret + ",10"));
    if (getbit(g2, 3), if (ret = "", ret := "11", ret := ret + ",11"));
    if (getbit(g2, 4), if (ret = "", ret := "12", ret := ret + ",12"));
    if (getbit(g2, 5), if (ret = "", ret := "13", ret := ret + ",13"));
    if (getbit(g2, 6), if (ret = "", ret := "14", ret := ret + ",14"));
    if (getbit(g2, 7), if (ret = "", ret := "15", ret := ret + ",15"));

    if (ret = "", return("None"), return(ret));
else
    return("--");
end
DALI Status
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x90);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if x <= 0xFF
        var s := "";
        if (getbit(x, 0), s := if(s = "", "gear failure", s + ", gear failure"));
        if (getbit(x, 1), s := if(s = "", "lamp failure", s + ", lamp failure"));
        if (getbit(x, 2), s := if(s = "", "lamp on", s + ", lamp on"));
        if (getbit(x, 3), s := if(s = "", "limit error", s + ", limit error"));
        if (getbit(x, 4), s := if(s = "", "fade running", s + ", fade running"));
        if (getbit(x, 5), s := if(s = "", "reset state", s + ", reset state"));
        if (getbit(x, 6), s := if(s = "", "missing short address", s + ", missing short address"));
        if (getbit(x, 7), s := if(s = "", "power cycle", s + ", power cycle"));
        var ign := if((ignGear = 1) and (ignLamp = 1), "gear and lamp failure", if(ignGear = 1, "gear failure", if(ignLamp = 1, "lamp failure", "")));
        return(if(s = "", "OK", s) + " (0x" + tostring(x, "X2") + ")" + if(ign = "", "", "; not raised: " + ign + " reported since start"));
    end
end

return("--")
Fade
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA5);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if x <= 0xFF
        var t := getbits(x, 4, 4);
        var ret := if(t = 0, "off", t + " (" + round(sqrt(power(2, t)) * 5) / 10 + " s)");
        modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA8);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
        var e := modbusr(SH, 511, uint16);
        if (t = 0 and e <= 0xFF and e != 0, ret := "extended 0x" + tostring(e, "X2"));
        return("fade time " + ret + ", fade rate " + getbits(x, 0, 4));
    end
end

return("--")
DALI Version
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x97);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if x <= 0xFF
        return(if(x >= 8, "DALI-2 " + getbits(x, 2, 6) + "." + getbits(x, 0, 2), "DALI-1") + " (" + x + ")");
    end
end

return("--")
Bus statistics
return("since start: queries " + cntQ + ", stale answers read away " + cntStale + ", no answer " + cntNone + ", collisions " + cntColl + ", rejected levels " + cntBad)
Azioni di servizio
${xml_add_to_group}
Parametri: Group ID (0–15 grp)
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x60 + grp);
${xml_remove_from_group}
Parametri: Group ID (0–15 grp)
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x70 + grp);
${xml_reset_to_default_settings}
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x20);
${xml_set_startup_levels}
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x21);
sleep(10);
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x2c);
sleep(10);
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x2d);
Disable fading
modbusw(SH, 541, uint16, 0xA300);
sleep(100);
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x2E);
sleep(100);
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x30);
Gear 31 Dimmer Lettura e scrittura

Dispositivo di controllo DALI all'indirizzo breve 31 — dimmer TapHome mappato su DALI arc power 0–100 % tramite H:510 LAMP LEVEL (scrittura) e QUERY ACTUAL LEVEL tramite H:511 (lettura), delimitato dai propri MIN / MAX LEVEL del gear.

Registro: H:511 → H:510 UInt16 Unità: % numeric
Attributi di servizio
Indirizzo breveIndirizzo breve DALI (0–63) target di questo dispositivo — fissato al momento dell'importazione del template e utilizzato nel byte alto di ogni scrittura Modbus.
Device TypeByte device-type DALI restituito da QUERY DEVICE TYPE (0x99) — riporta DT0 (fluorescente), DT6 (driver LED), DT8 (colore / tunable white) ecc., o -- quando non c'è risposta.
Physical Min LevelLivello minimo di dimmerazione imposto dall'hardware riportato dal gear — letto da QUERY PHYSICAL MIN LEVEL (0x9A), in percentuale.
Max LevelDALI MAX LEVEL configurato — letto da QUERY MAX LEVEL (0xA1); utilizzato come limite superiore durante la scalatura di TapHome 0–100 % su DALI arc power.
Min LevelDALI MIN LEVEL configurato — letto da QUERY MIN LEVEL (0xA2); utilizzato come limite inferiore durante la scalatura di TapHome 0–100 % su DALI arc power.
Power Up LevelLuminosità ripristinata dopo il ripristino dell'alimentazione del bus DALI — letta da QUERY POWER ON LEVEL (0xA3).
System Failure LevelLuminosità adottata quando il bus DALI perde la comunicazione per più di 500 ms — letta da QUERY SYSTEM FAILURE LEVEL (0xA4).
GruppiElenco separato da virgole dei gruppi DALI (0–15) a cui appartiene il gear — decodificato da QUERY GROUPS 0-7 (0xC0) e QUERY GROUPS 8-15 (0xC1); mostra None o ad es. 0,3,7.
Support Lamp FailureSe la lampada / driver supporta il rilevamento dei guasti della lampada — Yes / No / --. Gestisce l'errore Lamp failure! nel readscript periodico.
Support Power FailureSe la lampada / driver supporta il rilevamento dei guasti di alimentazione — Yes / No / --. Gestisce l'errore Power failure! nel readscript periodico.
DALI Version
Bus statistics
Azioni di servizio
Add to GroupAggiunge questo gear a un gruppo DALI (0–15) tramite ADD TO GROUP (0x60+grp) — auto-ripetuto entro 100 ms come richiesto per i comandi di configurazione DALI.
Remove from GroupRimuove questo gear da un gruppo DALI (0–15) tramite REMOVE FROM GROUP (0x70+grp).
Reset to Default SettingsInvia DALI RESET (0x20) — ripristina ogni parametro NVM del gear (livelli max / min / power-on / system-failure, appartenenza al gruppo, scene) al valore predefinito del produttore.
Set Startup LevelsCattura l'arc power corrente e la memorizza come Power On Level e System Failure Level — sequenza STORE ACTUAL LEVEL IN DTR (0x21) → STORE DTR AS POWER ON LEVEL (0x2C) → STORE DTR AS SYSTEM FAILURE LEVEL (0x2D).
Disable fading

Gear 31

Lettura (modulo)
var x := 0; var rx := 0; var y := 0;
if Status > 0
    Status := Status - 1;
    adderror(3, "Gear not responding!");
    return(0);
end

# checkStatus: ReadLevel resets it while the gear answers; statusPoll: QUERY STATUS at least once per 60 runs
checkStatus := checkStatus - 1;
statusPoll := statusPoll - 1;
if checkStatus < 1 or statusPoll < 1
    # an unread answer left in the gateway would be taken for this query: read it away and count it
    x := modbusr(SH, 511, uint16); if (x != 0x8000, cntStale := cntStale + 1);
    modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x90);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    x := modbusr(SH, 511, uint16);
    cntQ := cntQ + 1; if (x = 0x8000, cntNone := cntNone + 1); if (x = 0x20FF, cntColl := cntColl + 1);
    # a single lost answer happens on DALI: ask once more before declaring the gear missing
    if x = 0x8000
        x := modbusr(SH, 511, uint16); if (x != 0x8000, cntStale := cntStale + 1);
        modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x90);
        sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
        x := modbusr(SH, 511, uint16);
        cntQ := cntQ + 1; if (x = 0x8000, cntNone := cntNone + 1); if (x = 0x20FF, cntColl := cntColl + 1);
    end
    if x <= 0xFF
        # a changed failure bit must be read twice the same before it is taken
        if statusSeen = 1 and getbits(x, 0, 2) != getbits(gearStatus, 0, 2)
            y := modbusr(SH, 511, uint16); if (y != 0x8000, cntStale := cntStale + 1);
            modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x90);
            sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
            y := modbusr(SH, 511, uint16);
            cntQ := cntQ + 1; if (y = 0x8000, cntNone := cntNone + 1); if (y = 0x20FF, cntColl := cntColl + 1);
            if y != x
                cntBad := cntBad + 1;
                x := gearStatus;
            end
        end
        if statusSeen = 0
            ignGear := getbit(x, 0);
            ignLamp := getbit(x, 1);
            statusSeen := 1;
        end
        # a bit that clears ends its ignore, so a later failure is raised
        if (getbit(x, 0) = 0, ignGear := 0);
        if (getbit(x, 1) = 0, ignLamp := 0);
        gearStatus := x;
        checkStatus := 60;
        statusPoll := 60;
    else
        if x = 0x8000
            Status := RANDINT(10, 60);
            adderror(3, "Gear not responding!");
            return(0);
        end
    end
end

# messages last one run only, so they are raised from the stored status on every run
if ((getbit(gearStatus, 0) = 1) and (ignGear = 0), adderror(1, "Control gear failure!"));
if ((getbit(gearStatus, 1) = 1) and (ignLamp = 0), adderror(2, "Lamp failure!"));
Inizializzazione
var x := 0; var rx := 0;
# QUERY STATUS 0x90: every reply byte proves the gear is present; 0x8000 = no answer, 0x20FF = bus collision
# an unread answer left in the gateway would be taken for this query: read it away and count it
x := modbusr(SH, 511, uint16); if (x != 0x8000, cntStale := cntStale + 1);
modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x90);
sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
x := modbusr(SH, 511, uint16);
cntQ := cntQ + 1; if (x = 0x8000, cntNone := cntNone + 1); if (x = 0x20FF, cntColl := cntColl + 1);
statusSeen := 0;
if x <= 0xFF
    # failure bits a gear reports from its first answer are its permanent state, not an event: shown, not raised
    gearStatus := x;
    ignGear := getbit(x, 0);
    ignLamp := getbit(x, 1);
    statusSeen := 1;
    Status := 0;
else
    Status := RANDINT(1, 60);
end

if Status = 0
    x := modbusr(SH, 511, uint16); if (x != 0x8000, cntStale := cntStale + 1);
    modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA2);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    x := modbusr(SH, 511, uint16);
    cntQ := cntQ + 1; if (x = 0x8000, cntNone := cntNone + 1); if (x = 0x20FF, cntColl := cntColl + 1);
    if (x <= 0xFE, minLevel := x);

    x := modbusr(SH, 511, uint16); if (x != 0x8000, cntStale := cntStale + 1);
    modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA1);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    x := modbusr(SH, 511, uint16);
    cntQ := cntQ + 1; if (x = 0x8000, cntNone := cntNone + 1); if (x = 0x20FF, cntColl := cntColl + 1);
    if (x <= 0xFE, maxLevel := x);
end
Lettura livello
var x := 0; var rx := 0; var y := 0;
if Status = 0
    if minLevel = 0
        # an unread answer left in the gateway would be taken for this query: read it away and count it
        x := modbusr(SH, 511, uint16); if (x != 0x8000, cntStale := cntStale + 1);
        modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA2);
        sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
        x := modbusr(SH, 511, uint16);
        cntQ := cntQ + 1; if (x = 0x8000, cntNone := cntNone + 1); if (x = 0x20FF, cntColl := cntColl + 1);
        if (x <= 0xFE, minLevel := x);
    end
    x := modbusr(SH, 511, uint16); if (x != 0x8000, cntStale := cntStale + 1);
    modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA0);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    x := modbusr(SH, 511, uint16);
    cntQ := cntQ + 1; if (x = 0x8000, cntNone := cntNone + 1); if (x = 0x20FF, cntColl := cntColl + 1);
    if (x != 0x8000 or rx, checkStatus := 60);
    # 0xFF = MASK, 0x20FF = collision, 0x8000 = no answer: keep the last level instead of a phantom value
    if x > 0xFE
        return(Le);
    end
    # an actual level is 0 or between the gear's min and max: anything else is not this gear's answer
    if x > 0 and x < minLevel
        cntBad := cntBad + 1;
        return(Le);
    end
    # a changed level must be read twice the same before it is taken
    if x != lastRaw
        y := modbusr(SH, 511, uint16); if (y != 0x8000, cntStale := cntStale + 1);
        modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA0);
        sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
        y := modbusr(SH, 511, uint16);
        cntQ := cntQ + 1; if (y = 0x8000, cntNone := cntNone + 1); if (y = 0x20FF, cntColl := cntColl + 1);
        if y != x
            cntBad := cntBad + 1;
            return(Le);
        end
        lastRaw := x;
    end
    return(if(x = 0, 0, linear(x, minLevel, 0.01, maxLevel, 1)));
else
    return(NaN);
end
Scrittura livello
var level := 0;
if(Le > 0, level := round(linear(Le, 0.01, minLevel, 1, maxLevel)));
modbusw(SH, 510, uint16, (ShortAddress << 8) + level );
Attributi di servizio
${xml_short_address}
ShortAddress
${xml_device_type}
var x := 0; var y := 0; var rx := 0; var s := ""; var i := 0;
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x99);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    x := modbusr(SH, 511, uint16);
    if (x < 0xFF, return("DT" + x));
    if x = 0xFF
        while i < 8
            modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA7);
            sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
            y := modbusr(SH, 511, uint16);
            if y < 0xFE
                s := if(s = "", "DT" + y, s + ", DT" + y);
                i := i + 1;
            else
                i := 8;
            end
        loop
        return(if(s = "", "MASK", s));
    end
end

return("--")
Physical Min Level
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x9A);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if (x <= 0xFE, return(round((x / 0xFE) * 100) + " %"));
end

return("--")
Max Level
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA1);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if (x <= 0xFE, return(round((x / 0xFE) * 100) + " %"));
end

return("--")
Min Level
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA2);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if (x <= 0xFE, return(round((x / 0xFE) * 100) + " %"));
end

return("--")
Power Up Level
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA3);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if (x <= 0xFE, return(round((x / 0xFE) * 100) + " %"));
end

return("--")
System Failure Level
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA4);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if (x <= 0xFE, return(round((x / 0xFE) * 100) + " %"));
end

return("--")
${xml_groups}
var x := 0; var rx := 0;
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xC0);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var g1 := modbusr(SH, 511, uint16);
    if (g1 > 0xFF, return("--")); 

    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xC1);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var g2 := modbusr(SH, 511, uint16);
    if (g2 > 0xFF, return("--")); 

    var ret := "";

    if (getbit(g1, 0), ret := ret + "0");
    if (getbit(g1, 1), if (ret = "", ret := "1", ret := ret + ",1"));
    if (getbit(g1, 2), if (ret = "", ret := "2", ret := ret + ",2"));
    if (getbit(g1, 3), if (ret = "", ret := "3", ret := ret + ",3"));
    if (getbit(g1, 4), if (ret = "", ret := "4", ret := ret + ",4"));
    if (getbit(g1, 5), if (ret = "", ret := "5", ret := ret + ",5"));
    if (getbit(g1, 6), if (ret = "", ret := "6", ret := ret + ",6"));
    if (getbit(g1, 7), if (ret = "", ret := "7", ret := ret + ",7"));
    if (getbit(g2, 0), if (ret = "", ret := "8", ret := ret + ",8"));
    if (getbit(g2, 1), if (ret = "", ret := "9", ret := ret + ",9"));
    if (getbit(g2, 2), if (ret = "", ret := "10", ret := ret + ",10"));
    if (getbit(g2, 3), if (ret = "", ret := "11", ret := ret + ",11"));
    if (getbit(g2, 4), if (ret = "", ret := "12", ret := ret + ",12"));
    if (getbit(g2, 5), if (ret = "", ret := "13", ret := ret + ",13"));
    if (getbit(g2, 6), if (ret = "", ret := "14", ret := ret + ",14"));
    if (getbit(g2, 7), if (ret = "", ret := "15", ret := ret + ",15"));

    if (ret = "", return("None"), return(ret));
else
    return("--");
end
DALI Status
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x90);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if x <= 0xFF
        var s := "";
        if (getbit(x, 0), s := if(s = "", "gear failure", s + ", gear failure"));
        if (getbit(x, 1), s := if(s = "", "lamp failure", s + ", lamp failure"));
        if (getbit(x, 2), s := if(s = "", "lamp on", s + ", lamp on"));
        if (getbit(x, 3), s := if(s = "", "limit error", s + ", limit error"));
        if (getbit(x, 4), s := if(s = "", "fade running", s + ", fade running"));
        if (getbit(x, 5), s := if(s = "", "reset state", s + ", reset state"));
        if (getbit(x, 6), s := if(s = "", "missing short address", s + ", missing short address"));
        if (getbit(x, 7), s := if(s = "", "power cycle", s + ", power cycle"));
        var ign := if((ignGear = 1) and (ignLamp = 1), "gear and lamp failure", if(ignGear = 1, "gear failure", if(ignLamp = 1, "lamp failure", "")));
        return(if(s = "", "OK", s) + " (0x" + tostring(x, "X2") + ")" + if(ign = "", "", "; not raised: " + ign + " reported since start"));
    end
end

return("--")
Fade
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA5);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if x <= 0xFF
        var t := getbits(x, 4, 4);
        var ret := if(t = 0, "off", t + " (" + round(sqrt(power(2, t)) * 5) / 10 + " s)");
        modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA8);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
        var e := modbusr(SH, 511, uint16);
        if (t = 0 and e <= 0xFF and e != 0, ret := "extended 0x" + tostring(e, "X2"));
        return("fade time " + ret + ", fade rate " + getbits(x, 0, 4));
    end
end

return("--")
DALI Version
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x97);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if x <= 0xFF
        return(if(x >= 8, "DALI-2 " + getbits(x, 2, 6) + "." + getbits(x, 0, 2), "DALI-1") + " (" + x + ")");
    end
end

return("--")
Bus statistics
return("since start: queries " + cntQ + ", stale answers read away " + cntStale + ", no answer " + cntNone + ", collisions " + cntColl + ", rejected levels " + cntBad)
Azioni di servizio
${xml_add_to_group}
Parametri: Group ID (0–15 grp)
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x60 + grp);
${xml_remove_from_group}
Parametri: Group ID (0–15 grp)
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x70 + grp);
${xml_reset_to_default_settings}
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x20);
${xml_set_startup_levels}
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x21);
sleep(10);
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x2c);
sleep(10);
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x2d);
Disable fading
modbusw(SH, 541, uint16, 0xA300);
sleep(100);
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x2E);
sleep(100);
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x30);
Gear 32 Dimmer Lettura e scrittura

Dispositivo di controllo DALI all'indirizzo breve 32 — dimmer TapHome mappato su DALI arc power 0–100 % tramite H:510 LAMP LEVEL (scrittura) e QUERY ACTUAL LEVEL tramite H:511 (lettura), delimitato dai propri MIN / MAX LEVEL del gear.

Registro: H:511 → H:510 UInt16 Unità: % numeric
Attributi di servizio
Indirizzo breveIndirizzo breve DALI (0–63) target di questo dispositivo — fissato al momento dell'importazione del template e utilizzato nel byte alto di ogni scrittura Modbus.
Device TypeByte device-type DALI restituito da QUERY DEVICE TYPE (0x99) — riporta DT0 (fluorescente), DT6 (driver LED), DT8 (colore / tunable white) ecc., o -- quando non c'è risposta.
Physical Min LevelLivello minimo di dimmerazione imposto dall'hardware riportato dal gear — letto da QUERY PHYSICAL MIN LEVEL (0x9A), in percentuale.
Max LevelDALI MAX LEVEL configurato — letto da QUERY MAX LEVEL (0xA1); utilizzato come limite superiore durante la scalatura di TapHome 0–100 % su DALI arc power.
Min LevelDALI MIN LEVEL configurato — letto da QUERY MIN LEVEL (0xA2); utilizzato come limite inferiore durante la scalatura di TapHome 0–100 % su DALI arc power.
Power Up LevelLuminosità ripristinata dopo il ripristino dell'alimentazione del bus DALI — letta da QUERY POWER ON LEVEL (0xA3).
System Failure LevelLuminosità adottata quando il bus DALI perde la comunicazione per più di 500 ms — letta da QUERY SYSTEM FAILURE LEVEL (0xA4).
GruppiElenco separato da virgole dei gruppi DALI (0–15) a cui appartiene il gear — decodificato da QUERY GROUPS 0-7 (0xC0) e QUERY GROUPS 8-15 (0xC1); mostra None o ad es. 0,3,7.
Support Lamp FailureSe la lampada / driver supporta il rilevamento dei guasti della lampada — Yes / No / --. Gestisce l'errore Lamp failure! nel readscript periodico.
Support Power FailureSe la lampada / driver supporta il rilevamento dei guasti di alimentazione — Yes / No / --. Gestisce l'errore Power failure! nel readscript periodico.
DALI Version
Bus statistics
Azioni di servizio
Add to GroupAggiunge questo gear a un gruppo DALI (0–15) tramite ADD TO GROUP (0x60+grp) — auto-ripetuto entro 100 ms come richiesto per i comandi di configurazione DALI.
Remove from GroupRimuove questo gear da un gruppo DALI (0–15) tramite REMOVE FROM GROUP (0x70+grp).
Reset to Default SettingsInvia DALI RESET (0x20) — ripristina ogni parametro NVM del gear (livelli max / min / power-on / system-failure, appartenenza al gruppo, scene) al valore predefinito del produttore.
Set Startup LevelsCattura l'arc power corrente e la memorizza come Power On Level e System Failure Level — sequenza STORE ACTUAL LEVEL IN DTR (0x21) → STORE DTR AS POWER ON LEVEL (0x2C) → STORE DTR AS SYSTEM FAILURE LEVEL (0x2D).
Disable fading

Gear 32

Lettura (modulo)
var x := 0; var rx := 0; var y := 0;
if Status > 0
    Status := Status - 1;
    adderror(3, "Gear not responding!");
    return(0);
end

# checkStatus: ReadLevel resets it while the gear answers; statusPoll: QUERY STATUS at least once per 60 runs
checkStatus := checkStatus - 1;
statusPoll := statusPoll - 1;
if checkStatus < 1 or statusPoll < 1
    # an unread answer left in the gateway would be taken for this query: read it away and count it
    x := modbusr(SH, 511, uint16); if (x != 0x8000, cntStale := cntStale + 1);
    modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x90);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    x := modbusr(SH, 511, uint16);
    cntQ := cntQ + 1; if (x = 0x8000, cntNone := cntNone + 1); if (x = 0x20FF, cntColl := cntColl + 1);
    # a single lost answer happens on DALI: ask once more before declaring the gear missing
    if x = 0x8000
        x := modbusr(SH, 511, uint16); if (x != 0x8000, cntStale := cntStale + 1);
        modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x90);
        sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
        x := modbusr(SH, 511, uint16);
        cntQ := cntQ + 1; if (x = 0x8000, cntNone := cntNone + 1); if (x = 0x20FF, cntColl := cntColl + 1);
    end
    if x <= 0xFF
        # a changed failure bit must be read twice the same before it is taken
        if statusSeen = 1 and getbits(x, 0, 2) != getbits(gearStatus, 0, 2)
            y := modbusr(SH, 511, uint16); if (y != 0x8000, cntStale := cntStale + 1);
            modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x90);
            sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
            y := modbusr(SH, 511, uint16);
            cntQ := cntQ + 1; if (y = 0x8000, cntNone := cntNone + 1); if (y = 0x20FF, cntColl := cntColl + 1);
            if y != x
                cntBad := cntBad + 1;
                x := gearStatus;
            end
        end
        if statusSeen = 0
            ignGear := getbit(x, 0);
            ignLamp := getbit(x, 1);
            statusSeen := 1;
        end
        # a bit that clears ends its ignore, so a later failure is raised
        if (getbit(x, 0) = 0, ignGear := 0);
        if (getbit(x, 1) = 0, ignLamp := 0);
        gearStatus := x;
        checkStatus := 60;
        statusPoll := 60;
    else
        if x = 0x8000
            Status := RANDINT(10, 60);
            adderror(3, "Gear not responding!");
            return(0);
        end
    end
end

# messages last one run only, so they are raised from the stored status on every run
if ((getbit(gearStatus, 0) = 1) and (ignGear = 0), adderror(1, "Control gear failure!"));
if ((getbit(gearStatus, 1) = 1) and (ignLamp = 0), adderror(2, "Lamp failure!"));
Inizializzazione
var x := 0; var rx := 0;
# QUERY STATUS 0x90: every reply byte proves the gear is present; 0x8000 = no answer, 0x20FF = bus collision
# an unread answer left in the gateway would be taken for this query: read it away and count it
x := modbusr(SH, 511, uint16); if (x != 0x8000, cntStale := cntStale + 1);
modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x90);
sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
x := modbusr(SH, 511, uint16);
cntQ := cntQ + 1; if (x = 0x8000, cntNone := cntNone + 1); if (x = 0x20FF, cntColl := cntColl + 1);
statusSeen := 0;
if x <= 0xFF
    # failure bits a gear reports from its first answer are its permanent state, not an event: shown, not raised
    gearStatus := x;
    ignGear := getbit(x, 0);
    ignLamp := getbit(x, 1);
    statusSeen := 1;
    Status := 0;
else
    Status := RANDINT(1, 60);
end

if Status = 0
    x := modbusr(SH, 511, uint16); if (x != 0x8000, cntStale := cntStale + 1);
    modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA2);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    x := modbusr(SH, 511, uint16);
    cntQ := cntQ + 1; if (x = 0x8000, cntNone := cntNone + 1); if (x = 0x20FF, cntColl := cntColl + 1);
    if (x <= 0xFE, minLevel := x);

    x := modbusr(SH, 511, uint16); if (x != 0x8000, cntStale := cntStale + 1);
    modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA1);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    x := modbusr(SH, 511, uint16);
    cntQ := cntQ + 1; if (x = 0x8000, cntNone := cntNone + 1); if (x = 0x20FF, cntColl := cntColl + 1);
    if (x <= 0xFE, maxLevel := x);
end
Lettura livello
var x := 0; var rx := 0; var y := 0;
if Status = 0
    if minLevel = 0
        # an unread answer left in the gateway would be taken for this query: read it away and count it
        x := modbusr(SH, 511, uint16); if (x != 0x8000, cntStale := cntStale + 1);
        modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA2);
        sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
        x := modbusr(SH, 511, uint16);
        cntQ := cntQ + 1; if (x = 0x8000, cntNone := cntNone + 1); if (x = 0x20FF, cntColl := cntColl + 1);
        if (x <= 0xFE, minLevel := x);
    end
    x := modbusr(SH, 511, uint16); if (x != 0x8000, cntStale := cntStale + 1);
    modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA0);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    x := modbusr(SH, 511, uint16);
    cntQ := cntQ + 1; if (x = 0x8000, cntNone := cntNone + 1); if (x = 0x20FF, cntColl := cntColl + 1);
    if (x != 0x8000 or rx, checkStatus := 60);
    # 0xFF = MASK, 0x20FF = collision, 0x8000 = no answer: keep the last level instead of a phantom value
    if x > 0xFE
        return(Le);
    end
    # an actual level is 0 or between the gear's min and max: anything else is not this gear's answer
    if x > 0 and x < minLevel
        cntBad := cntBad + 1;
        return(Le);
    end
    # a changed level must be read twice the same before it is taken
    if x != lastRaw
        y := modbusr(SH, 511, uint16); if (y != 0x8000, cntStale := cntStale + 1);
        modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA0);
        sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
        y := modbusr(SH, 511, uint16);
        cntQ := cntQ + 1; if (y = 0x8000, cntNone := cntNone + 1); if (y = 0x20FF, cntColl := cntColl + 1);
        if y != x
            cntBad := cntBad + 1;
            return(Le);
        end
        lastRaw := x;
    end
    return(if(x = 0, 0, linear(x, minLevel, 0.01, maxLevel, 1)));
else
    return(NaN);
end
Scrittura livello
var level := 0;
if(Le > 0, level := round(linear(Le, 0.01, minLevel, 1, maxLevel)));
modbusw(SH, 510, uint16, (ShortAddress << 8) + level );
Attributi di servizio
${xml_short_address}
ShortAddress
${xml_device_type}
var x := 0; var y := 0; var rx := 0; var s := ""; var i := 0;
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x99);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    x := modbusr(SH, 511, uint16);
    if (x < 0xFF, return("DT" + x));
    if x = 0xFF
        while i < 8
            modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA7);
            sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
            y := modbusr(SH, 511, uint16);
            if y < 0xFE
                s := if(s = "", "DT" + y, s + ", DT" + y);
                i := i + 1;
            else
                i := 8;
            end
        loop
        return(if(s = "", "MASK", s));
    end
end

return("--")
Physical Min Level
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x9A);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if (x <= 0xFE, return(round((x / 0xFE) * 100) + " %"));
end

return("--")
Max Level
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA1);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if (x <= 0xFE, return(round((x / 0xFE) * 100) + " %"));
end

return("--")
Min Level
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA2);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if (x <= 0xFE, return(round((x / 0xFE) * 100) + " %"));
end

return("--")
Power Up Level
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA3);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if (x <= 0xFE, return(round((x / 0xFE) * 100) + " %"));
end

return("--")
System Failure Level
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA4);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if (x <= 0xFE, return(round((x / 0xFE) * 100) + " %"));
end

return("--")
${xml_groups}
var x := 0; var rx := 0;
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xC0);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var g1 := modbusr(SH, 511, uint16);
    if (g1 > 0xFF, return("--")); 

    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xC1);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var g2 := modbusr(SH, 511, uint16);
    if (g2 > 0xFF, return("--")); 

    var ret := "";

    if (getbit(g1, 0), ret := ret + "0");
    if (getbit(g1, 1), if (ret = "", ret := "1", ret := ret + ",1"));
    if (getbit(g1, 2), if (ret = "", ret := "2", ret := ret + ",2"));
    if (getbit(g1, 3), if (ret = "", ret := "3", ret := ret + ",3"));
    if (getbit(g1, 4), if (ret = "", ret := "4", ret := ret + ",4"));
    if (getbit(g1, 5), if (ret = "", ret := "5", ret := ret + ",5"));
    if (getbit(g1, 6), if (ret = "", ret := "6", ret := ret + ",6"));
    if (getbit(g1, 7), if (ret = "", ret := "7", ret := ret + ",7"));
    if (getbit(g2, 0), if (ret = "", ret := "8", ret := ret + ",8"));
    if (getbit(g2, 1), if (ret = "", ret := "9", ret := ret + ",9"));
    if (getbit(g2, 2), if (ret = "", ret := "10", ret := ret + ",10"));
    if (getbit(g2, 3), if (ret = "", ret := "11", ret := ret + ",11"));
    if (getbit(g2, 4), if (ret = "", ret := "12", ret := ret + ",12"));
    if (getbit(g2, 5), if (ret = "", ret := "13", ret := ret + ",13"));
    if (getbit(g2, 6), if (ret = "", ret := "14", ret := ret + ",14"));
    if (getbit(g2, 7), if (ret = "", ret := "15", ret := ret + ",15"));

    if (ret = "", return("None"), return(ret));
else
    return("--");
end
DALI Status
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x90);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if x <= 0xFF
        var s := "";
        if (getbit(x, 0), s := if(s = "", "gear failure", s + ", gear failure"));
        if (getbit(x, 1), s := if(s = "", "lamp failure", s + ", lamp failure"));
        if (getbit(x, 2), s := if(s = "", "lamp on", s + ", lamp on"));
        if (getbit(x, 3), s := if(s = "", "limit error", s + ", limit error"));
        if (getbit(x, 4), s := if(s = "", "fade running", s + ", fade running"));
        if (getbit(x, 5), s := if(s = "", "reset state", s + ", reset state"));
        if (getbit(x, 6), s := if(s = "", "missing short address", s + ", missing short address"));
        if (getbit(x, 7), s := if(s = "", "power cycle", s + ", power cycle"));
        var ign := if((ignGear = 1) and (ignLamp = 1), "gear and lamp failure", if(ignGear = 1, "gear failure", if(ignLamp = 1, "lamp failure", "")));
        return(if(s = "", "OK", s) + " (0x" + tostring(x, "X2") + ")" + if(ign = "", "", "; not raised: " + ign + " reported since start"));
    end
end

return("--")
Fade
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA5);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if x <= 0xFF
        var t := getbits(x, 4, 4);
        var ret := if(t = 0, "off", t + " (" + round(sqrt(power(2, t)) * 5) / 10 + " s)");
        modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA8);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
        var e := modbusr(SH, 511, uint16);
        if (t = 0 and e <= 0xFF and e != 0, ret := "extended 0x" + tostring(e, "X2"));
        return("fade time " + ret + ", fade rate " + getbits(x, 0, 4));
    end
end

return("--")
DALI Version
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x97);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if x <= 0xFF
        return(if(x >= 8, "DALI-2 " + getbits(x, 2, 6) + "." + getbits(x, 0, 2), "DALI-1") + " (" + x + ")");
    end
end

return("--")
Bus statistics
return("since start: queries " + cntQ + ", stale answers read away " + cntStale + ", no answer " + cntNone + ", collisions " + cntColl + ", rejected levels " + cntBad)
Azioni di servizio
${xml_add_to_group}
Parametri: Group ID (0–15 grp)
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x60 + grp);
${xml_remove_from_group}
Parametri: Group ID (0–15 grp)
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x70 + grp);
${xml_reset_to_default_settings}
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x20);
${xml_set_startup_levels}
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x21);
sleep(10);
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x2c);
sleep(10);
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x2d);
Disable fading
modbusw(SH, 541, uint16, 0xA300);
sleep(100);
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x2E);
sleep(100);
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x30);
Gear 33 Dimmer Lettura e scrittura

Dispositivo di controllo DALI all'indirizzo breve 33 — dimmer TapHome mappato su DALI arc power 0–100 % tramite H:510 LAMP LEVEL (scrittura) e QUERY ACTUAL LEVEL tramite H:511 (lettura), delimitato dai propri MIN / MAX LEVEL del gear.

Registro: H:511 → H:510 UInt16 Unità: % numeric
Attributi di servizio
Indirizzo breveIndirizzo breve DALI (0–63) target di questo dispositivo — fissato al momento dell'importazione del template e utilizzato nel byte alto di ogni scrittura Modbus.
Device TypeByte device-type DALI restituito da QUERY DEVICE TYPE (0x99) — riporta DT0 (fluorescente), DT6 (driver LED), DT8 (colore / tunable white) ecc., o -- quando non c'è risposta.
Physical Min LevelLivello minimo di dimmerazione imposto dall'hardware riportato dal gear — letto da QUERY PHYSICAL MIN LEVEL (0x9A), in percentuale.
Max LevelDALI MAX LEVEL configurato — letto da QUERY MAX LEVEL (0xA1); utilizzato come limite superiore durante la scalatura di TapHome 0–100 % su DALI arc power.
Min LevelDALI MIN LEVEL configurato — letto da QUERY MIN LEVEL (0xA2); utilizzato come limite inferiore durante la scalatura di TapHome 0–100 % su DALI arc power.
Power Up LevelLuminosità ripristinata dopo il ripristino dell'alimentazione del bus DALI — letta da QUERY POWER ON LEVEL (0xA3).
System Failure LevelLuminosità adottata quando il bus DALI perde la comunicazione per più di 500 ms — letta da QUERY SYSTEM FAILURE LEVEL (0xA4).
GruppiElenco separato da virgole dei gruppi DALI (0–15) a cui appartiene il gear — decodificato da QUERY GROUPS 0-7 (0xC0) e QUERY GROUPS 8-15 (0xC1); mostra None o ad es. 0,3,7.
Support Lamp FailureSe la lampada / driver supporta il rilevamento dei guasti della lampada — Yes / No / --. Gestisce l'errore Lamp failure! nel readscript periodico.
Support Power FailureSe la lampada / driver supporta il rilevamento dei guasti di alimentazione — Yes / No / --. Gestisce l'errore Power failure! nel readscript periodico.
DALI Version
Bus statistics
Azioni di servizio
Add to GroupAggiunge questo gear a un gruppo DALI (0–15) tramite ADD TO GROUP (0x60+grp) — auto-ripetuto entro 100 ms come richiesto per i comandi di configurazione DALI.
Remove from GroupRimuove questo gear da un gruppo DALI (0–15) tramite REMOVE FROM GROUP (0x70+grp).
Reset to Default SettingsInvia DALI RESET (0x20) — ripristina ogni parametro NVM del gear (livelli max / min / power-on / system-failure, appartenenza al gruppo, scene) al valore predefinito del produttore.
Set Startup LevelsCattura l'arc power corrente e la memorizza come Power On Level e System Failure Level — sequenza STORE ACTUAL LEVEL IN DTR (0x21) → STORE DTR AS POWER ON LEVEL (0x2C) → STORE DTR AS SYSTEM FAILURE LEVEL (0x2D).
Disable fading

Gear 33

Lettura (modulo)
var x := 0; var rx := 0; var y := 0;
if Status > 0
    Status := Status - 1;
    adderror(3, "Gear not responding!");
    return(0);
end

# checkStatus: ReadLevel resets it while the gear answers; statusPoll: QUERY STATUS at least once per 60 runs
checkStatus := checkStatus - 1;
statusPoll := statusPoll - 1;
if checkStatus < 1 or statusPoll < 1
    # an unread answer left in the gateway would be taken for this query: read it away and count it
    x := modbusr(SH, 511, uint16); if (x != 0x8000, cntStale := cntStale + 1);
    modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x90);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    x := modbusr(SH, 511, uint16);
    cntQ := cntQ + 1; if (x = 0x8000, cntNone := cntNone + 1); if (x = 0x20FF, cntColl := cntColl + 1);
    # a single lost answer happens on DALI: ask once more before declaring the gear missing
    if x = 0x8000
        x := modbusr(SH, 511, uint16); if (x != 0x8000, cntStale := cntStale + 1);
        modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x90);
        sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
        x := modbusr(SH, 511, uint16);
        cntQ := cntQ + 1; if (x = 0x8000, cntNone := cntNone + 1); if (x = 0x20FF, cntColl := cntColl + 1);
    end
    if x <= 0xFF
        # a changed failure bit must be read twice the same before it is taken
        if statusSeen = 1 and getbits(x, 0, 2) != getbits(gearStatus, 0, 2)
            y := modbusr(SH, 511, uint16); if (y != 0x8000, cntStale := cntStale + 1);
            modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x90);
            sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
            y := modbusr(SH, 511, uint16);
            cntQ := cntQ + 1; if (y = 0x8000, cntNone := cntNone + 1); if (y = 0x20FF, cntColl := cntColl + 1);
            if y != x
                cntBad := cntBad + 1;
                x := gearStatus;
            end
        end
        if statusSeen = 0
            ignGear := getbit(x, 0);
            ignLamp := getbit(x, 1);
            statusSeen := 1;
        end
        # a bit that clears ends its ignore, so a later failure is raised
        if (getbit(x, 0) = 0, ignGear := 0);
        if (getbit(x, 1) = 0, ignLamp := 0);
        gearStatus := x;
        checkStatus := 60;
        statusPoll := 60;
    else
        if x = 0x8000
            Status := RANDINT(10, 60);
            adderror(3, "Gear not responding!");
            return(0);
        end
    end
end

# messages last one run only, so they are raised from the stored status on every run
if ((getbit(gearStatus, 0) = 1) and (ignGear = 0), adderror(1, "Control gear failure!"));
if ((getbit(gearStatus, 1) = 1) and (ignLamp = 0), adderror(2, "Lamp failure!"));
Inizializzazione
var x := 0; var rx := 0;
# QUERY STATUS 0x90: every reply byte proves the gear is present; 0x8000 = no answer, 0x20FF = bus collision
# an unread answer left in the gateway would be taken for this query: read it away and count it
x := modbusr(SH, 511, uint16); if (x != 0x8000, cntStale := cntStale + 1);
modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x90);
sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
x := modbusr(SH, 511, uint16);
cntQ := cntQ + 1; if (x = 0x8000, cntNone := cntNone + 1); if (x = 0x20FF, cntColl := cntColl + 1);
statusSeen := 0;
if x <= 0xFF
    # failure bits a gear reports from its first answer are its permanent state, not an event: shown, not raised
    gearStatus := x;
    ignGear := getbit(x, 0);
    ignLamp := getbit(x, 1);
    statusSeen := 1;
    Status := 0;
else
    Status := RANDINT(1, 60);
end

if Status = 0
    x := modbusr(SH, 511, uint16); if (x != 0x8000, cntStale := cntStale + 1);
    modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA2);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    x := modbusr(SH, 511, uint16);
    cntQ := cntQ + 1; if (x = 0x8000, cntNone := cntNone + 1); if (x = 0x20FF, cntColl := cntColl + 1);
    if (x <= 0xFE, minLevel := x);

    x := modbusr(SH, 511, uint16); if (x != 0x8000, cntStale := cntStale + 1);
    modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA1);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    x := modbusr(SH, 511, uint16);
    cntQ := cntQ + 1; if (x = 0x8000, cntNone := cntNone + 1); if (x = 0x20FF, cntColl := cntColl + 1);
    if (x <= 0xFE, maxLevel := x);
end
Lettura livello
var x := 0; var rx := 0; var y := 0;
if Status = 0
    if minLevel = 0
        # an unread answer left in the gateway would be taken for this query: read it away and count it
        x := modbusr(SH, 511, uint16); if (x != 0x8000, cntStale := cntStale + 1);
        modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA2);
        sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
        x := modbusr(SH, 511, uint16);
        cntQ := cntQ + 1; if (x = 0x8000, cntNone := cntNone + 1); if (x = 0x20FF, cntColl := cntColl + 1);
        if (x <= 0xFE, minLevel := x);
    end
    x := modbusr(SH, 511, uint16); if (x != 0x8000, cntStale := cntStale + 1);
    modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA0);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    x := modbusr(SH, 511, uint16);
    cntQ := cntQ + 1; if (x = 0x8000, cntNone := cntNone + 1); if (x = 0x20FF, cntColl := cntColl + 1);
    if (x != 0x8000 or rx, checkStatus := 60);
    # 0xFF = MASK, 0x20FF = collision, 0x8000 = no answer: keep the last level instead of a phantom value
    if x > 0xFE
        return(Le);
    end
    # an actual level is 0 or between the gear's min and max: anything else is not this gear's answer
    if x > 0 and x < minLevel
        cntBad := cntBad + 1;
        return(Le);
    end
    # a changed level must be read twice the same before it is taken
    if x != lastRaw
        y := modbusr(SH, 511, uint16); if (y != 0x8000, cntStale := cntStale + 1);
        modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA0);
        sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
        y := modbusr(SH, 511, uint16);
        cntQ := cntQ + 1; if (y = 0x8000, cntNone := cntNone + 1); if (y = 0x20FF, cntColl := cntColl + 1);
        if y != x
            cntBad := cntBad + 1;
            return(Le);
        end
        lastRaw := x;
    end
    return(if(x = 0, 0, linear(x, minLevel, 0.01, maxLevel, 1)));
else
    return(NaN);
end
Scrittura livello
var level := 0;
if(Le > 0, level := round(linear(Le, 0.01, minLevel, 1, maxLevel)));
modbusw(SH, 510, uint16, (ShortAddress << 8) + level );
Attributi di servizio
${xml_short_address}
ShortAddress
${xml_device_type}
var x := 0; var y := 0; var rx := 0; var s := ""; var i := 0;
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x99);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    x := modbusr(SH, 511, uint16);
    if (x < 0xFF, return("DT" + x));
    if x = 0xFF
        while i < 8
            modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA7);
            sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
            y := modbusr(SH, 511, uint16);
            if y < 0xFE
                s := if(s = "", "DT" + y, s + ", DT" + y);
                i := i + 1;
            else
                i := 8;
            end
        loop
        return(if(s = "", "MASK", s));
    end
end

return("--")
Physical Min Level
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x9A);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if (x <= 0xFE, return(round((x / 0xFE) * 100) + " %"));
end

return("--")
Max Level
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA1);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if (x <= 0xFE, return(round((x / 0xFE) * 100) + " %"));
end

return("--")
Min Level
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA2);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if (x <= 0xFE, return(round((x / 0xFE) * 100) + " %"));
end

return("--")
Power Up Level
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA3);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if (x <= 0xFE, return(round((x / 0xFE) * 100) + " %"));
end

return("--")
System Failure Level
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA4);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if (x <= 0xFE, return(round((x / 0xFE) * 100) + " %"));
end

return("--")
${xml_groups}
var x := 0; var rx := 0;
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xC0);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var g1 := modbusr(SH, 511, uint16);
    if (g1 > 0xFF, return("--")); 

    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xC1);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var g2 := modbusr(SH, 511, uint16);
    if (g2 > 0xFF, return("--")); 

    var ret := "";

    if (getbit(g1, 0), ret := ret + "0");
    if (getbit(g1, 1), if (ret = "", ret := "1", ret := ret + ",1"));
    if (getbit(g1, 2), if (ret = "", ret := "2", ret := ret + ",2"));
    if (getbit(g1, 3), if (ret = "", ret := "3", ret := ret + ",3"));
    if (getbit(g1, 4), if (ret = "", ret := "4", ret := ret + ",4"));
    if (getbit(g1, 5), if (ret = "", ret := "5", ret := ret + ",5"));
    if (getbit(g1, 6), if (ret = "", ret := "6", ret := ret + ",6"));
    if (getbit(g1, 7), if (ret = "", ret := "7", ret := ret + ",7"));
    if (getbit(g2, 0), if (ret = "", ret := "8", ret := ret + ",8"));
    if (getbit(g2, 1), if (ret = "", ret := "9", ret := ret + ",9"));
    if (getbit(g2, 2), if (ret = "", ret := "10", ret := ret + ",10"));
    if (getbit(g2, 3), if (ret = "", ret := "11", ret := ret + ",11"));
    if (getbit(g2, 4), if (ret = "", ret := "12", ret := ret + ",12"));
    if (getbit(g2, 5), if (ret = "", ret := "13", ret := ret + ",13"));
    if (getbit(g2, 6), if (ret = "", ret := "14", ret := ret + ",14"));
    if (getbit(g2, 7), if (ret = "", ret := "15", ret := ret + ",15"));

    if (ret = "", return("None"), return(ret));
else
    return("--");
end
DALI Status
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x90);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if x <= 0xFF
        var s := "";
        if (getbit(x, 0), s := if(s = "", "gear failure", s + ", gear failure"));
        if (getbit(x, 1), s := if(s = "", "lamp failure", s + ", lamp failure"));
        if (getbit(x, 2), s := if(s = "", "lamp on", s + ", lamp on"));
        if (getbit(x, 3), s := if(s = "", "limit error", s + ", limit error"));
        if (getbit(x, 4), s := if(s = "", "fade running", s + ", fade running"));
        if (getbit(x, 5), s := if(s = "", "reset state", s + ", reset state"));
        if (getbit(x, 6), s := if(s = "", "missing short address", s + ", missing short address"));
        if (getbit(x, 7), s := if(s = "", "power cycle", s + ", power cycle"));
        var ign := if((ignGear = 1) and (ignLamp = 1), "gear and lamp failure", if(ignGear = 1, "gear failure", if(ignLamp = 1, "lamp failure", "")));
        return(if(s = "", "OK", s) + " (0x" + tostring(x, "X2") + ")" + if(ign = "", "", "; not raised: " + ign + " reported since start"));
    end
end

return("--")
Fade
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA5);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if x <= 0xFF
        var t := getbits(x, 4, 4);
        var ret := if(t = 0, "off", t + " (" + round(sqrt(power(2, t)) * 5) / 10 + " s)");
        modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA8);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
        var e := modbusr(SH, 511, uint16);
        if (t = 0 and e <= 0xFF and e != 0, ret := "extended 0x" + tostring(e, "X2"));
        return("fade time " + ret + ", fade rate " + getbits(x, 0, 4));
    end
end

return("--")
DALI Version
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x97);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if x <= 0xFF
        return(if(x >= 8, "DALI-2 " + getbits(x, 2, 6) + "." + getbits(x, 0, 2), "DALI-1") + " (" + x + ")");
    end
end

return("--")
Bus statistics
return("since start: queries " + cntQ + ", stale answers read away " + cntStale + ", no answer " + cntNone + ", collisions " + cntColl + ", rejected levels " + cntBad)
Azioni di servizio
${xml_add_to_group}
Parametri: Group ID (0–15 grp)
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x60 + grp);
${xml_remove_from_group}
Parametri: Group ID (0–15 grp)
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x70 + grp);
${xml_reset_to_default_settings}
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x20);
${xml_set_startup_levels}
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x21);
sleep(10);
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x2c);
sleep(10);
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x2d);
Disable fading
modbusw(SH, 541, uint16, 0xA300);
sleep(100);
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x2E);
sleep(100);
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x30);
Gear 34 Dimmer Lettura e scrittura

Dispositivo di controllo DALI all'indirizzo breve 34 — dimmer TapHome mappato su DALI arc power 0–100 % tramite H:510 LAMP LEVEL (scrittura) e QUERY ACTUAL LEVEL tramite H:511 (lettura), delimitato dai propri MIN / MAX LEVEL del gear.

Registro: H:511 → H:510 UInt16 Unità: % numeric
Attributi di servizio
Indirizzo breveIndirizzo breve DALI (0–63) target di questo dispositivo — fissato al momento dell'importazione del template e utilizzato nel byte alto di ogni scrittura Modbus.
Device TypeByte device-type DALI restituito da QUERY DEVICE TYPE (0x99) — riporta DT0 (fluorescente), DT6 (driver LED), DT8 (colore / tunable white) ecc., o -- quando non c'è risposta.
Physical Min LevelLivello minimo di dimmerazione imposto dall'hardware riportato dal gear — letto da QUERY PHYSICAL MIN LEVEL (0x9A), in percentuale.
Max LevelDALI MAX LEVEL configurato — letto da QUERY MAX LEVEL (0xA1); utilizzato come limite superiore durante la scalatura di TapHome 0–100 % su DALI arc power.
Min LevelDALI MIN LEVEL configurato — letto da QUERY MIN LEVEL (0xA2); utilizzato come limite inferiore durante la scalatura di TapHome 0–100 % su DALI arc power.
Power Up LevelLuminosità ripristinata dopo il ripristino dell'alimentazione del bus DALI — letta da QUERY POWER ON LEVEL (0xA3).
System Failure LevelLuminosità adottata quando il bus DALI perde la comunicazione per più di 500 ms — letta da QUERY SYSTEM FAILURE LEVEL (0xA4).
GruppiElenco separato da virgole dei gruppi DALI (0–15) a cui appartiene il gear — decodificato da QUERY GROUPS 0-7 (0xC0) e QUERY GROUPS 8-15 (0xC1); mostra None o ad es. 0,3,7.
Support Lamp FailureSe la lampada / driver supporta il rilevamento dei guasti della lampada — Yes / No / --. Gestisce l'errore Lamp failure! nel readscript periodico.
Support Power FailureSe la lampada / driver supporta il rilevamento dei guasti di alimentazione — Yes / No / --. Gestisce l'errore Power failure! nel readscript periodico.
DALI Version
Bus statistics
Azioni di servizio
Add to GroupAggiunge questo gear a un gruppo DALI (0–15) tramite ADD TO GROUP (0x60+grp) — auto-ripetuto entro 100 ms come richiesto per i comandi di configurazione DALI.
Remove from GroupRimuove questo gear da un gruppo DALI (0–15) tramite REMOVE FROM GROUP (0x70+grp).
Reset to Default SettingsInvia DALI RESET (0x20) — ripristina ogni parametro NVM del gear (livelli max / min / power-on / system-failure, appartenenza al gruppo, scene) al valore predefinito del produttore.
Set Startup LevelsCattura l'arc power corrente e la memorizza come Power On Level e System Failure Level — sequenza STORE ACTUAL LEVEL IN DTR (0x21) → STORE DTR AS POWER ON LEVEL (0x2C) → STORE DTR AS SYSTEM FAILURE LEVEL (0x2D).
Disable fading

Gear 34

Lettura (modulo)
var x := 0; var rx := 0; var y := 0;
if Status > 0
    Status := Status - 1;
    adderror(3, "Gear not responding!");
    return(0);
end

# checkStatus: ReadLevel resets it while the gear answers; statusPoll: QUERY STATUS at least once per 60 runs
checkStatus := checkStatus - 1;
statusPoll := statusPoll - 1;
if checkStatus < 1 or statusPoll < 1
    # an unread answer left in the gateway would be taken for this query: read it away and count it
    x := modbusr(SH, 511, uint16); if (x != 0x8000, cntStale := cntStale + 1);
    modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x90);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    x := modbusr(SH, 511, uint16);
    cntQ := cntQ + 1; if (x = 0x8000, cntNone := cntNone + 1); if (x = 0x20FF, cntColl := cntColl + 1);
    # a single lost answer happens on DALI: ask once more before declaring the gear missing
    if x = 0x8000
        x := modbusr(SH, 511, uint16); if (x != 0x8000, cntStale := cntStale + 1);
        modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x90);
        sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
        x := modbusr(SH, 511, uint16);
        cntQ := cntQ + 1; if (x = 0x8000, cntNone := cntNone + 1); if (x = 0x20FF, cntColl := cntColl + 1);
    end
    if x <= 0xFF
        # a changed failure bit must be read twice the same before it is taken
        if statusSeen = 1 and getbits(x, 0, 2) != getbits(gearStatus, 0, 2)
            y := modbusr(SH, 511, uint16); if (y != 0x8000, cntStale := cntStale + 1);
            modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x90);
            sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
            y := modbusr(SH, 511, uint16);
            cntQ := cntQ + 1; if (y = 0x8000, cntNone := cntNone + 1); if (y = 0x20FF, cntColl := cntColl + 1);
            if y != x
                cntBad := cntBad + 1;
                x := gearStatus;
            end
        end
        if statusSeen = 0
            ignGear := getbit(x, 0);
            ignLamp := getbit(x, 1);
            statusSeen := 1;
        end
        # a bit that clears ends its ignore, so a later failure is raised
        if (getbit(x, 0) = 0, ignGear := 0);
        if (getbit(x, 1) = 0, ignLamp := 0);
        gearStatus := x;
        checkStatus := 60;
        statusPoll := 60;
    else
        if x = 0x8000
            Status := RANDINT(10, 60);
            adderror(3, "Gear not responding!");
            return(0);
        end
    end
end

# messages last one run only, so they are raised from the stored status on every run
if ((getbit(gearStatus, 0) = 1) and (ignGear = 0), adderror(1, "Control gear failure!"));
if ((getbit(gearStatus, 1) = 1) and (ignLamp = 0), adderror(2, "Lamp failure!"));
Inizializzazione
var x := 0; var rx := 0;
# QUERY STATUS 0x90: every reply byte proves the gear is present; 0x8000 = no answer, 0x20FF = bus collision
# an unread answer left in the gateway would be taken for this query: read it away and count it
x := modbusr(SH, 511, uint16); if (x != 0x8000, cntStale := cntStale + 1);
modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x90);
sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
x := modbusr(SH, 511, uint16);
cntQ := cntQ + 1; if (x = 0x8000, cntNone := cntNone + 1); if (x = 0x20FF, cntColl := cntColl + 1);
statusSeen := 0;
if x <= 0xFF
    # failure bits a gear reports from its first answer are its permanent state, not an event: shown, not raised
    gearStatus := x;
    ignGear := getbit(x, 0);
    ignLamp := getbit(x, 1);
    statusSeen := 1;
    Status := 0;
else
    Status := RANDINT(1, 60);
end

if Status = 0
    x := modbusr(SH, 511, uint16); if (x != 0x8000, cntStale := cntStale + 1);
    modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA2);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    x := modbusr(SH, 511, uint16);
    cntQ := cntQ + 1; if (x = 0x8000, cntNone := cntNone + 1); if (x = 0x20FF, cntColl := cntColl + 1);
    if (x <= 0xFE, minLevel := x);

    x := modbusr(SH, 511, uint16); if (x != 0x8000, cntStale := cntStale + 1);
    modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA1);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    x := modbusr(SH, 511, uint16);
    cntQ := cntQ + 1; if (x = 0x8000, cntNone := cntNone + 1); if (x = 0x20FF, cntColl := cntColl + 1);
    if (x <= 0xFE, maxLevel := x);
end
Lettura livello
var x := 0; var rx := 0; var y := 0;
if Status = 0
    if minLevel = 0
        # an unread answer left in the gateway would be taken for this query: read it away and count it
        x := modbusr(SH, 511, uint16); if (x != 0x8000, cntStale := cntStale + 1);
        modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA2);
        sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
        x := modbusr(SH, 511, uint16);
        cntQ := cntQ + 1; if (x = 0x8000, cntNone := cntNone + 1); if (x = 0x20FF, cntColl := cntColl + 1);
        if (x <= 0xFE, minLevel := x);
    end
    x := modbusr(SH, 511, uint16); if (x != 0x8000, cntStale := cntStale + 1);
    modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA0);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    x := modbusr(SH, 511, uint16);
    cntQ := cntQ + 1; if (x = 0x8000, cntNone := cntNone + 1); if (x = 0x20FF, cntColl := cntColl + 1);
    if (x != 0x8000 or rx, checkStatus := 60);
    # 0xFF = MASK, 0x20FF = collision, 0x8000 = no answer: keep the last level instead of a phantom value
    if x > 0xFE
        return(Le);
    end
    # an actual level is 0 or between the gear's min and max: anything else is not this gear's answer
    if x > 0 and x < minLevel
        cntBad := cntBad + 1;
        return(Le);
    end
    # a changed level must be read twice the same before it is taken
    if x != lastRaw
        y := modbusr(SH, 511, uint16); if (y != 0x8000, cntStale := cntStale + 1);
        modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA0);
        sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
        y := modbusr(SH, 511, uint16);
        cntQ := cntQ + 1; if (y = 0x8000, cntNone := cntNone + 1); if (y = 0x20FF, cntColl := cntColl + 1);
        if y != x
            cntBad := cntBad + 1;
            return(Le);
        end
        lastRaw := x;
    end
    return(if(x = 0, 0, linear(x, minLevel, 0.01, maxLevel, 1)));
else
    return(NaN);
end
Scrittura livello
var level := 0;
if(Le > 0, level := round(linear(Le, 0.01, minLevel, 1, maxLevel)));
modbusw(SH, 510, uint16, (ShortAddress << 8) + level );
Attributi di servizio
${xml_short_address}
ShortAddress
${xml_device_type}
var x := 0; var y := 0; var rx := 0; var s := ""; var i := 0;
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x99);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    x := modbusr(SH, 511, uint16);
    if (x < 0xFF, return("DT" + x));
    if x = 0xFF
        while i < 8
            modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA7);
            sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
            y := modbusr(SH, 511, uint16);
            if y < 0xFE
                s := if(s = "", "DT" + y, s + ", DT" + y);
                i := i + 1;
            else
                i := 8;
            end
        loop
        return(if(s = "", "MASK", s));
    end
end

return("--")
Physical Min Level
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x9A);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if (x <= 0xFE, return(round((x / 0xFE) * 100) + " %"));
end

return("--")
Max Level
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA1);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if (x <= 0xFE, return(round((x / 0xFE) * 100) + " %"));
end

return("--")
Min Level
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA2);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if (x <= 0xFE, return(round((x / 0xFE) * 100) + " %"));
end

return("--")
Power Up Level
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA3);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if (x <= 0xFE, return(round((x / 0xFE) * 100) + " %"));
end

return("--")
System Failure Level
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA4);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if (x <= 0xFE, return(round((x / 0xFE) * 100) + " %"));
end

return("--")
${xml_groups}
var x := 0; var rx := 0;
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xC0);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var g1 := modbusr(SH, 511, uint16);
    if (g1 > 0xFF, return("--")); 

    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xC1);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var g2 := modbusr(SH, 511, uint16);
    if (g2 > 0xFF, return("--")); 

    var ret := "";

    if (getbit(g1, 0), ret := ret + "0");
    if (getbit(g1, 1), if (ret = "", ret := "1", ret := ret + ",1"));
    if (getbit(g1, 2), if (ret = "", ret := "2", ret := ret + ",2"));
    if (getbit(g1, 3), if (ret = "", ret := "3", ret := ret + ",3"));
    if (getbit(g1, 4), if (ret = "", ret := "4", ret := ret + ",4"));
    if (getbit(g1, 5), if (ret = "", ret := "5", ret := ret + ",5"));
    if (getbit(g1, 6), if (ret = "", ret := "6", ret := ret + ",6"));
    if (getbit(g1, 7), if (ret = "", ret := "7", ret := ret + ",7"));
    if (getbit(g2, 0), if (ret = "", ret := "8", ret := ret + ",8"));
    if (getbit(g2, 1), if (ret = "", ret := "9", ret := ret + ",9"));
    if (getbit(g2, 2), if (ret = "", ret := "10", ret := ret + ",10"));
    if (getbit(g2, 3), if (ret = "", ret := "11", ret := ret + ",11"));
    if (getbit(g2, 4), if (ret = "", ret := "12", ret := ret + ",12"));
    if (getbit(g2, 5), if (ret = "", ret := "13", ret := ret + ",13"));
    if (getbit(g2, 6), if (ret = "", ret := "14", ret := ret + ",14"));
    if (getbit(g2, 7), if (ret = "", ret := "15", ret := ret + ",15"));

    if (ret = "", return("None"), return(ret));
else
    return("--");
end
DALI Status
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x90);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if x <= 0xFF
        var s := "";
        if (getbit(x, 0), s := if(s = "", "gear failure", s + ", gear failure"));
        if (getbit(x, 1), s := if(s = "", "lamp failure", s + ", lamp failure"));
        if (getbit(x, 2), s := if(s = "", "lamp on", s + ", lamp on"));
        if (getbit(x, 3), s := if(s = "", "limit error", s + ", limit error"));
        if (getbit(x, 4), s := if(s = "", "fade running", s + ", fade running"));
        if (getbit(x, 5), s := if(s = "", "reset state", s + ", reset state"));
        if (getbit(x, 6), s := if(s = "", "missing short address", s + ", missing short address"));
        if (getbit(x, 7), s := if(s = "", "power cycle", s + ", power cycle"));
        var ign := if((ignGear = 1) and (ignLamp = 1), "gear and lamp failure", if(ignGear = 1, "gear failure", if(ignLamp = 1, "lamp failure", "")));
        return(if(s = "", "OK", s) + " (0x" + tostring(x, "X2") + ")" + if(ign = "", "", "; not raised: " + ign + " reported since start"));
    end
end

return("--")
Fade
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA5);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if x <= 0xFF
        var t := getbits(x, 4, 4);
        var ret := if(t = 0, "off", t + " (" + round(sqrt(power(2, t)) * 5) / 10 + " s)");
        modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA8);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
        var e := modbusr(SH, 511, uint16);
        if (t = 0 and e <= 0xFF and e != 0, ret := "extended 0x" + tostring(e, "X2"));
        return("fade time " + ret + ", fade rate " + getbits(x, 0, 4));
    end
end

return("--")
DALI Version
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x97);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if x <= 0xFF
        return(if(x >= 8, "DALI-2 " + getbits(x, 2, 6) + "." + getbits(x, 0, 2), "DALI-1") + " (" + x + ")");
    end
end

return("--")
Bus statistics
return("since start: queries " + cntQ + ", stale answers read away " + cntStale + ", no answer " + cntNone + ", collisions " + cntColl + ", rejected levels " + cntBad)
Azioni di servizio
${xml_add_to_group}
Parametri: Group ID (0–15 grp)
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x60 + grp);
${xml_remove_from_group}
Parametri: Group ID (0–15 grp)
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x70 + grp);
${xml_reset_to_default_settings}
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x20);
${xml_set_startup_levels}
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x21);
sleep(10);
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x2c);
sleep(10);
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x2d);
Disable fading
modbusw(SH, 541, uint16, 0xA300);
sleep(100);
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x2E);
sleep(100);
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x30);
Gear 35 Dimmer Lettura e scrittura

Dispositivo di controllo DALI all'indirizzo breve 35 — dimmer TapHome mappato su DALI arc power 0–100 % tramite H:510 LAMP LEVEL (scrittura) e QUERY ACTUAL LEVEL tramite H:511 (lettura), delimitato dai propri MIN / MAX LEVEL del gear.

Registro: H:511 → H:510 UInt16 Unità: % numeric
Attributi di servizio
Indirizzo breveIndirizzo breve DALI (0–63) target di questo dispositivo — fissato al momento dell'importazione del template e utilizzato nel byte alto di ogni scrittura Modbus.
Device TypeByte device-type DALI restituito da QUERY DEVICE TYPE (0x99) — riporta DT0 (fluorescente), DT6 (driver LED), DT8 (colore / tunable white) ecc., o -- quando non c'è risposta.
Physical Min LevelLivello minimo di dimmerazione imposto dall'hardware riportato dal gear — letto da QUERY PHYSICAL MIN LEVEL (0x9A), in percentuale.
Max LevelDALI MAX LEVEL configurato — letto da QUERY MAX LEVEL (0xA1); utilizzato come limite superiore durante la scalatura di TapHome 0–100 % su DALI arc power.
Min LevelDALI MIN LEVEL configurato — letto da QUERY MIN LEVEL (0xA2); utilizzato come limite inferiore durante la scalatura di TapHome 0–100 % su DALI arc power.
Power Up LevelLuminosità ripristinata dopo il ripristino dell'alimentazione del bus DALI — letta da QUERY POWER ON LEVEL (0xA3).
System Failure LevelLuminosità adottata quando il bus DALI perde la comunicazione per più di 500 ms — letta da QUERY SYSTEM FAILURE LEVEL (0xA4).
GruppiElenco separato da virgole dei gruppi DALI (0–15) a cui appartiene il gear — decodificato da QUERY GROUPS 0-7 (0xC0) e QUERY GROUPS 8-15 (0xC1); mostra None o ad es. 0,3,7.
Support Lamp FailureSe la lampada / driver supporta il rilevamento dei guasti della lampada — Yes / No / --. Gestisce l'errore Lamp failure! nel readscript periodico.
Support Power FailureSe la lampada / driver supporta il rilevamento dei guasti di alimentazione — Yes / No / --. Gestisce l'errore Power failure! nel readscript periodico.
DALI Version
Bus statistics
Azioni di servizio
Add to GroupAggiunge questo gear a un gruppo DALI (0–15) tramite ADD TO GROUP (0x60+grp) — auto-ripetuto entro 100 ms come richiesto per i comandi di configurazione DALI.
Remove from GroupRimuove questo gear da un gruppo DALI (0–15) tramite REMOVE FROM GROUP (0x70+grp).
Reset to Default SettingsInvia DALI RESET (0x20) — ripristina ogni parametro NVM del gear (livelli max / min / power-on / system-failure, appartenenza al gruppo, scene) al valore predefinito del produttore.
Set Startup LevelsCattura l'arc power corrente e la memorizza come Power On Level e System Failure Level — sequenza STORE ACTUAL LEVEL IN DTR (0x21) → STORE DTR AS POWER ON LEVEL (0x2C) → STORE DTR AS SYSTEM FAILURE LEVEL (0x2D).
Disable fading

Gear 35

Lettura (modulo)
var x := 0; var rx := 0; var y := 0;
if Status > 0
    Status := Status - 1;
    adderror(3, "Gear not responding!");
    return(0);
end

# checkStatus: ReadLevel resets it while the gear answers; statusPoll: QUERY STATUS at least once per 60 runs
checkStatus := checkStatus - 1;
statusPoll := statusPoll - 1;
if checkStatus < 1 or statusPoll < 1
    # an unread answer left in the gateway would be taken for this query: read it away and count it
    x := modbusr(SH, 511, uint16); if (x != 0x8000, cntStale := cntStale + 1);
    modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x90);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    x := modbusr(SH, 511, uint16);
    cntQ := cntQ + 1; if (x = 0x8000, cntNone := cntNone + 1); if (x = 0x20FF, cntColl := cntColl + 1);
    # a single lost answer happens on DALI: ask once more before declaring the gear missing
    if x = 0x8000
        x := modbusr(SH, 511, uint16); if (x != 0x8000, cntStale := cntStale + 1);
        modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x90);
        sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
        x := modbusr(SH, 511, uint16);
        cntQ := cntQ + 1; if (x = 0x8000, cntNone := cntNone + 1); if (x = 0x20FF, cntColl := cntColl + 1);
    end
    if x <= 0xFF
        # a changed failure bit must be read twice the same before it is taken
        if statusSeen = 1 and getbits(x, 0, 2) != getbits(gearStatus, 0, 2)
            y := modbusr(SH, 511, uint16); if (y != 0x8000, cntStale := cntStale + 1);
            modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x90);
            sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
            y := modbusr(SH, 511, uint16);
            cntQ := cntQ + 1; if (y = 0x8000, cntNone := cntNone + 1); if (y = 0x20FF, cntColl := cntColl + 1);
            if y != x
                cntBad := cntBad + 1;
                x := gearStatus;
            end
        end
        if statusSeen = 0
            ignGear := getbit(x, 0);
            ignLamp := getbit(x, 1);
            statusSeen := 1;
        end
        # a bit that clears ends its ignore, so a later failure is raised
        if (getbit(x, 0) = 0, ignGear := 0);
        if (getbit(x, 1) = 0, ignLamp := 0);
        gearStatus := x;
        checkStatus := 60;
        statusPoll := 60;
    else
        if x = 0x8000
            Status := RANDINT(10, 60);
            adderror(3, "Gear not responding!");
            return(0);
        end
    end
end

# messages last one run only, so they are raised from the stored status on every run
if ((getbit(gearStatus, 0) = 1) and (ignGear = 0), adderror(1, "Control gear failure!"));
if ((getbit(gearStatus, 1) = 1) and (ignLamp = 0), adderror(2, "Lamp failure!"));
Inizializzazione
var x := 0; var rx := 0;
# QUERY STATUS 0x90: every reply byte proves the gear is present; 0x8000 = no answer, 0x20FF = bus collision
# an unread answer left in the gateway would be taken for this query: read it away and count it
x := modbusr(SH, 511, uint16); if (x != 0x8000, cntStale := cntStale + 1);
modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x90);
sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
x := modbusr(SH, 511, uint16);
cntQ := cntQ + 1; if (x = 0x8000, cntNone := cntNone + 1); if (x = 0x20FF, cntColl := cntColl + 1);
statusSeen := 0;
if x <= 0xFF
    # failure bits a gear reports from its first answer are its permanent state, not an event: shown, not raised
    gearStatus := x;
    ignGear := getbit(x, 0);
    ignLamp := getbit(x, 1);
    statusSeen := 1;
    Status := 0;
else
    Status := RANDINT(1, 60);
end

if Status = 0
    x := modbusr(SH, 511, uint16); if (x != 0x8000, cntStale := cntStale + 1);
    modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA2);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    x := modbusr(SH, 511, uint16);
    cntQ := cntQ + 1; if (x = 0x8000, cntNone := cntNone + 1); if (x = 0x20FF, cntColl := cntColl + 1);
    if (x <= 0xFE, minLevel := x);

    x := modbusr(SH, 511, uint16); if (x != 0x8000, cntStale := cntStale + 1);
    modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA1);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    x := modbusr(SH, 511, uint16);
    cntQ := cntQ + 1; if (x = 0x8000, cntNone := cntNone + 1); if (x = 0x20FF, cntColl := cntColl + 1);
    if (x <= 0xFE, maxLevel := x);
end
Lettura livello
var x := 0; var rx := 0; var y := 0;
if Status = 0
    if minLevel = 0
        # an unread answer left in the gateway would be taken for this query: read it away and count it
        x := modbusr(SH, 511, uint16); if (x != 0x8000, cntStale := cntStale + 1);
        modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA2);
        sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
        x := modbusr(SH, 511, uint16);
        cntQ := cntQ + 1; if (x = 0x8000, cntNone := cntNone + 1); if (x = 0x20FF, cntColl := cntColl + 1);
        if (x <= 0xFE, minLevel := x);
    end
    x := modbusr(SH, 511, uint16); if (x != 0x8000, cntStale := cntStale + 1);
    modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA0);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    x := modbusr(SH, 511, uint16);
    cntQ := cntQ + 1; if (x = 0x8000, cntNone := cntNone + 1); if (x = 0x20FF, cntColl := cntColl + 1);
    if (x != 0x8000 or rx, checkStatus := 60);
    # 0xFF = MASK, 0x20FF = collision, 0x8000 = no answer: keep the last level instead of a phantom value
    if x > 0xFE
        return(Le);
    end
    # an actual level is 0 or between the gear's min and max: anything else is not this gear's answer
    if x > 0 and x < minLevel
        cntBad := cntBad + 1;
        return(Le);
    end
    # a changed level must be read twice the same before it is taken
    if x != lastRaw
        y := modbusr(SH, 511, uint16); if (y != 0x8000, cntStale := cntStale + 1);
        modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA0);
        sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
        y := modbusr(SH, 511, uint16);
        cntQ := cntQ + 1; if (y = 0x8000, cntNone := cntNone + 1); if (y = 0x20FF, cntColl := cntColl + 1);
        if y != x
            cntBad := cntBad + 1;
            return(Le);
        end
        lastRaw := x;
    end
    return(if(x = 0, 0, linear(x, minLevel, 0.01, maxLevel, 1)));
else
    return(NaN);
end
Scrittura livello
var level := 0;
if(Le > 0, level := round(linear(Le, 0.01, minLevel, 1, maxLevel)));
modbusw(SH, 510, uint16, (ShortAddress << 8) + level );
Attributi di servizio
${xml_short_address}
ShortAddress
${xml_device_type}
var x := 0; var y := 0; var rx := 0; var s := ""; var i := 0;
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x99);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    x := modbusr(SH, 511, uint16);
    if (x < 0xFF, return("DT" + x));
    if x = 0xFF
        while i < 8
            modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA7);
            sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
            y := modbusr(SH, 511, uint16);
            if y < 0xFE
                s := if(s = "", "DT" + y, s + ", DT" + y);
                i := i + 1;
            else
                i := 8;
            end
        loop
        return(if(s = "", "MASK", s));
    end
end

return("--")
Physical Min Level
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x9A);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if (x <= 0xFE, return(round((x / 0xFE) * 100) + " %"));
end

return("--")
Max Level
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA1);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if (x <= 0xFE, return(round((x / 0xFE) * 100) + " %"));
end

return("--")
Min Level
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA2);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if (x <= 0xFE, return(round((x / 0xFE) * 100) + " %"));
end

return("--")
Power Up Level
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA3);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if (x <= 0xFE, return(round((x / 0xFE) * 100) + " %"));
end

return("--")
System Failure Level
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA4);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if (x <= 0xFE, return(round((x / 0xFE) * 100) + " %"));
end

return("--")
${xml_groups}
var x := 0; var rx := 0;
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xC0);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var g1 := modbusr(SH, 511, uint16);
    if (g1 > 0xFF, return("--")); 

    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xC1);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var g2 := modbusr(SH, 511, uint16);
    if (g2 > 0xFF, return("--")); 

    var ret := "";

    if (getbit(g1, 0), ret := ret + "0");
    if (getbit(g1, 1), if (ret = "", ret := "1", ret := ret + ",1"));
    if (getbit(g1, 2), if (ret = "", ret := "2", ret := ret + ",2"));
    if (getbit(g1, 3), if (ret = "", ret := "3", ret := ret + ",3"));
    if (getbit(g1, 4), if (ret = "", ret := "4", ret := ret + ",4"));
    if (getbit(g1, 5), if (ret = "", ret := "5", ret := ret + ",5"));
    if (getbit(g1, 6), if (ret = "", ret := "6", ret := ret + ",6"));
    if (getbit(g1, 7), if (ret = "", ret := "7", ret := ret + ",7"));
    if (getbit(g2, 0), if (ret = "", ret := "8", ret := ret + ",8"));
    if (getbit(g2, 1), if (ret = "", ret := "9", ret := ret + ",9"));
    if (getbit(g2, 2), if (ret = "", ret := "10", ret := ret + ",10"));
    if (getbit(g2, 3), if (ret = "", ret := "11", ret := ret + ",11"));
    if (getbit(g2, 4), if (ret = "", ret := "12", ret := ret + ",12"));
    if (getbit(g2, 5), if (ret = "", ret := "13", ret := ret + ",13"));
    if (getbit(g2, 6), if (ret = "", ret := "14", ret := ret + ",14"));
    if (getbit(g2, 7), if (ret = "", ret := "15", ret := ret + ",15"));

    if (ret = "", return("None"), return(ret));
else
    return("--");
end
DALI Status
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x90);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if x <= 0xFF
        var s := "";
        if (getbit(x, 0), s := if(s = "", "gear failure", s + ", gear failure"));
        if (getbit(x, 1), s := if(s = "", "lamp failure", s + ", lamp failure"));
        if (getbit(x, 2), s := if(s = "", "lamp on", s + ", lamp on"));
        if (getbit(x, 3), s := if(s = "", "limit error", s + ", limit error"));
        if (getbit(x, 4), s := if(s = "", "fade running", s + ", fade running"));
        if (getbit(x, 5), s := if(s = "", "reset state", s + ", reset state"));
        if (getbit(x, 6), s := if(s = "", "missing short address", s + ", missing short address"));
        if (getbit(x, 7), s := if(s = "", "power cycle", s + ", power cycle"));
        var ign := if((ignGear = 1) and (ignLamp = 1), "gear and lamp failure", if(ignGear = 1, "gear failure", if(ignLamp = 1, "lamp failure", "")));
        return(if(s = "", "OK", s) + " (0x" + tostring(x, "X2") + ")" + if(ign = "", "", "; not raised: " + ign + " reported since start"));
    end
end

return("--")
Fade
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA5);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if x <= 0xFF
        var t := getbits(x, 4, 4);
        var ret := if(t = 0, "off", t + " (" + round(sqrt(power(2, t)) * 5) / 10 + " s)");
        modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA8);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
        var e := modbusr(SH, 511, uint16);
        if (t = 0 and e <= 0xFF and e != 0, ret := "extended 0x" + tostring(e, "X2"));
        return("fade time " + ret + ", fade rate " + getbits(x, 0, 4));
    end
end

return("--")
DALI Version
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x97);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if x <= 0xFF
        return(if(x >= 8, "DALI-2 " + getbits(x, 2, 6) + "." + getbits(x, 0, 2), "DALI-1") + " (" + x + ")");
    end
end

return("--")
Bus statistics
return("since start: queries " + cntQ + ", stale answers read away " + cntStale + ", no answer " + cntNone + ", collisions " + cntColl + ", rejected levels " + cntBad)
Azioni di servizio
${xml_add_to_group}
Parametri: Group ID (0–15 grp)
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x60 + grp);
${xml_remove_from_group}
Parametri: Group ID (0–15 grp)
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x70 + grp);
${xml_reset_to_default_settings}
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x20);
${xml_set_startup_levels}
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x21);
sleep(10);
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x2c);
sleep(10);
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x2d);
Disable fading
modbusw(SH, 541, uint16, 0xA300);
sleep(100);
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x2E);
sleep(100);
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x30);
Gear 36 Dimmer Lettura e scrittura

Dispositivo di controllo DALI all'indirizzo breve 36 — dimmer TapHome mappato su DALI arc power 0–100 % tramite H:510 LAMP LEVEL (scrittura) e QUERY ACTUAL LEVEL tramite H:511 (lettura), delimitato dai propri MIN / MAX LEVEL del gear.

Registro: H:511 → H:510 UInt16 Unità: % numeric
Attributi di servizio
Indirizzo breveIndirizzo breve DALI (0–63) target di questo dispositivo — fissato al momento dell'importazione del template e utilizzato nel byte alto di ogni scrittura Modbus.
Device TypeByte device-type DALI restituito da QUERY DEVICE TYPE (0x99) — riporta DT0 (fluorescente), DT6 (driver LED), DT8 (colore / tunable white) ecc., o -- quando non c'è risposta.
Physical Min LevelLivello minimo di dimmerazione imposto dall'hardware riportato dal gear — letto da QUERY PHYSICAL MIN LEVEL (0x9A), in percentuale.
Max LevelDALI MAX LEVEL configurato — letto da QUERY MAX LEVEL (0xA1); utilizzato come limite superiore durante la scalatura di TapHome 0–100 % su DALI arc power.
Min LevelDALI MIN LEVEL configurato — letto da QUERY MIN LEVEL (0xA2); utilizzato come limite inferiore durante la scalatura di TapHome 0–100 % su DALI arc power.
Power Up LevelLuminosità ripristinata dopo il ripristino dell'alimentazione del bus DALI — letta da QUERY POWER ON LEVEL (0xA3).
System Failure LevelLuminosità adottata quando il bus DALI perde la comunicazione per più di 500 ms — letta da QUERY SYSTEM FAILURE LEVEL (0xA4).
GruppiElenco separato da virgole dei gruppi DALI (0–15) a cui appartiene il gear — decodificato da QUERY GROUPS 0-7 (0xC0) e QUERY GROUPS 8-15 (0xC1); mostra None o ad es. 0,3,7.
Support Lamp FailureSe la lampada / driver supporta il rilevamento dei guasti della lampada — Yes / No / --. Gestisce l'errore Lamp failure! nel readscript periodico.
Support Power FailureSe la lampada / driver supporta il rilevamento dei guasti di alimentazione — Yes / No / --. Gestisce l'errore Power failure! nel readscript periodico.
DALI Version
Bus statistics
Azioni di servizio
Add to GroupAggiunge questo gear a un gruppo DALI (0–15) tramite ADD TO GROUP (0x60+grp) — auto-ripetuto entro 100 ms come richiesto per i comandi di configurazione DALI.
Remove from GroupRimuove questo gear da un gruppo DALI (0–15) tramite REMOVE FROM GROUP (0x70+grp).
Reset to Default SettingsInvia DALI RESET (0x20) — ripristina ogni parametro NVM del gear (livelli max / min / power-on / system-failure, appartenenza al gruppo, scene) al valore predefinito del produttore.
Set Startup LevelsCattura l'arc power corrente e la memorizza come Power On Level e System Failure Level — sequenza STORE ACTUAL LEVEL IN DTR (0x21) → STORE DTR AS POWER ON LEVEL (0x2C) → STORE DTR AS SYSTEM FAILURE LEVEL (0x2D).
Disable fading

Gear 36

Lettura (modulo)
var x := 0; var rx := 0; var y := 0;
if Status > 0
    Status := Status - 1;
    adderror(3, "Gear not responding!");
    return(0);
end

# checkStatus: ReadLevel resets it while the gear answers; statusPoll: QUERY STATUS at least once per 60 runs
checkStatus := checkStatus - 1;
statusPoll := statusPoll - 1;
if checkStatus < 1 or statusPoll < 1
    # an unread answer left in the gateway would be taken for this query: read it away and count it
    x := modbusr(SH, 511, uint16); if (x != 0x8000, cntStale := cntStale + 1);
    modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x90);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    x := modbusr(SH, 511, uint16);
    cntQ := cntQ + 1; if (x = 0x8000, cntNone := cntNone + 1); if (x = 0x20FF, cntColl := cntColl + 1);
    # a single lost answer happens on DALI: ask once more before declaring the gear missing
    if x = 0x8000
        x := modbusr(SH, 511, uint16); if (x != 0x8000, cntStale := cntStale + 1);
        modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x90);
        sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
        x := modbusr(SH, 511, uint16);
        cntQ := cntQ + 1; if (x = 0x8000, cntNone := cntNone + 1); if (x = 0x20FF, cntColl := cntColl + 1);
    end
    if x <= 0xFF
        # a changed failure bit must be read twice the same before it is taken
        if statusSeen = 1 and getbits(x, 0, 2) != getbits(gearStatus, 0, 2)
            y := modbusr(SH, 511, uint16); if (y != 0x8000, cntStale := cntStale + 1);
            modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x90);
            sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
            y := modbusr(SH, 511, uint16);
            cntQ := cntQ + 1; if (y = 0x8000, cntNone := cntNone + 1); if (y = 0x20FF, cntColl := cntColl + 1);
            if y != x
                cntBad := cntBad + 1;
                x := gearStatus;
            end
        end
        if statusSeen = 0
            ignGear := getbit(x, 0);
            ignLamp := getbit(x, 1);
            statusSeen := 1;
        end
        # a bit that clears ends its ignore, so a later failure is raised
        if (getbit(x, 0) = 0, ignGear := 0);
        if (getbit(x, 1) = 0, ignLamp := 0);
        gearStatus := x;
        checkStatus := 60;
        statusPoll := 60;
    else
        if x = 0x8000
            Status := RANDINT(10, 60);
            adderror(3, "Gear not responding!");
            return(0);
        end
    end
end

# messages last one run only, so they are raised from the stored status on every run
if ((getbit(gearStatus, 0) = 1) and (ignGear = 0), adderror(1, "Control gear failure!"));
if ((getbit(gearStatus, 1) = 1) and (ignLamp = 0), adderror(2, "Lamp failure!"));
Inizializzazione
var x := 0; var rx := 0;
# QUERY STATUS 0x90: every reply byte proves the gear is present; 0x8000 = no answer, 0x20FF = bus collision
# an unread answer left in the gateway would be taken for this query: read it away and count it
x := modbusr(SH, 511, uint16); if (x != 0x8000, cntStale := cntStale + 1);
modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x90);
sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
x := modbusr(SH, 511, uint16);
cntQ := cntQ + 1; if (x = 0x8000, cntNone := cntNone + 1); if (x = 0x20FF, cntColl := cntColl + 1);
statusSeen := 0;
if x <= 0xFF
    # failure bits a gear reports from its first answer are its permanent state, not an event: shown, not raised
    gearStatus := x;
    ignGear := getbit(x, 0);
    ignLamp := getbit(x, 1);
    statusSeen := 1;
    Status := 0;
else
    Status := RANDINT(1, 60);
end

if Status = 0
    x := modbusr(SH, 511, uint16); if (x != 0x8000, cntStale := cntStale + 1);
    modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA2);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    x := modbusr(SH, 511, uint16);
    cntQ := cntQ + 1; if (x = 0x8000, cntNone := cntNone + 1); if (x = 0x20FF, cntColl := cntColl + 1);
    if (x <= 0xFE, minLevel := x);

    x := modbusr(SH, 511, uint16); if (x != 0x8000, cntStale := cntStale + 1);
    modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA1);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    x := modbusr(SH, 511, uint16);
    cntQ := cntQ + 1; if (x = 0x8000, cntNone := cntNone + 1); if (x = 0x20FF, cntColl := cntColl + 1);
    if (x <= 0xFE, maxLevel := x);
end
Lettura livello
var x := 0; var rx := 0; var y := 0;
if Status = 0
    if minLevel = 0
        # an unread answer left in the gateway would be taken for this query: read it away and count it
        x := modbusr(SH, 511, uint16); if (x != 0x8000, cntStale := cntStale + 1);
        modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA2);
        sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
        x := modbusr(SH, 511, uint16);
        cntQ := cntQ + 1; if (x = 0x8000, cntNone := cntNone + 1); if (x = 0x20FF, cntColl := cntColl + 1);
        if (x <= 0xFE, minLevel := x);
    end
    x := modbusr(SH, 511, uint16); if (x != 0x8000, cntStale := cntStale + 1);
    modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA0);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    x := modbusr(SH, 511, uint16);
    cntQ := cntQ + 1; if (x = 0x8000, cntNone := cntNone + 1); if (x = 0x20FF, cntColl := cntColl + 1);
    if (x != 0x8000 or rx, checkStatus := 60);
    # 0xFF = MASK, 0x20FF = collision, 0x8000 = no answer: keep the last level instead of a phantom value
    if x > 0xFE
        return(Le);
    end
    # an actual level is 0 or between the gear's min and max: anything else is not this gear's answer
    if x > 0 and x < minLevel
        cntBad := cntBad + 1;
        return(Le);
    end
    # a changed level must be read twice the same before it is taken
    if x != lastRaw
        y := modbusr(SH, 511, uint16); if (y != 0x8000, cntStale := cntStale + 1);
        modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA0);
        sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
        y := modbusr(SH, 511, uint16);
        cntQ := cntQ + 1; if (y = 0x8000, cntNone := cntNone + 1); if (y = 0x20FF, cntColl := cntColl + 1);
        if y != x
            cntBad := cntBad + 1;
            return(Le);
        end
        lastRaw := x;
    end
    return(if(x = 0, 0, linear(x, minLevel, 0.01, maxLevel, 1)));
else
    return(NaN);
end
Scrittura livello
var level := 0;
if(Le > 0, level := round(linear(Le, 0.01, minLevel, 1, maxLevel)));
modbusw(SH, 510, uint16, (ShortAddress << 8) + level );
Attributi di servizio
${xml_short_address}
ShortAddress
${xml_device_type}
var x := 0; var y := 0; var rx := 0; var s := ""; var i := 0;
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x99);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    x := modbusr(SH, 511, uint16);
    if (x < 0xFF, return("DT" + x));
    if x = 0xFF
        while i < 8
            modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA7);
            sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
            y := modbusr(SH, 511, uint16);
            if y < 0xFE
                s := if(s = "", "DT" + y, s + ", DT" + y);
                i := i + 1;
            else
                i := 8;
            end
        loop
        return(if(s = "", "MASK", s));
    end
end

return("--")
Physical Min Level
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x9A);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if (x <= 0xFE, return(round((x / 0xFE) * 100) + " %"));
end

return("--")
Max Level
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA1);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if (x <= 0xFE, return(round((x / 0xFE) * 100) + " %"));
end

return("--")
Min Level
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA2);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if (x <= 0xFE, return(round((x / 0xFE) * 100) + " %"));
end

return("--")
Power Up Level
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA3);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if (x <= 0xFE, return(round((x / 0xFE) * 100) + " %"));
end

return("--")
System Failure Level
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA4);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if (x <= 0xFE, return(round((x / 0xFE) * 100) + " %"));
end

return("--")
${xml_groups}
var x := 0; var rx := 0;
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xC0);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var g1 := modbusr(SH, 511, uint16);
    if (g1 > 0xFF, return("--")); 

    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xC1);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var g2 := modbusr(SH, 511, uint16);
    if (g2 > 0xFF, return("--")); 

    var ret := "";

    if (getbit(g1, 0), ret := ret + "0");
    if (getbit(g1, 1), if (ret = "", ret := "1", ret := ret + ",1"));
    if (getbit(g1, 2), if (ret = "", ret := "2", ret := ret + ",2"));
    if (getbit(g1, 3), if (ret = "", ret := "3", ret := ret + ",3"));
    if (getbit(g1, 4), if (ret = "", ret := "4", ret := ret + ",4"));
    if (getbit(g1, 5), if (ret = "", ret := "5", ret := ret + ",5"));
    if (getbit(g1, 6), if (ret = "", ret := "6", ret := ret + ",6"));
    if (getbit(g1, 7), if (ret = "", ret := "7", ret := ret + ",7"));
    if (getbit(g2, 0), if (ret = "", ret := "8", ret := ret + ",8"));
    if (getbit(g2, 1), if (ret = "", ret := "9", ret := ret + ",9"));
    if (getbit(g2, 2), if (ret = "", ret := "10", ret := ret + ",10"));
    if (getbit(g2, 3), if (ret = "", ret := "11", ret := ret + ",11"));
    if (getbit(g2, 4), if (ret = "", ret := "12", ret := ret + ",12"));
    if (getbit(g2, 5), if (ret = "", ret := "13", ret := ret + ",13"));
    if (getbit(g2, 6), if (ret = "", ret := "14", ret := ret + ",14"));
    if (getbit(g2, 7), if (ret = "", ret := "15", ret := ret + ",15"));

    if (ret = "", return("None"), return(ret));
else
    return("--");
end
DALI Status
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x90);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if x <= 0xFF
        var s := "";
        if (getbit(x, 0), s := if(s = "", "gear failure", s + ", gear failure"));
        if (getbit(x, 1), s := if(s = "", "lamp failure", s + ", lamp failure"));
        if (getbit(x, 2), s := if(s = "", "lamp on", s + ", lamp on"));
        if (getbit(x, 3), s := if(s = "", "limit error", s + ", limit error"));
        if (getbit(x, 4), s := if(s = "", "fade running", s + ", fade running"));
        if (getbit(x, 5), s := if(s = "", "reset state", s + ", reset state"));
        if (getbit(x, 6), s := if(s = "", "missing short address", s + ", missing short address"));
        if (getbit(x, 7), s := if(s = "", "power cycle", s + ", power cycle"));
        var ign := if((ignGear = 1) and (ignLamp = 1), "gear and lamp failure", if(ignGear = 1, "gear failure", if(ignLamp = 1, "lamp failure", "")));
        return(if(s = "", "OK", s) + " (0x" + tostring(x, "X2") + ")" + if(ign = "", "", "; not raised: " + ign + " reported since start"));
    end
end

return("--")
Fade
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA5);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if x <= 0xFF
        var t := getbits(x, 4, 4);
        var ret := if(t = 0, "off", t + " (" + round(sqrt(power(2, t)) * 5) / 10 + " s)");
        modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA8);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
        var e := modbusr(SH, 511, uint16);
        if (t = 0 and e <= 0xFF and e != 0, ret := "extended 0x" + tostring(e, "X2"));
        return("fade time " + ret + ", fade rate " + getbits(x, 0, 4));
    end
end

return("--")
DALI Version
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x97);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if x <= 0xFF
        return(if(x >= 8, "DALI-2 " + getbits(x, 2, 6) + "." + getbits(x, 0, 2), "DALI-1") + " (" + x + ")");
    end
end

return("--")
Bus statistics
return("since start: queries " + cntQ + ", stale answers read away " + cntStale + ", no answer " + cntNone + ", collisions " + cntColl + ", rejected levels " + cntBad)
Azioni di servizio
${xml_add_to_group}
Parametri: Group ID (0–15 grp)
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x60 + grp);
${xml_remove_from_group}
Parametri: Group ID (0–15 grp)
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x70 + grp);
${xml_reset_to_default_settings}
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x20);
${xml_set_startup_levels}
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x21);
sleep(10);
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x2c);
sleep(10);
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x2d);
Disable fading
modbusw(SH, 541, uint16, 0xA300);
sleep(100);
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x2E);
sleep(100);
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x30);
Gear 37 Dimmer Lettura e scrittura

Dispositivo di controllo DALI all'indirizzo breve 37 — dimmer TapHome mappato su DALI arc power 0–100 % tramite H:510 LAMP LEVEL (scrittura) e QUERY ACTUAL LEVEL tramite H:511 (lettura), delimitato dai propri MIN / MAX LEVEL del gear.

Registro: H:511 → H:510 UInt16 Unità: % numeric
Attributi di servizio
Indirizzo breveIndirizzo breve DALI (0–63) target di questo dispositivo — fissato al momento dell'importazione del template e utilizzato nel byte alto di ogni scrittura Modbus.
Device TypeByte device-type DALI restituito da QUERY DEVICE TYPE (0x99) — riporta DT0 (fluorescente), DT6 (driver LED), DT8 (colore / tunable white) ecc., o -- quando non c'è risposta.
Physical Min LevelLivello minimo di dimmerazione imposto dall'hardware riportato dal gear — letto da QUERY PHYSICAL MIN LEVEL (0x9A), in percentuale.
Max LevelDALI MAX LEVEL configurato — letto da QUERY MAX LEVEL (0xA1); utilizzato come limite superiore durante la scalatura di TapHome 0–100 % su DALI arc power.
Min LevelDALI MIN LEVEL configurato — letto da QUERY MIN LEVEL (0xA2); utilizzato come limite inferiore durante la scalatura di TapHome 0–100 % su DALI arc power.
Power Up LevelLuminosità ripristinata dopo il ripristino dell'alimentazione del bus DALI — letta da QUERY POWER ON LEVEL (0xA3).
System Failure LevelLuminosità adottata quando il bus DALI perde la comunicazione per più di 500 ms — letta da QUERY SYSTEM FAILURE LEVEL (0xA4).
GruppiElenco separato da virgole dei gruppi DALI (0–15) a cui appartiene il gear — decodificato da QUERY GROUPS 0-7 (0xC0) e QUERY GROUPS 8-15 (0xC1); mostra None o ad es. 0,3,7.
Support Lamp FailureSe la lampada / driver supporta il rilevamento dei guasti della lampada — Yes / No / --. Gestisce l'errore Lamp failure! nel readscript periodico.
Support Power FailureSe la lampada / driver supporta il rilevamento dei guasti di alimentazione — Yes / No / --. Gestisce l'errore Power failure! nel readscript periodico.
DALI Version
Bus statistics
Azioni di servizio
Add to GroupAggiunge questo gear a un gruppo DALI (0–15) tramite ADD TO GROUP (0x60+grp) — auto-ripetuto entro 100 ms come richiesto per i comandi di configurazione DALI.
Remove from GroupRimuove questo gear da un gruppo DALI (0–15) tramite REMOVE FROM GROUP (0x70+grp).
Reset to Default SettingsInvia DALI RESET (0x20) — ripristina ogni parametro NVM del gear (livelli max / min / power-on / system-failure, appartenenza al gruppo, scene) al valore predefinito del produttore.
Set Startup LevelsCattura l'arc power corrente e la memorizza come Power On Level e System Failure Level — sequenza STORE ACTUAL LEVEL IN DTR (0x21) → STORE DTR AS POWER ON LEVEL (0x2C) → STORE DTR AS SYSTEM FAILURE LEVEL (0x2D).
Disable fading

Gear 37

Lettura (modulo)
var x := 0; var rx := 0; var y := 0;
if Status > 0
    Status := Status - 1;
    adderror(3, "Gear not responding!");
    return(0);
end

# checkStatus: ReadLevel resets it while the gear answers; statusPoll: QUERY STATUS at least once per 60 runs
checkStatus := checkStatus - 1;
statusPoll := statusPoll - 1;
if checkStatus < 1 or statusPoll < 1
    # an unread answer left in the gateway would be taken for this query: read it away and count it
    x := modbusr(SH, 511, uint16); if (x != 0x8000, cntStale := cntStale + 1);
    modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x90);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    x := modbusr(SH, 511, uint16);
    cntQ := cntQ + 1; if (x = 0x8000, cntNone := cntNone + 1); if (x = 0x20FF, cntColl := cntColl + 1);
    # a single lost answer happens on DALI: ask once more before declaring the gear missing
    if x = 0x8000
        x := modbusr(SH, 511, uint16); if (x != 0x8000, cntStale := cntStale + 1);
        modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x90);
        sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
        x := modbusr(SH, 511, uint16);
        cntQ := cntQ + 1; if (x = 0x8000, cntNone := cntNone + 1); if (x = 0x20FF, cntColl := cntColl + 1);
    end
    if x <= 0xFF
        # a changed failure bit must be read twice the same before it is taken
        if statusSeen = 1 and getbits(x, 0, 2) != getbits(gearStatus, 0, 2)
            y := modbusr(SH, 511, uint16); if (y != 0x8000, cntStale := cntStale + 1);
            modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x90);
            sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
            y := modbusr(SH, 511, uint16);
            cntQ := cntQ + 1; if (y = 0x8000, cntNone := cntNone + 1); if (y = 0x20FF, cntColl := cntColl + 1);
            if y != x
                cntBad := cntBad + 1;
                x := gearStatus;
            end
        end
        if statusSeen = 0
            ignGear := getbit(x, 0);
            ignLamp := getbit(x, 1);
            statusSeen := 1;
        end
        # a bit that clears ends its ignore, so a later failure is raised
        if (getbit(x, 0) = 0, ignGear := 0);
        if (getbit(x, 1) = 0, ignLamp := 0);
        gearStatus := x;
        checkStatus := 60;
        statusPoll := 60;
    else
        if x = 0x8000
            Status := RANDINT(10, 60);
            adderror(3, "Gear not responding!");
            return(0);
        end
    end
end

# messages last one run only, so they are raised from the stored status on every run
if ((getbit(gearStatus, 0) = 1) and (ignGear = 0), adderror(1, "Control gear failure!"));
if ((getbit(gearStatus, 1) = 1) and (ignLamp = 0), adderror(2, "Lamp failure!"));
Inizializzazione
var x := 0; var rx := 0;
# QUERY STATUS 0x90: every reply byte proves the gear is present; 0x8000 = no answer, 0x20FF = bus collision
# an unread answer left in the gateway would be taken for this query: read it away and count it
x := modbusr(SH, 511, uint16); if (x != 0x8000, cntStale := cntStale + 1);
modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x90);
sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
x := modbusr(SH, 511, uint16);
cntQ := cntQ + 1; if (x = 0x8000, cntNone := cntNone + 1); if (x = 0x20FF, cntColl := cntColl + 1);
statusSeen := 0;
if x <= 0xFF
    # failure bits a gear reports from its first answer are its permanent state, not an event: shown, not raised
    gearStatus := x;
    ignGear := getbit(x, 0);
    ignLamp := getbit(x, 1);
    statusSeen := 1;
    Status := 0;
else
    Status := RANDINT(1, 60);
end

if Status = 0
    x := modbusr(SH, 511, uint16); if (x != 0x8000, cntStale := cntStale + 1);
    modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA2);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    x := modbusr(SH, 511, uint16);
    cntQ := cntQ + 1; if (x = 0x8000, cntNone := cntNone + 1); if (x = 0x20FF, cntColl := cntColl + 1);
    if (x <= 0xFE, minLevel := x);

    x := modbusr(SH, 511, uint16); if (x != 0x8000, cntStale := cntStale + 1);
    modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA1);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    x := modbusr(SH, 511, uint16);
    cntQ := cntQ + 1; if (x = 0x8000, cntNone := cntNone + 1); if (x = 0x20FF, cntColl := cntColl + 1);
    if (x <= 0xFE, maxLevel := x);
end
Lettura livello
var x := 0; var rx := 0; var y := 0;
if Status = 0
    if minLevel = 0
        # an unread answer left in the gateway would be taken for this query: read it away and count it
        x := modbusr(SH, 511, uint16); if (x != 0x8000, cntStale := cntStale + 1);
        modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA2);
        sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
        x := modbusr(SH, 511, uint16);
        cntQ := cntQ + 1; if (x = 0x8000, cntNone := cntNone + 1); if (x = 0x20FF, cntColl := cntColl + 1);
        if (x <= 0xFE, minLevel := x);
    end
    x := modbusr(SH, 511, uint16); if (x != 0x8000, cntStale := cntStale + 1);
    modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA0);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    x := modbusr(SH, 511, uint16);
    cntQ := cntQ + 1; if (x = 0x8000, cntNone := cntNone + 1); if (x = 0x20FF, cntColl := cntColl + 1);
    if (x != 0x8000 or rx, checkStatus := 60);
    # 0xFF = MASK, 0x20FF = collision, 0x8000 = no answer: keep the last level instead of a phantom value
    if x > 0xFE
        return(Le);
    end
    # an actual level is 0 or between the gear's min and max: anything else is not this gear's answer
    if x > 0 and x < minLevel
        cntBad := cntBad + 1;
        return(Le);
    end
    # a changed level must be read twice the same before it is taken
    if x != lastRaw
        y := modbusr(SH, 511, uint16); if (y != 0x8000, cntStale := cntStale + 1);
        modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA0);
        sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
        y := modbusr(SH, 511, uint16);
        cntQ := cntQ + 1; if (y = 0x8000, cntNone := cntNone + 1); if (y = 0x20FF, cntColl := cntColl + 1);
        if y != x
            cntBad := cntBad + 1;
            return(Le);
        end
        lastRaw := x;
    end
    return(if(x = 0, 0, linear(x, minLevel, 0.01, maxLevel, 1)));
else
    return(NaN);
end
Scrittura livello
var level := 0;
if(Le > 0, level := round(linear(Le, 0.01, minLevel, 1, maxLevel)));
modbusw(SH, 510, uint16, (ShortAddress << 8) + level );
Attributi di servizio
${xml_short_address}
ShortAddress
${xml_device_type}
var x := 0; var y := 0; var rx := 0; var s := ""; var i := 0;
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x99);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    x := modbusr(SH, 511, uint16);
    if (x < 0xFF, return("DT" + x));
    if x = 0xFF
        while i < 8
            modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA7);
            sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
            y := modbusr(SH, 511, uint16);
            if y < 0xFE
                s := if(s = "", "DT" + y, s + ", DT" + y);
                i := i + 1;
            else
                i := 8;
            end
        loop
        return(if(s = "", "MASK", s));
    end
end

return("--")
Physical Min Level
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x9A);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if (x <= 0xFE, return(round((x / 0xFE) * 100) + " %"));
end

return("--")
Max Level
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA1);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if (x <= 0xFE, return(round((x / 0xFE) * 100) + " %"));
end

return("--")
Min Level
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA2);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if (x <= 0xFE, return(round((x / 0xFE) * 100) + " %"));
end

return("--")
Power Up Level
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA3);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if (x <= 0xFE, return(round((x / 0xFE) * 100) + " %"));
end

return("--")
System Failure Level
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA4);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if (x <= 0xFE, return(round((x / 0xFE) * 100) + " %"));
end

return("--")
${xml_groups}
var x := 0; var rx := 0;
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xC0);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var g1 := modbusr(SH, 511, uint16);
    if (g1 > 0xFF, return("--")); 

    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xC1);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var g2 := modbusr(SH, 511, uint16);
    if (g2 > 0xFF, return("--")); 

    var ret := "";

    if (getbit(g1, 0), ret := ret + "0");
    if (getbit(g1, 1), if (ret = "", ret := "1", ret := ret + ",1"));
    if (getbit(g1, 2), if (ret = "", ret := "2", ret := ret + ",2"));
    if (getbit(g1, 3), if (ret = "", ret := "3", ret := ret + ",3"));
    if (getbit(g1, 4), if (ret = "", ret := "4", ret := ret + ",4"));
    if (getbit(g1, 5), if (ret = "", ret := "5", ret := ret + ",5"));
    if (getbit(g1, 6), if (ret = "", ret := "6", ret := ret + ",6"));
    if (getbit(g1, 7), if (ret = "", ret := "7", ret := ret + ",7"));
    if (getbit(g2, 0), if (ret = "", ret := "8", ret := ret + ",8"));
    if (getbit(g2, 1), if (ret = "", ret := "9", ret := ret + ",9"));
    if (getbit(g2, 2), if (ret = "", ret := "10", ret := ret + ",10"));
    if (getbit(g2, 3), if (ret = "", ret := "11", ret := ret + ",11"));
    if (getbit(g2, 4), if (ret = "", ret := "12", ret := ret + ",12"));
    if (getbit(g2, 5), if (ret = "", ret := "13", ret := ret + ",13"));
    if (getbit(g2, 6), if (ret = "", ret := "14", ret := ret + ",14"));
    if (getbit(g2, 7), if (ret = "", ret := "15", ret := ret + ",15"));

    if (ret = "", return("None"), return(ret));
else
    return("--");
end
DALI Status
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x90);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if x <= 0xFF
        var s := "";
        if (getbit(x, 0), s := if(s = "", "gear failure", s + ", gear failure"));
        if (getbit(x, 1), s := if(s = "", "lamp failure", s + ", lamp failure"));
        if (getbit(x, 2), s := if(s = "", "lamp on", s + ", lamp on"));
        if (getbit(x, 3), s := if(s = "", "limit error", s + ", limit error"));
        if (getbit(x, 4), s := if(s = "", "fade running", s + ", fade running"));
        if (getbit(x, 5), s := if(s = "", "reset state", s + ", reset state"));
        if (getbit(x, 6), s := if(s = "", "missing short address", s + ", missing short address"));
        if (getbit(x, 7), s := if(s = "", "power cycle", s + ", power cycle"));
        var ign := if((ignGear = 1) and (ignLamp = 1), "gear and lamp failure", if(ignGear = 1, "gear failure", if(ignLamp = 1, "lamp failure", "")));
        return(if(s = "", "OK", s) + " (0x" + tostring(x, "X2") + ")" + if(ign = "", "", "; not raised: " + ign + " reported since start"));
    end
end

return("--")
Fade
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA5);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if x <= 0xFF
        var t := getbits(x, 4, 4);
        var ret := if(t = 0, "off", t + " (" + round(sqrt(power(2, t)) * 5) / 10 + " s)");
        modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA8);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
        var e := modbusr(SH, 511, uint16);
        if (t = 0 and e <= 0xFF and e != 0, ret := "extended 0x" + tostring(e, "X2"));
        return("fade time " + ret + ", fade rate " + getbits(x, 0, 4));
    end
end

return("--")
DALI Version
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x97);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if x <= 0xFF
        return(if(x >= 8, "DALI-2 " + getbits(x, 2, 6) + "." + getbits(x, 0, 2), "DALI-1") + " (" + x + ")");
    end
end

return("--")
Bus statistics
return("since start: queries " + cntQ + ", stale answers read away " + cntStale + ", no answer " + cntNone + ", collisions " + cntColl + ", rejected levels " + cntBad)
Azioni di servizio
${xml_add_to_group}
Parametri: Group ID (0–15 grp)
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x60 + grp);
${xml_remove_from_group}
Parametri: Group ID (0–15 grp)
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x70 + grp);
${xml_reset_to_default_settings}
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x20);
${xml_set_startup_levels}
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x21);
sleep(10);
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x2c);
sleep(10);
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x2d);
Disable fading
modbusw(SH, 541, uint16, 0xA300);
sleep(100);
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x2E);
sleep(100);
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x30);
Gear 38 Dimmer Lettura e scrittura

Dispositivo di controllo DALI all'indirizzo breve 38 — dimmer TapHome mappato su DALI arc power 0–100 % tramite H:510 LAMP LEVEL (scrittura) e QUERY ACTUAL LEVEL tramite H:511 (lettura), delimitato dai propri MIN / MAX LEVEL del gear.

Registro: H:511 → H:510 UInt16 Unità: % numeric
Attributi di servizio
Indirizzo breveIndirizzo breve DALI (0–63) target di questo dispositivo — fissato al momento dell'importazione del template e utilizzato nel byte alto di ogni scrittura Modbus.
Device TypeByte device-type DALI restituito da QUERY DEVICE TYPE (0x99) — riporta DT0 (fluorescente), DT6 (driver LED), DT8 (colore / tunable white) ecc., o -- quando non c'è risposta.
Physical Min LevelLivello minimo di dimmerazione imposto dall'hardware riportato dal gear — letto da QUERY PHYSICAL MIN LEVEL (0x9A), in percentuale.
Max LevelDALI MAX LEVEL configurato — letto da QUERY MAX LEVEL (0xA1); utilizzato come limite superiore durante la scalatura di TapHome 0–100 % su DALI arc power.
Min LevelDALI MIN LEVEL configurato — letto da QUERY MIN LEVEL (0xA2); utilizzato come limite inferiore durante la scalatura di TapHome 0–100 % su DALI arc power.
Power Up LevelLuminosità ripristinata dopo il ripristino dell'alimentazione del bus DALI — letta da QUERY POWER ON LEVEL (0xA3).
System Failure LevelLuminosità adottata quando il bus DALI perde la comunicazione per più di 500 ms — letta da QUERY SYSTEM FAILURE LEVEL (0xA4).
GruppiElenco separato da virgole dei gruppi DALI (0–15) a cui appartiene il gear — decodificato da QUERY GROUPS 0-7 (0xC0) e QUERY GROUPS 8-15 (0xC1); mostra None o ad es. 0,3,7.
Support Lamp FailureSe la lampada / driver supporta il rilevamento dei guasti della lampada — Yes / No / --. Gestisce l'errore Lamp failure! nel readscript periodico.
Support Power FailureSe la lampada / driver supporta il rilevamento dei guasti di alimentazione — Yes / No / --. Gestisce l'errore Power failure! nel readscript periodico.
DALI Version
Bus statistics
Azioni di servizio
Add to GroupAggiunge questo gear a un gruppo DALI (0–15) tramite ADD TO GROUP (0x60+grp) — auto-ripetuto entro 100 ms come richiesto per i comandi di configurazione DALI.
Remove from GroupRimuove questo gear da un gruppo DALI (0–15) tramite REMOVE FROM GROUP (0x70+grp).
Reset to Default SettingsInvia DALI RESET (0x20) — ripristina ogni parametro NVM del gear (livelli max / min / power-on / system-failure, appartenenza al gruppo, scene) al valore predefinito del produttore.
Set Startup LevelsCattura l'arc power corrente e la memorizza come Power On Level e System Failure Level — sequenza STORE ACTUAL LEVEL IN DTR (0x21) → STORE DTR AS POWER ON LEVEL (0x2C) → STORE DTR AS SYSTEM FAILURE LEVEL (0x2D).
Disable fading

Gear 38

Lettura (modulo)
var x := 0; var rx := 0; var y := 0;
if Status > 0
    Status := Status - 1;
    adderror(3, "Gear not responding!");
    return(0);
end

# checkStatus: ReadLevel resets it while the gear answers; statusPoll: QUERY STATUS at least once per 60 runs
checkStatus := checkStatus - 1;
statusPoll := statusPoll - 1;
if checkStatus < 1 or statusPoll < 1
    # an unread answer left in the gateway would be taken for this query: read it away and count it
    x := modbusr(SH, 511, uint16); if (x != 0x8000, cntStale := cntStale + 1);
    modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x90);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    x := modbusr(SH, 511, uint16);
    cntQ := cntQ + 1; if (x = 0x8000, cntNone := cntNone + 1); if (x = 0x20FF, cntColl := cntColl + 1);
    # a single lost answer happens on DALI: ask once more before declaring the gear missing
    if x = 0x8000
        x := modbusr(SH, 511, uint16); if (x != 0x8000, cntStale := cntStale + 1);
        modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x90);
        sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
        x := modbusr(SH, 511, uint16);
        cntQ := cntQ + 1; if (x = 0x8000, cntNone := cntNone + 1); if (x = 0x20FF, cntColl := cntColl + 1);
    end
    if x <= 0xFF
        # a changed failure bit must be read twice the same before it is taken
        if statusSeen = 1 and getbits(x, 0, 2) != getbits(gearStatus, 0, 2)
            y := modbusr(SH, 511, uint16); if (y != 0x8000, cntStale := cntStale + 1);
            modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x90);
            sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
            y := modbusr(SH, 511, uint16);
            cntQ := cntQ + 1; if (y = 0x8000, cntNone := cntNone + 1); if (y = 0x20FF, cntColl := cntColl + 1);
            if y != x
                cntBad := cntBad + 1;
                x := gearStatus;
            end
        end
        if statusSeen = 0
            ignGear := getbit(x, 0);
            ignLamp := getbit(x, 1);
            statusSeen := 1;
        end
        # a bit that clears ends its ignore, so a later failure is raised
        if (getbit(x, 0) = 0, ignGear := 0);
        if (getbit(x, 1) = 0, ignLamp := 0);
        gearStatus := x;
        checkStatus := 60;
        statusPoll := 60;
    else
        if x = 0x8000
            Status := RANDINT(10, 60);
            adderror(3, "Gear not responding!");
            return(0);
        end
    end
end

# messages last one run only, so they are raised from the stored status on every run
if ((getbit(gearStatus, 0) = 1) and (ignGear = 0), adderror(1, "Control gear failure!"));
if ((getbit(gearStatus, 1) = 1) and (ignLamp = 0), adderror(2, "Lamp failure!"));
Inizializzazione
var x := 0; var rx := 0;
# QUERY STATUS 0x90: every reply byte proves the gear is present; 0x8000 = no answer, 0x20FF = bus collision
# an unread answer left in the gateway would be taken for this query: read it away and count it
x := modbusr(SH, 511, uint16); if (x != 0x8000, cntStale := cntStale + 1);
modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x90);
sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
x := modbusr(SH, 511, uint16);
cntQ := cntQ + 1; if (x = 0x8000, cntNone := cntNone + 1); if (x = 0x20FF, cntColl := cntColl + 1);
statusSeen := 0;
if x <= 0xFF
    # failure bits a gear reports from its first answer are its permanent state, not an event: shown, not raised
    gearStatus := x;
    ignGear := getbit(x, 0);
    ignLamp := getbit(x, 1);
    statusSeen := 1;
    Status := 0;
else
    Status := RANDINT(1, 60);
end

if Status = 0
    x := modbusr(SH, 511, uint16); if (x != 0x8000, cntStale := cntStale + 1);
    modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA2);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    x := modbusr(SH, 511, uint16);
    cntQ := cntQ + 1; if (x = 0x8000, cntNone := cntNone + 1); if (x = 0x20FF, cntColl := cntColl + 1);
    if (x <= 0xFE, minLevel := x);

    x := modbusr(SH, 511, uint16); if (x != 0x8000, cntStale := cntStale + 1);
    modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA1);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    x := modbusr(SH, 511, uint16);
    cntQ := cntQ + 1; if (x = 0x8000, cntNone := cntNone + 1); if (x = 0x20FF, cntColl := cntColl + 1);
    if (x <= 0xFE, maxLevel := x);
end
Lettura livello
var x := 0; var rx := 0; var y := 0;
if Status = 0
    if minLevel = 0
        # an unread answer left in the gateway would be taken for this query: read it away and count it
        x := modbusr(SH, 511, uint16); if (x != 0x8000, cntStale := cntStale + 1);
        modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA2);
        sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
        x := modbusr(SH, 511, uint16);
        cntQ := cntQ + 1; if (x = 0x8000, cntNone := cntNone + 1); if (x = 0x20FF, cntColl := cntColl + 1);
        if (x <= 0xFE, minLevel := x);
    end
    x := modbusr(SH, 511, uint16); if (x != 0x8000, cntStale := cntStale + 1);
    modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA0);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    x := modbusr(SH, 511, uint16);
    cntQ := cntQ + 1; if (x = 0x8000, cntNone := cntNone + 1); if (x = 0x20FF, cntColl := cntColl + 1);
    if (x != 0x8000 or rx, checkStatus := 60);
    # 0xFF = MASK, 0x20FF = collision, 0x8000 = no answer: keep the last level instead of a phantom value
    if x > 0xFE
        return(Le);
    end
    # an actual level is 0 or between the gear's min and max: anything else is not this gear's answer
    if x > 0 and x < minLevel
        cntBad := cntBad + 1;
        return(Le);
    end
    # a changed level must be read twice the same before it is taken
    if x != lastRaw
        y := modbusr(SH, 511, uint16); if (y != 0x8000, cntStale := cntStale + 1);
        modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA0);
        sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
        y := modbusr(SH, 511, uint16);
        cntQ := cntQ + 1; if (y = 0x8000, cntNone := cntNone + 1); if (y = 0x20FF, cntColl := cntColl + 1);
        if y != x
            cntBad := cntBad + 1;
            return(Le);
        end
        lastRaw := x;
    end
    return(if(x = 0, 0, linear(x, minLevel, 0.01, maxLevel, 1)));
else
    return(NaN);
end
Scrittura livello
var level := 0;
if(Le > 0, level := round(linear(Le, 0.01, minLevel, 1, maxLevel)));
modbusw(SH, 510, uint16, (ShortAddress << 8) + level );
Attributi di servizio
${xml_short_address}
ShortAddress
${xml_device_type}
var x := 0; var y := 0; var rx := 0; var s := ""; var i := 0;
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x99);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    x := modbusr(SH, 511, uint16);
    if (x < 0xFF, return("DT" + x));
    if x = 0xFF
        while i < 8
            modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA7);
            sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
            y := modbusr(SH, 511, uint16);
            if y < 0xFE
                s := if(s = "", "DT" + y, s + ", DT" + y);
                i := i + 1;
            else
                i := 8;
            end
        loop
        return(if(s = "", "MASK", s));
    end
end

return("--")
Physical Min Level
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x9A);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if (x <= 0xFE, return(round((x / 0xFE) * 100) + " %"));
end

return("--")
Max Level
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA1);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if (x <= 0xFE, return(round((x / 0xFE) * 100) + " %"));
end

return("--")
Min Level
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA2);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if (x <= 0xFE, return(round((x / 0xFE) * 100) + " %"));
end

return("--")
Power Up Level
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA3);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if (x <= 0xFE, return(round((x / 0xFE) * 100) + " %"));
end

return("--")
System Failure Level
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA4);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if (x <= 0xFE, return(round((x / 0xFE) * 100) + " %"));
end

return("--")
${xml_groups}
var x := 0; var rx := 0;
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xC0);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var g1 := modbusr(SH, 511, uint16);
    if (g1 > 0xFF, return("--")); 

    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xC1);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var g2 := modbusr(SH, 511, uint16);
    if (g2 > 0xFF, return("--")); 

    var ret := "";

    if (getbit(g1, 0), ret := ret + "0");
    if (getbit(g1, 1), if (ret = "", ret := "1", ret := ret + ",1"));
    if (getbit(g1, 2), if (ret = "", ret := "2", ret := ret + ",2"));
    if (getbit(g1, 3), if (ret = "", ret := "3", ret := ret + ",3"));
    if (getbit(g1, 4), if (ret = "", ret := "4", ret := ret + ",4"));
    if (getbit(g1, 5), if (ret = "", ret := "5", ret := ret + ",5"));
    if (getbit(g1, 6), if (ret = "", ret := "6", ret := ret + ",6"));
    if (getbit(g1, 7), if (ret = "", ret := "7", ret := ret + ",7"));
    if (getbit(g2, 0), if (ret = "", ret := "8", ret := ret + ",8"));
    if (getbit(g2, 1), if (ret = "", ret := "9", ret := ret + ",9"));
    if (getbit(g2, 2), if (ret = "", ret := "10", ret := ret + ",10"));
    if (getbit(g2, 3), if (ret = "", ret := "11", ret := ret + ",11"));
    if (getbit(g2, 4), if (ret = "", ret := "12", ret := ret + ",12"));
    if (getbit(g2, 5), if (ret = "", ret := "13", ret := ret + ",13"));
    if (getbit(g2, 6), if (ret = "", ret := "14", ret := ret + ",14"));
    if (getbit(g2, 7), if (ret = "", ret := "15", ret := ret + ",15"));

    if (ret = "", return("None"), return(ret));
else
    return("--");
end
DALI Status
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x90);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if x <= 0xFF
        var s := "";
        if (getbit(x, 0), s := if(s = "", "gear failure", s + ", gear failure"));
        if (getbit(x, 1), s := if(s = "", "lamp failure", s + ", lamp failure"));
        if (getbit(x, 2), s := if(s = "", "lamp on", s + ", lamp on"));
        if (getbit(x, 3), s := if(s = "", "limit error", s + ", limit error"));
        if (getbit(x, 4), s := if(s = "", "fade running", s + ", fade running"));
        if (getbit(x, 5), s := if(s = "", "reset state", s + ", reset state"));
        if (getbit(x, 6), s := if(s = "", "missing short address", s + ", missing short address"));
        if (getbit(x, 7), s := if(s = "", "power cycle", s + ", power cycle"));
        var ign := if((ignGear = 1) and (ignLamp = 1), "gear and lamp failure", if(ignGear = 1, "gear failure", if(ignLamp = 1, "lamp failure", "")));
        return(if(s = "", "OK", s) + " (0x" + tostring(x, "X2") + ")" + if(ign = "", "", "; not raised: " + ign + " reported since start"));
    end
end

return("--")
Fade
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA5);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if x <= 0xFF
        var t := getbits(x, 4, 4);
        var ret := if(t = 0, "off", t + " (" + round(sqrt(power(2, t)) * 5) / 10 + " s)");
        modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA8);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
        var e := modbusr(SH, 511, uint16);
        if (t = 0 and e <= 0xFF and e != 0, ret := "extended 0x" + tostring(e, "X2"));
        return("fade time " + ret + ", fade rate " + getbits(x, 0, 4));
    end
end

return("--")
DALI Version
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x97);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if x <= 0xFF
        return(if(x >= 8, "DALI-2 " + getbits(x, 2, 6) + "." + getbits(x, 0, 2), "DALI-1") + " (" + x + ")");
    end
end

return("--")
Bus statistics
return("since start: queries " + cntQ + ", stale answers read away " + cntStale + ", no answer " + cntNone + ", collisions " + cntColl + ", rejected levels " + cntBad)
Azioni di servizio
${xml_add_to_group}
Parametri: Group ID (0–15 grp)
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x60 + grp);
${xml_remove_from_group}
Parametri: Group ID (0–15 grp)
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x70 + grp);
${xml_reset_to_default_settings}
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x20);
${xml_set_startup_levels}
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x21);
sleep(10);
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x2c);
sleep(10);
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x2d);
Disable fading
modbusw(SH, 541, uint16, 0xA300);
sleep(100);
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x2E);
sleep(100);
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x30);
Gear 39 Dimmer Lettura e scrittura

Dispositivo di controllo DALI all'indirizzo breve 39 — dimmer TapHome mappato su DALI arc power 0–100 % tramite H:510 LAMP LEVEL (scrittura) e QUERY ACTUAL LEVEL tramite H:511 (lettura), delimitato dai propri MIN / MAX LEVEL del gear.

Registro: H:511 → H:510 UInt16 Unità: % numeric
Attributi di servizio
Indirizzo breveIndirizzo breve DALI (0–63) target di questo dispositivo — fissato al momento dell'importazione del template e utilizzato nel byte alto di ogni scrittura Modbus.
Device TypeByte device-type DALI restituito da QUERY DEVICE TYPE (0x99) — riporta DT0 (fluorescente), DT6 (driver LED), DT8 (colore / tunable white) ecc., o -- quando non c'è risposta.
Physical Min LevelLivello minimo di dimmerazione imposto dall'hardware riportato dal gear — letto da QUERY PHYSICAL MIN LEVEL (0x9A), in percentuale.
Max LevelDALI MAX LEVEL configurato — letto da QUERY MAX LEVEL (0xA1); utilizzato come limite superiore durante la scalatura di TapHome 0–100 % su DALI arc power.
Min LevelDALI MIN LEVEL configurato — letto da QUERY MIN LEVEL (0xA2); utilizzato come limite inferiore durante la scalatura di TapHome 0–100 % su DALI arc power.
Power Up LevelLuminosità ripristinata dopo il ripristino dell'alimentazione del bus DALI — letta da QUERY POWER ON LEVEL (0xA3).
System Failure LevelLuminosità adottata quando il bus DALI perde la comunicazione per più di 500 ms — letta da QUERY SYSTEM FAILURE LEVEL (0xA4).
GruppiElenco separato da virgole dei gruppi DALI (0–15) a cui appartiene il gear — decodificato da QUERY GROUPS 0-7 (0xC0) e QUERY GROUPS 8-15 (0xC1); mostra None o ad es. 0,3,7.
Support Lamp FailureSe la lampada / driver supporta il rilevamento dei guasti della lampada — Yes / No / --. Gestisce l'errore Lamp failure! nel readscript periodico.
Support Power FailureSe la lampada / driver supporta il rilevamento dei guasti di alimentazione — Yes / No / --. Gestisce l'errore Power failure! nel readscript periodico.
DALI Version
Bus statistics
Azioni di servizio
Add to GroupAggiunge questo gear a un gruppo DALI (0–15) tramite ADD TO GROUP (0x60+grp) — auto-ripetuto entro 100 ms come richiesto per i comandi di configurazione DALI.
Remove from GroupRimuove questo gear da un gruppo DALI (0–15) tramite REMOVE FROM GROUP (0x70+grp).
Reset to Default SettingsInvia DALI RESET (0x20) — ripristina ogni parametro NVM del gear (livelli max / min / power-on / system-failure, appartenenza al gruppo, scene) al valore predefinito del produttore.
Set Startup LevelsCattura l'arc power corrente e la memorizza come Power On Level e System Failure Level — sequenza STORE ACTUAL LEVEL IN DTR (0x21) → STORE DTR AS POWER ON LEVEL (0x2C) → STORE DTR AS SYSTEM FAILURE LEVEL (0x2D).
Disable fading

Gear 39

Lettura (modulo)
var x := 0; var rx := 0; var y := 0;
if Status > 0
    Status := Status - 1;
    adderror(3, "Gear not responding!");
    return(0);
end

# checkStatus: ReadLevel resets it while the gear answers; statusPoll: QUERY STATUS at least once per 60 runs
checkStatus := checkStatus - 1;
statusPoll := statusPoll - 1;
if checkStatus < 1 or statusPoll < 1
    # an unread answer left in the gateway would be taken for this query: read it away and count it
    x := modbusr(SH, 511, uint16); if (x != 0x8000, cntStale := cntStale + 1);
    modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x90);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    x := modbusr(SH, 511, uint16);
    cntQ := cntQ + 1; if (x = 0x8000, cntNone := cntNone + 1); if (x = 0x20FF, cntColl := cntColl + 1);
    # a single lost answer happens on DALI: ask once more before declaring the gear missing
    if x = 0x8000
        x := modbusr(SH, 511, uint16); if (x != 0x8000, cntStale := cntStale + 1);
        modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x90);
        sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
        x := modbusr(SH, 511, uint16);
        cntQ := cntQ + 1; if (x = 0x8000, cntNone := cntNone + 1); if (x = 0x20FF, cntColl := cntColl + 1);
    end
    if x <= 0xFF
        # a changed failure bit must be read twice the same before it is taken
        if statusSeen = 1 and getbits(x, 0, 2) != getbits(gearStatus, 0, 2)
            y := modbusr(SH, 511, uint16); if (y != 0x8000, cntStale := cntStale + 1);
            modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x90);
            sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
            y := modbusr(SH, 511, uint16);
            cntQ := cntQ + 1; if (y = 0x8000, cntNone := cntNone + 1); if (y = 0x20FF, cntColl := cntColl + 1);
            if y != x
                cntBad := cntBad + 1;
                x := gearStatus;
            end
        end
        if statusSeen = 0
            ignGear := getbit(x, 0);
            ignLamp := getbit(x, 1);
            statusSeen := 1;
        end
        # a bit that clears ends its ignore, so a later failure is raised
        if (getbit(x, 0) = 0, ignGear := 0);
        if (getbit(x, 1) = 0, ignLamp := 0);
        gearStatus := x;
        checkStatus := 60;
        statusPoll := 60;
    else
        if x = 0x8000
            Status := RANDINT(10, 60);
            adderror(3, "Gear not responding!");
            return(0);
        end
    end
end

# messages last one run only, so they are raised from the stored status on every run
if ((getbit(gearStatus, 0) = 1) and (ignGear = 0), adderror(1, "Control gear failure!"));
if ((getbit(gearStatus, 1) = 1) and (ignLamp = 0), adderror(2, "Lamp failure!"));
Inizializzazione
var x := 0; var rx := 0;
# QUERY STATUS 0x90: every reply byte proves the gear is present; 0x8000 = no answer, 0x20FF = bus collision
# an unread answer left in the gateway would be taken for this query: read it away and count it
x := modbusr(SH, 511, uint16); if (x != 0x8000, cntStale := cntStale + 1);
modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x90);
sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
x := modbusr(SH, 511, uint16);
cntQ := cntQ + 1; if (x = 0x8000, cntNone := cntNone + 1); if (x = 0x20FF, cntColl := cntColl + 1);
statusSeen := 0;
if x <= 0xFF
    # failure bits a gear reports from its first answer are its permanent state, not an event: shown, not raised
    gearStatus := x;
    ignGear := getbit(x, 0);
    ignLamp := getbit(x, 1);
    statusSeen := 1;
    Status := 0;
else
    Status := RANDINT(1, 60);
end

if Status = 0
    x := modbusr(SH, 511, uint16); if (x != 0x8000, cntStale := cntStale + 1);
    modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA2);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    x := modbusr(SH, 511, uint16);
    cntQ := cntQ + 1; if (x = 0x8000, cntNone := cntNone + 1); if (x = 0x20FF, cntColl := cntColl + 1);
    if (x <= 0xFE, minLevel := x);

    x := modbusr(SH, 511, uint16); if (x != 0x8000, cntStale := cntStale + 1);
    modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA1);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    x := modbusr(SH, 511, uint16);
    cntQ := cntQ + 1; if (x = 0x8000, cntNone := cntNone + 1); if (x = 0x20FF, cntColl := cntColl + 1);
    if (x <= 0xFE, maxLevel := x);
end
Lettura livello
var x := 0; var rx := 0; var y := 0;
if Status = 0
    if minLevel = 0
        # an unread answer left in the gateway would be taken for this query: read it away and count it
        x := modbusr(SH, 511, uint16); if (x != 0x8000, cntStale := cntStale + 1);
        modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA2);
        sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
        x := modbusr(SH, 511, uint16);
        cntQ := cntQ + 1; if (x = 0x8000, cntNone := cntNone + 1); if (x = 0x20FF, cntColl := cntColl + 1);
        if (x <= 0xFE, minLevel := x);
    end
    x := modbusr(SH, 511, uint16); if (x != 0x8000, cntStale := cntStale + 1);
    modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA0);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    x := modbusr(SH, 511, uint16);
    cntQ := cntQ + 1; if (x = 0x8000, cntNone := cntNone + 1); if (x = 0x20FF, cntColl := cntColl + 1);
    if (x != 0x8000 or rx, checkStatus := 60);
    # 0xFF = MASK, 0x20FF = collision, 0x8000 = no answer: keep the last level instead of a phantom value
    if x > 0xFE
        return(Le);
    end
    # an actual level is 0 or between the gear's min and max: anything else is not this gear's answer
    if x > 0 and x < minLevel
        cntBad := cntBad + 1;
        return(Le);
    end
    # a changed level must be read twice the same before it is taken
    if x != lastRaw
        y := modbusr(SH, 511, uint16); if (y != 0x8000, cntStale := cntStale + 1);
        modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA0);
        sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
        y := modbusr(SH, 511, uint16);
        cntQ := cntQ + 1; if (y = 0x8000, cntNone := cntNone + 1); if (y = 0x20FF, cntColl := cntColl + 1);
        if y != x
            cntBad := cntBad + 1;
            return(Le);
        end
        lastRaw := x;
    end
    return(if(x = 0, 0, linear(x, minLevel, 0.01, maxLevel, 1)));
else
    return(NaN);
end
Scrittura livello
var level := 0;
if(Le > 0, level := round(linear(Le, 0.01, minLevel, 1, maxLevel)));
modbusw(SH, 510, uint16, (ShortAddress << 8) + level );
Attributi di servizio
${xml_short_address}
ShortAddress
${xml_device_type}
var x := 0; var y := 0; var rx := 0; var s := ""; var i := 0;
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x99);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    x := modbusr(SH, 511, uint16);
    if (x < 0xFF, return("DT" + x));
    if x = 0xFF
        while i < 8
            modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA7);
            sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
            y := modbusr(SH, 511, uint16);
            if y < 0xFE
                s := if(s = "", "DT" + y, s + ", DT" + y);
                i := i + 1;
            else
                i := 8;
            end
        loop
        return(if(s = "", "MASK", s));
    end
end

return("--")
Physical Min Level
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x9A);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if (x <= 0xFE, return(round((x / 0xFE) * 100) + " %"));
end

return("--")
Max Level
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA1);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if (x <= 0xFE, return(round((x / 0xFE) * 100) + " %"));
end

return("--")
Min Level
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA2);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if (x <= 0xFE, return(round((x / 0xFE) * 100) + " %"));
end

return("--")
Power Up Level
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA3);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if (x <= 0xFE, return(round((x / 0xFE) * 100) + " %"));
end

return("--")
System Failure Level
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA4);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if (x <= 0xFE, return(round((x / 0xFE) * 100) + " %"));
end

return("--")
${xml_groups}
var x := 0; var rx := 0;
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xC0);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var g1 := modbusr(SH, 511, uint16);
    if (g1 > 0xFF, return("--")); 

    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xC1);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var g2 := modbusr(SH, 511, uint16);
    if (g2 > 0xFF, return("--")); 

    var ret := "";

    if (getbit(g1, 0), ret := ret + "0");
    if (getbit(g1, 1), if (ret = "", ret := "1", ret := ret + ",1"));
    if (getbit(g1, 2), if (ret = "", ret := "2", ret := ret + ",2"));
    if (getbit(g1, 3), if (ret = "", ret := "3", ret := ret + ",3"));
    if (getbit(g1, 4), if (ret = "", ret := "4", ret := ret + ",4"));
    if (getbit(g1, 5), if (ret = "", ret := "5", ret := ret + ",5"));
    if (getbit(g1, 6), if (ret = "", ret := "6", ret := ret + ",6"));
    if (getbit(g1, 7), if (ret = "", ret := "7", ret := ret + ",7"));
    if (getbit(g2, 0), if (ret = "", ret := "8", ret := ret + ",8"));
    if (getbit(g2, 1), if (ret = "", ret := "9", ret := ret + ",9"));
    if (getbit(g2, 2), if (ret = "", ret := "10", ret := ret + ",10"));
    if (getbit(g2, 3), if (ret = "", ret := "11", ret := ret + ",11"));
    if (getbit(g2, 4), if (ret = "", ret := "12", ret := ret + ",12"));
    if (getbit(g2, 5), if (ret = "", ret := "13", ret := ret + ",13"));
    if (getbit(g2, 6), if (ret = "", ret := "14", ret := ret + ",14"));
    if (getbit(g2, 7), if (ret = "", ret := "15", ret := ret + ",15"));

    if (ret = "", return("None"), return(ret));
else
    return("--");
end
DALI Status
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x90);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if x <= 0xFF
        var s := "";
        if (getbit(x, 0), s := if(s = "", "gear failure", s + ", gear failure"));
        if (getbit(x, 1), s := if(s = "", "lamp failure", s + ", lamp failure"));
        if (getbit(x, 2), s := if(s = "", "lamp on", s + ", lamp on"));
        if (getbit(x, 3), s := if(s = "", "limit error", s + ", limit error"));
        if (getbit(x, 4), s := if(s = "", "fade running", s + ", fade running"));
        if (getbit(x, 5), s := if(s = "", "reset state", s + ", reset state"));
        if (getbit(x, 6), s := if(s = "", "missing short address", s + ", missing short address"));
        if (getbit(x, 7), s := if(s = "", "power cycle", s + ", power cycle"));
        var ign := if((ignGear = 1) and (ignLamp = 1), "gear and lamp failure", if(ignGear = 1, "gear failure", if(ignLamp = 1, "lamp failure", "")));
        return(if(s = "", "OK", s) + " (0x" + tostring(x, "X2") + ")" + if(ign = "", "", "; not raised: " + ign + " reported since start"));
    end
end

return("--")
Fade
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA5);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if x <= 0xFF
        var t := getbits(x, 4, 4);
        var ret := if(t = 0, "off", t + " (" + round(sqrt(power(2, t)) * 5) / 10 + " s)");
        modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA8);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
        var e := modbusr(SH, 511, uint16);
        if (t = 0 and e <= 0xFF and e != 0, ret := "extended 0x" + tostring(e, "X2"));
        return("fade time " + ret + ", fade rate " + getbits(x, 0, 4));
    end
end

return("--")
DALI Version
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x97);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if x <= 0xFF
        return(if(x >= 8, "DALI-2 " + getbits(x, 2, 6) + "." + getbits(x, 0, 2), "DALI-1") + " (" + x + ")");
    end
end

return("--")
Bus statistics
return("since start: queries " + cntQ + ", stale answers read away " + cntStale + ", no answer " + cntNone + ", collisions " + cntColl + ", rejected levels " + cntBad)
Azioni di servizio
${xml_add_to_group}
Parametri: Group ID (0–15 grp)
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x60 + grp);
${xml_remove_from_group}
Parametri: Group ID (0–15 grp)
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x70 + grp);
${xml_reset_to_default_settings}
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x20);
${xml_set_startup_levels}
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x21);
sleep(10);
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x2c);
sleep(10);
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x2d);
Disable fading
modbusw(SH, 541, uint16, 0xA300);
sleep(100);
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x2E);
sleep(100);
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x30);
Gear 40 Dimmer Lettura e scrittura

Dispositivo di controllo DALI all'indirizzo breve 40 — dimmer TapHome mappato su DALI arc power 0–100 % tramite H:510 LAMP LEVEL (scrittura) e QUERY ACTUAL LEVEL tramite H:511 (lettura), delimitato dai propri MIN / MAX LEVEL del gear.

Registro: H:511 → H:510 UInt16 Unità: % numeric
Attributi di servizio
Indirizzo breveIndirizzo breve DALI (0–63) target di questo dispositivo — fissato al momento dell'importazione del template e utilizzato nel byte alto di ogni scrittura Modbus.
Device TypeByte device-type DALI restituito da QUERY DEVICE TYPE (0x99) — riporta DT0 (fluorescente), DT6 (driver LED), DT8 (colore / tunable white) ecc., o -- quando non c'è risposta.
Physical Min LevelLivello minimo di dimmerazione imposto dall'hardware riportato dal gear — letto da QUERY PHYSICAL MIN LEVEL (0x9A), in percentuale.
Max LevelDALI MAX LEVEL configurato — letto da QUERY MAX LEVEL (0xA1); utilizzato come limite superiore durante la scalatura di TapHome 0–100 % su DALI arc power.
Min LevelDALI MIN LEVEL configurato — letto da QUERY MIN LEVEL (0xA2); utilizzato come limite inferiore durante la scalatura di TapHome 0–100 % su DALI arc power.
Power Up LevelLuminosità ripristinata dopo il ripristino dell'alimentazione del bus DALI — letta da QUERY POWER ON LEVEL (0xA3).
System Failure LevelLuminosità adottata quando il bus DALI perde la comunicazione per più di 500 ms — letta da QUERY SYSTEM FAILURE LEVEL (0xA4).
GruppiElenco separato da virgole dei gruppi DALI (0–15) a cui appartiene il gear — decodificato da QUERY GROUPS 0-7 (0xC0) e QUERY GROUPS 8-15 (0xC1); mostra None o ad es. 0,3,7.
Support Lamp FailureSe la lampada / driver supporta il rilevamento dei guasti della lampada — Yes / No / --. Gestisce l'errore Lamp failure! nel readscript periodico.
Support Power FailureSe la lampada / driver supporta il rilevamento dei guasti di alimentazione — Yes / No / --. Gestisce l'errore Power failure! nel readscript periodico.
DALI Version
Bus statistics
Azioni di servizio
Add to GroupAggiunge questo gear a un gruppo DALI (0–15) tramite ADD TO GROUP (0x60+grp) — auto-ripetuto entro 100 ms come richiesto per i comandi di configurazione DALI.
Remove from GroupRimuove questo gear da un gruppo DALI (0–15) tramite REMOVE FROM GROUP (0x70+grp).
Reset to Default SettingsInvia DALI RESET (0x20) — ripristina ogni parametro NVM del gear (livelli max / min / power-on / system-failure, appartenenza al gruppo, scene) al valore predefinito del produttore.
Set Startup LevelsCattura l'arc power corrente e la memorizza come Power On Level e System Failure Level — sequenza STORE ACTUAL LEVEL IN DTR (0x21) → STORE DTR AS POWER ON LEVEL (0x2C) → STORE DTR AS SYSTEM FAILURE LEVEL (0x2D).
Disable fading

Gear 40

Lettura (modulo)
var x := 0; var rx := 0; var y := 0;
if Status > 0
    Status := Status - 1;
    adderror(3, "Gear not responding!");
    return(0);
end

# checkStatus: ReadLevel resets it while the gear answers; statusPoll: QUERY STATUS at least once per 60 runs
checkStatus := checkStatus - 1;
statusPoll := statusPoll - 1;
if checkStatus < 1 or statusPoll < 1
    # an unread answer left in the gateway would be taken for this query: read it away and count it
    x := modbusr(SH, 511, uint16); if (x != 0x8000, cntStale := cntStale + 1);
    modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x90);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    x := modbusr(SH, 511, uint16);
    cntQ := cntQ + 1; if (x = 0x8000, cntNone := cntNone + 1); if (x = 0x20FF, cntColl := cntColl + 1);
    # a single lost answer happens on DALI: ask once more before declaring the gear missing
    if x = 0x8000
        x := modbusr(SH, 511, uint16); if (x != 0x8000, cntStale := cntStale + 1);
        modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x90);
        sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
        x := modbusr(SH, 511, uint16);
        cntQ := cntQ + 1; if (x = 0x8000, cntNone := cntNone + 1); if (x = 0x20FF, cntColl := cntColl + 1);
    end
    if x <= 0xFF
        # a changed failure bit must be read twice the same before it is taken
        if statusSeen = 1 and getbits(x, 0, 2) != getbits(gearStatus, 0, 2)
            y := modbusr(SH, 511, uint16); if (y != 0x8000, cntStale := cntStale + 1);
            modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x90);
            sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
            y := modbusr(SH, 511, uint16);
            cntQ := cntQ + 1; if (y = 0x8000, cntNone := cntNone + 1); if (y = 0x20FF, cntColl := cntColl + 1);
            if y != x
                cntBad := cntBad + 1;
                x := gearStatus;
            end
        end
        if statusSeen = 0
            ignGear := getbit(x, 0);
            ignLamp := getbit(x, 1);
            statusSeen := 1;
        end
        # a bit that clears ends its ignore, so a later failure is raised
        if (getbit(x, 0) = 0, ignGear := 0);
        if (getbit(x, 1) = 0, ignLamp := 0);
        gearStatus := x;
        checkStatus := 60;
        statusPoll := 60;
    else
        if x = 0x8000
            Status := RANDINT(10, 60);
            adderror(3, "Gear not responding!");
            return(0);
        end
    end
end

# messages last one run only, so they are raised from the stored status on every run
if ((getbit(gearStatus, 0) = 1) and (ignGear = 0), adderror(1, "Control gear failure!"));
if ((getbit(gearStatus, 1) = 1) and (ignLamp = 0), adderror(2, "Lamp failure!"));
Inizializzazione
var x := 0; var rx := 0;
# QUERY STATUS 0x90: every reply byte proves the gear is present; 0x8000 = no answer, 0x20FF = bus collision
# an unread answer left in the gateway would be taken for this query: read it away and count it
x := modbusr(SH, 511, uint16); if (x != 0x8000, cntStale := cntStale + 1);
modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x90);
sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
x := modbusr(SH, 511, uint16);
cntQ := cntQ + 1; if (x = 0x8000, cntNone := cntNone + 1); if (x = 0x20FF, cntColl := cntColl + 1);
statusSeen := 0;
if x <= 0xFF
    # failure bits a gear reports from its first answer are its permanent state, not an event: shown, not raised
    gearStatus := x;
    ignGear := getbit(x, 0);
    ignLamp := getbit(x, 1);
    statusSeen := 1;
    Status := 0;
else
    Status := RANDINT(1, 60);
end

if Status = 0
    x := modbusr(SH, 511, uint16); if (x != 0x8000, cntStale := cntStale + 1);
    modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA2);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    x := modbusr(SH, 511, uint16);
    cntQ := cntQ + 1; if (x = 0x8000, cntNone := cntNone + 1); if (x = 0x20FF, cntColl := cntColl + 1);
    if (x <= 0xFE, minLevel := x);

    x := modbusr(SH, 511, uint16); if (x != 0x8000, cntStale := cntStale + 1);
    modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA1);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    x := modbusr(SH, 511, uint16);
    cntQ := cntQ + 1; if (x = 0x8000, cntNone := cntNone + 1); if (x = 0x20FF, cntColl := cntColl + 1);
    if (x <= 0xFE, maxLevel := x);
end
Lettura livello
var x := 0; var rx := 0; var y := 0;
if Status = 0
    if minLevel = 0
        # an unread answer left in the gateway would be taken for this query: read it away and count it
        x := modbusr(SH, 511, uint16); if (x != 0x8000, cntStale := cntStale + 1);
        modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA2);
        sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
        x := modbusr(SH, 511, uint16);
        cntQ := cntQ + 1; if (x = 0x8000, cntNone := cntNone + 1); if (x = 0x20FF, cntColl := cntColl + 1);
        if (x <= 0xFE, minLevel := x);
    end
    x := modbusr(SH, 511, uint16); if (x != 0x8000, cntStale := cntStale + 1);
    modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA0);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    x := modbusr(SH, 511, uint16);
    cntQ := cntQ + 1; if (x = 0x8000, cntNone := cntNone + 1); if (x = 0x20FF, cntColl := cntColl + 1);
    if (x != 0x8000 or rx, checkStatus := 60);
    # 0xFF = MASK, 0x20FF = collision, 0x8000 = no answer: keep the last level instead of a phantom value
    if x > 0xFE
        return(Le);
    end
    # an actual level is 0 or between the gear's min and max: anything else is not this gear's answer
    if x > 0 and x < minLevel
        cntBad := cntBad + 1;
        return(Le);
    end
    # a changed level must be read twice the same before it is taken
    if x != lastRaw
        y := modbusr(SH, 511, uint16); if (y != 0x8000, cntStale := cntStale + 1);
        modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA0);
        sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
        y := modbusr(SH, 511, uint16);
        cntQ := cntQ + 1; if (y = 0x8000, cntNone := cntNone + 1); if (y = 0x20FF, cntColl := cntColl + 1);
        if y != x
            cntBad := cntBad + 1;
            return(Le);
        end
        lastRaw := x;
    end
    return(if(x = 0, 0, linear(x, minLevel, 0.01, maxLevel, 1)));
else
    return(NaN);
end
Scrittura livello
var level := 0;
if(Le > 0, level := round(linear(Le, 0.01, minLevel, 1, maxLevel)));
modbusw(SH, 510, uint16, (ShortAddress << 8) + level );
Attributi di servizio
${xml_short_address}
ShortAddress
${xml_device_type}
var x := 0; var y := 0; var rx := 0; var s := ""; var i := 0;
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x99);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    x := modbusr(SH, 511, uint16);
    if (x < 0xFF, return("DT" + x));
    if x = 0xFF
        while i < 8
            modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA7);
            sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
            y := modbusr(SH, 511, uint16);
            if y < 0xFE
                s := if(s = "", "DT" + y, s + ", DT" + y);
                i := i + 1;
            else
                i := 8;
            end
        loop
        return(if(s = "", "MASK", s));
    end
end

return("--")
Physical Min Level
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x9A);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if (x <= 0xFE, return(round((x / 0xFE) * 100) + " %"));
end

return("--")
Max Level
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA1);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if (x <= 0xFE, return(round((x / 0xFE) * 100) + " %"));
end

return("--")
Min Level
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA2);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if (x <= 0xFE, return(round((x / 0xFE) * 100) + " %"));
end

return("--")
Power Up Level
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA3);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if (x <= 0xFE, return(round((x / 0xFE) * 100) + " %"));
end

return("--")
System Failure Level
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA4);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if (x <= 0xFE, return(round((x / 0xFE) * 100) + " %"));
end

return("--")
${xml_groups}
var x := 0; var rx := 0;
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xC0);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var g1 := modbusr(SH, 511, uint16);
    if (g1 > 0xFF, return("--")); 

    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xC1);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var g2 := modbusr(SH, 511, uint16);
    if (g2 > 0xFF, return("--")); 

    var ret := "";

    if (getbit(g1, 0), ret := ret + "0");
    if (getbit(g1, 1), if (ret = "", ret := "1", ret := ret + ",1"));
    if (getbit(g1, 2), if (ret = "", ret := "2", ret := ret + ",2"));
    if (getbit(g1, 3), if (ret = "", ret := "3", ret := ret + ",3"));
    if (getbit(g1, 4), if (ret = "", ret := "4", ret := ret + ",4"));
    if (getbit(g1, 5), if (ret = "", ret := "5", ret := ret + ",5"));
    if (getbit(g1, 6), if (ret = "", ret := "6", ret := ret + ",6"));
    if (getbit(g1, 7), if (ret = "", ret := "7", ret := ret + ",7"));
    if (getbit(g2, 0), if (ret = "", ret := "8", ret := ret + ",8"));
    if (getbit(g2, 1), if (ret = "", ret := "9", ret := ret + ",9"));
    if (getbit(g2, 2), if (ret = "", ret := "10", ret := ret + ",10"));
    if (getbit(g2, 3), if (ret = "", ret := "11", ret := ret + ",11"));
    if (getbit(g2, 4), if (ret = "", ret := "12", ret := ret + ",12"));
    if (getbit(g2, 5), if (ret = "", ret := "13", ret := ret + ",13"));
    if (getbit(g2, 6), if (ret = "", ret := "14", ret := ret + ",14"));
    if (getbit(g2, 7), if (ret = "", ret := "15", ret := ret + ",15"));

    if (ret = "", return("None"), return(ret));
else
    return("--");
end
DALI Status
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x90);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if x <= 0xFF
        var s := "";
        if (getbit(x, 0), s := if(s = "", "gear failure", s + ", gear failure"));
        if (getbit(x, 1), s := if(s = "", "lamp failure", s + ", lamp failure"));
        if (getbit(x, 2), s := if(s = "", "lamp on", s + ", lamp on"));
        if (getbit(x, 3), s := if(s = "", "limit error", s + ", limit error"));
        if (getbit(x, 4), s := if(s = "", "fade running", s + ", fade running"));
        if (getbit(x, 5), s := if(s = "", "reset state", s + ", reset state"));
        if (getbit(x, 6), s := if(s = "", "missing short address", s + ", missing short address"));
        if (getbit(x, 7), s := if(s = "", "power cycle", s + ", power cycle"));
        var ign := if((ignGear = 1) and (ignLamp = 1), "gear and lamp failure", if(ignGear = 1, "gear failure", if(ignLamp = 1, "lamp failure", "")));
        return(if(s = "", "OK", s) + " (0x" + tostring(x, "X2") + ")" + if(ign = "", "", "; not raised: " + ign + " reported since start"));
    end
end

return("--")
Fade
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA5);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if x <= 0xFF
        var t := getbits(x, 4, 4);
        var ret := if(t = 0, "off", t + " (" + round(sqrt(power(2, t)) * 5) / 10 + " s)");
        modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA8);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
        var e := modbusr(SH, 511, uint16);
        if (t = 0 and e <= 0xFF and e != 0, ret := "extended 0x" + tostring(e, "X2"));
        return("fade time " + ret + ", fade rate " + getbits(x, 0, 4));
    end
end

return("--")
DALI Version
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x97);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if x <= 0xFF
        return(if(x >= 8, "DALI-2 " + getbits(x, 2, 6) + "." + getbits(x, 0, 2), "DALI-1") + " (" + x + ")");
    end
end

return("--")
Bus statistics
return("since start: queries " + cntQ + ", stale answers read away " + cntStale + ", no answer " + cntNone + ", collisions " + cntColl + ", rejected levels " + cntBad)
Azioni di servizio
${xml_add_to_group}
Parametri: Group ID (0–15 grp)
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x60 + grp);
${xml_remove_from_group}
Parametri: Group ID (0–15 grp)
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x70 + grp);
${xml_reset_to_default_settings}
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x20);
${xml_set_startup_levels}
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x21);
sleep(10);
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x2c);
sleep(10);
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x2d);
Disable fading
modbusw(SH, 541, uint16, 0xA300);
sleep(100);
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x2E);
sleep(100);
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x30);
Gear 41 Dimmer Lettura e scrittura

Dispositivo di controllo DALI all'indirizzo breve 41 — dimmer TapHome mappato su DALI arc power 0–100 % tramite H:510 LAMP LEVEL (scrittura) e QUERY ACTUAL LEVEL tramite H:511 (lettura), delimitato dai propri MIN / MAX LEVEL del gear.

Registro: H:511 → H:510 UInt16 Unità: % numeric
Attributi di servizio
Indirizzo breveIndirizzo breve DALI (0–63) target di questo dispositivo — fissato al momento dell'importazione del template e utilizzato nel byte alto di ogni scrittura Modbus.
Device TypeByte device-type DALI restituito da QUERY DEVICE TYPE (0x99) — riporta DT0 (fluorescente), DT6 (driver LED), DT8 (colore / tunable white) ecc., o -- quando non c'è risposta.
Physical Min LevelLivello minimo di dimmerazione imposto dall'hardware riportato dal gear — letto da QUERY PHYSICAL MIN LEVEL (0x9A), in percentuale.
Max LevelDALI MAX LEVEL configurato — letto da QUERY MAX LEVEL (0xA1); utilizzato come limite superiore durante la scalatura di TapHome 0–100 % su DALI arc power.
Min LevelDALI MIN LEVEL configurato — letto da QUERY MIN LEVEL (0xA2); utilizzato come limite inferiore durante la scalatura di TapHome 0–100 % su DALI arc power.
Power Up LevelLuminosità ripristinata dopo il ripristino dell'alimentazione del bus DALI — letta da QUERY POWER ON LEVEL (0xA3).
System Failure LevelLuminosità adottata quando il bus DALI perde la comunicazione per più di 500 ms — letta da QUERY SYSTEM FAILURE LEVEL (0xA4).
GruppiElenco separato da virgole dei gruppi DALI (0–15) a cui appartiene il gear — decodificato da QUERY GROUPS 0-7 (0xC0) e QUERY GROUPS 8-15 (0xC1); mostra None o ad es. 0,3,7.
Support Lamp FailureSe la lampada / driver supporta il rilevamento dei guasti della lampada — Yes / No / --. Gestisce l'errore Lamp failure! nel readscript periodico.
Support Power FailureSe la lampada / driver supporta il rilevamento dei guasti di alimentazione — Yes / No / --. Gestisce l'errore Power failure! nel readscript periodico.
DALI Version
Bus statistics
Azioni di servizio
Add to GroupAggiunge questo gear a un gruppo DALI (0–15) tramite ADD TO GROUP (0x60+grp) — auto-ripetuto entro 100 ms come richiesto per i comandi di configurazione DALI.
Remove from GroupRimuove questo gear da un gruppo DALI (0–15) tramite REMOVE FROM GROUP (0x70+grp).
Reset to Default SettingsInvia DALI RESET (0x20) — ripristina ogni parametro NVM del gear (livelli max / min / power-on / system-failure, appartenenza al gruppo, scene) al valore predefinito del produttore.
Set Startup LevelsCattura l'arc power corrente e la memorizza come Power On Level e System Failure Level — sequenza STORE ACTUAL LEVEL IN DTR (0x21) → STORE DTR AS POWER ON LEVEL (0x2C) → STORE DTR AS SYSTEM FAILURE LEVEL (0x2D).
Disable fading

Gear 41

Lettura (modulo)
var x := 0; var rx := 0; var y := 0;
if Status > 0
    Status := Status - 1;
    adderror(3, "Gear not responding!");
    return(0);
end

# checkStatus: ReadLevel resets it while the gear answers; statusPoll: QUERY STATUS at least once per 60 runs
checkStatus := checkStatus - 1;
statusPoll := statusPoll - 1;
if checkStatus < 1 or statusPoll < 1
    # an unread answer left in the gateway would be taken for this query: read it away and count it
    x := modbusr(SH, 511, uint16); if (x != 0x8000, cntStale := cntStale + 1);
    modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x90);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    x := modbusr(SH, 511, uint16);
    cntQ := cntQ + 1; if (x = 0x8000, cntNone := cntNone + 1); if (x = 0x20FF, cntColl := cntColl + 1);
    # a single lost answer happens on DALI: ask once more before declaring the gear missing
    if x = 0x8000
        x := modbusr(SH, 511, uint16); if (x != 0x8000, cntStale := cntStale + 1);
        modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x90);
        sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
        x := modbusr(SH, 511, uint16);
        cntQ := cntQ + 1; if (x = 0x8000, cntNone := cntNone + 1); if (x = 0x20FF, cntColl := cntColl + 1);
    end
    if x <= 0xFF
        # a changed failure bit must be read twice the same before it is taken
        if statusSeen = 1 and getbits(x, 0, 2) != getbits(gearStatus, 0, 2)
            y := modbusr(SH, 511, uint16); if (y != 0x8000, cntStale := cntStale + 1);
            modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x90);
            sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
            y := modbusr(SH, 511, uint16);
            cntQ := cntQ + 1; if (y = 0x8000, cntNone := cntNone + 1); if (y = 0x20FF, cntColl := cntColl + 1);
            if y != x
                cntBad := cntBad + 1;
                x := gearStatus;
            end
        end
        if statusSeen = 0
            ignGear := getbit(x, 0);
            ignLamp := getbit(x, 1);
            statusSeen := 1;
        end
        # a bit that clears ends its ignore, so a later failure is raised
        if (getbit(x, 0) = 0, ignGear := 0);
        if (getbit(x, 1) = 0, ignLamp := 0);
        gearStatus := x;
        checkStatus := 60;
        statusPoll := 60;
    else
        if x = 0x8000
            Status := RANDINT(10, 60);
            adderror(3, "Gear not responding!");
            return(0);
        end
    end
end

# messages last one run only, so they are raised from the stored status on every run
if ((getbit(gearStatus, 0) = 1) and (ignGear = 0), adderror(1, "Control gear failure!"));
if ((getbit(gearStatus, 1) = 1) and (ignLamp = 0), adderror(2, "Lamp failure!"));
Inizializzazione
var x := 0; var rx := 0;
# QUERY STATUS 0x90: every reply byte proves the gear is present; 0x8000 = no answer, 0x20FF = bus collision
# an unread answer left in the gateway would be taken for this query: read it away and count it
x := modbusr(SH, 511, uint16); if (x != 0x8000, cntStale := cntStale + 1);
modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x90);
sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
x := modbusr(SH, 511, uint16);
cntQ := cntQ + 1; if (x = 0x8000, cntNone := cntNone + 1); if (x = 0x20FF, cntColl := cntColl + 1);
statusSeen := 0;
if x <= 0xFF
    # failure bits a gear reports from its first answer are its permanent state, not an event: shown, not raised
    gearStatus := x;
    ignGear := getbit(x, 0);
    ignLamp := getbit(x, 1);
    statusSeen := 1;
    Status := 0;
else
    Status := RANDINT(1, 60);
end

if Status = 0
    x := modbusr(SH, 511, uint16); if (x != 0x8000, cntStale := cntStale + 1);
    modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA2);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    x := modbusr(SH, 511, uint16);
    cntQ := cntQ + 1; if (x = 0x8000, cntNone := cntNone + 1); if (x = 0x20FF, cntColl := cntColl + 1);
    if (x <= 0xFE, minLevel := x);

    x := modbusr(SH, 511, uint16); if (x != 0x8000, cntStale := cntStale + 1);
    modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA1);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    x := modbusr(SH, 511, uint16);
    cntQ := cntQ + 1; if (x = 0x8000, cntNone := cntNone + 1); if (x = 0x20FF, cntColl := cntColl + 1);
    if (x <= 0xFE, maxLevel := x);
end
Lettura livello
var x := 0; var rx := 0; var y := 0;
if Status = 0
    if minLevel = 0
        # an unread answer left in the gateway would be taken for this query: read it away and count it
        x := modbusr(SH, 511, uint16); if (x != 0x8000, cntStale := cntStale + 1);
        modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA2);
        sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
        x := modbusr(SH, 511, uint16);
        cntQ := cntQ + 1; if (x = 0x8000, cntNone := cntNone + 1); if (x = 0x20FF, cntColl := cntColl + 1);
        if (x <= 0xFE, minLevel := x);
    end
    x := modbusr(SH, 511, uint16); if (x != 0x8000, cntStale := cntStale + 1);
    modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA0);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    x := modbusr(SH, 511, uint16);
    cntQ := cntQ + 1; if (x = 0x8000, cntNone := cntNone + 1); if (x = 0x20FF, cntColl := cntColl + 1);
    if (x != 0x8000 or rx, checkStatus := 60);
    # 0xFF = MASK, 0x20FF = collision, 0x8000 = no answer: keep the last level instead of a phantom value
    if x > 0xFE
        return(Le);
    end
    # an actual level is 0 or between the gear's min and max: anything else is not this gear's answer
    if x > 0 and x < minLevel
        cntBad := cntBad + 1;
        return(Le);
    end
    # a changed level must be read twice the same before it is taken
    if x != lastRaw
        y := modbusr(SH, 511, uint16); if (y != 0x8000, cntStale := cntStale + 1);
        modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA0);
        sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
        y := modbusr(SH, 511, uint16);
        cntQ := cntQ + 1; if (y = 0x8000, cntNone := cntNone + 1); if (y = 0x20FF, cntColl := cntColl + 1);
        if y != x
            cntBad := cntBad + 1;
            return(Le);
        end
        lastRaw := x;
    end
    return(if(x = 0, 0, linear(x, minLevel, 0.01, maxLevel, 1)));
else
    return(NaN);
end
Scrittura livello
var level := 0;
if(Le > 0, level := round(linear(Le, 0.01, minLevel, 1, maxLevel)));
modbusw(SH, 510, uint16, (ShortAddress << 8) + level );
Attributi di servizio
${xml_short_address}
ShortAddress
${xml_device_type}
var x := 0; var y := 0; var rx := 0; var s := ""; var i := 0;
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x99);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    x := modbusr(SH, 511, uint16);
    if (x < 0xFF, return("DT" + x));
    if x = 0xFF
        while i < 8
            modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA7);
            sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
            y := modbusr(SH, 511, uint16);
            if y < 0xFE
                s := if(s = "", "DT" + y, s + ", DT" + y);
                i := i + 1;
            else
                i := 8;
            end
        loop
        return(if(s = "", "MASK", s));
    end
end

return("--")
Physical Min Level
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x9A);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if (x <= 0xFE, return(round((x / 0xFE) * 100) + " %"));
end

return("--")
Max Level
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA1);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if (x <= 0xFE, return(round((x / 0xFE) * 100) + " %"));
end

return("--")
Min Level
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA2);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if (x <= 0xFE, return(round((x / 0xFE) * 100) + " %"));
end

return("--")
Power Up Level
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA3);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if (x <= 0xFE, return(round((x / 0xFE) * 100) + " %"));
end

return("--")
System Failure Level
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA4);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if (x <= 0xFE, return(round((x / 0xFE) * 100) + " %"));
end

return("--")
${xml_groups}
var x := 0; var rx := 0;
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xC0);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var g1 := modbusr(SH, 511, uint16);
    if (g1 > 0xFF, return("--")); 

    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xC1);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var g2 := modbusr(SH, 511, uint16);
    if (g2 > 0xFF, return("--")); 

    var ret := "";

    if (getbit(g1, 0), ret := ret + "0");
    if (getbit(g1, 1), if (ret = "", ret := "1", ret := ret + ",1"));
    if (getbit(g1, 2), if (ret = "", ret := "2", ret := ret + ",2"));
    if (getbit(g1, 3), if (ret = "", ret := "3", ret := ret + ",3"));
    if (getbit(g1, 4), if (ret = "", ret := "4", ret := ret + ",4"));
    if (getbit(g1, 5), if (ret = "", ret := "5", ret := ret + ",5"));
    if (getbit(g1, 6), if (ret = "", ret := "6", ret := ret + ",6"));
    if (getbit(g1, 7), if (ret = "", ret := "7", ret := ret + ",7"));
    if (getbit(g2, 0), if (ret = "", ret := "8", ret := ret + ",8"));
    if (getbit(g2, 1), if (ret = "", ret := "9", ret := ret + ",9"));
    if (getbit(g2, 2), if (ret = "", ret := "10", ret := ret + ",10"));
    if (getbit(g2, 3), if (ret = "", ret := "11", ret := ret + ",11"));
    if (getbit(g2, 4), if (ret = "", ret := "12", ret := ret + ",12"));
    if (getbit(g2, 5), if (ret = "", ret := "13", ret := ret + ",13"));
    if (getbit(g2, 6), if (ret = "", ret := "14", ret := ret + ",14"));
    if (getbit(g2, 7), if (ret = "", ret := "15", ret := ret + ",15"));

    if (ret = "", return("None"), return(ret));
else
    return("--");
end
DALI Status
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x90);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if x <= 0xFF
        var s := "";
        if (getbit(x, 0), s := if(s = "", "gear failure", s + ", gear failure"));
        if (getbit(x, 1), s := if(s = "", "lamp failure", s + ", lamp failure"));
        if (getbit(x, 2), s := if(s = "", "lamp on", s + ", lamp on"));
        if (getbit(x, 3), s := if(s = "", "limit error", s + ", limit error"));
        if (getbit(x, 4), s := if(s = "", "fade running", s + ", fade running"));
        if (getbit(x, 5), s := if(s = "", "reset state", s + ", reset state"));
        if (getbit(x, 6), s := if(s = "", "missing short address", s + ", missing short address"));
        if (getbit(x, 7), s := if(s = "", "power cycle", s + ", power cycle"));
        var ign := if((ignGear = 1) and (ignLamp = 1), "gear and lamp failure", if(ignGear = 1, "gear failure", if(ignLamp = 1, "lamp failure", "")));
        return(if(s = "", "OK", s) + " (0x" + tostring(x, "X2") + ")" + if(ign = "", "", "; not raised: " + ign + " reported since start"));
    end
end

return("--")
Fade
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA5);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if x <= 0xFF
        var t := getbits(x, 4, 4);
        var ret := if(t = 0, "off", t + " (" + round(sqrt(power(2, t)) * 5) / 10 + " s)");
        modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA8);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
        var e := modbusr(SH, 511, uint16);
        if (t = 0 and e <= 0xFF and e != 0, ret := "extended 0x" + tostring(e, "X2"));
        return("fade time " + ret + ", fade rate " + getbits(x, 0, 4));
    end
end

return("--")
DALI Version
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x97);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if x <= 0xFF
        return(if(x >= 8, "DALI-2 " + getbits(x, 2, 6) + "." + getbits(x, 0, 2), "DALI-1") + " (" + x + ")");
    end
end

return("--")
Bus statistics
return("since start: queries " + cntQ + ", stale answers read away " + cntStale + ", no answer " + cntNone + ", collisions " + cntColl + ", rejected levels " + cntBad)
Azioni di servizio
${xml_add_to_group}
Parametri: Group ID (0–15 grp)
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x60 + grp);
${xml_remove_from_group}
Parametri: Group ID (0–15 grp)
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x70 + grp);
${xml_reset_to_default_settings}
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x20);
${xml_set_startup_levels}
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x21);
sleep(10);
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x2c);
sleep(10);
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x2d);
Disable fading
modbusw(SH, 541, uint16, 0xA300);
sleep(100);
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x2E);
sleep(100);
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x30);
Gear 42 Dimmer Lettura e scrittura

Dispositivo di controllo DALI all'indirizzo breve 42 — dimmer TapHome mappato su DALI arc power 0–100 % tramite H:510 LAMP LEVEL (scrittura) e QUERY ACTUAL LEVEL tramite H:511 (lettura), delimitato dai propri MIN / MAX LEVEL del gear.

Registro: H:511 → H:510 UInt16 Unità: % numeric
Attributi di servizio
Indirizzo breveIndirizzo breve DALI (0–63) target di questo dispositivo — fissato al momento dell'importazione del template e utilizzato nel byte alto di ogni scrittura Modbus.
Device TypeByte device-type DALI restituito da QUERY DEVICE TYPE (0x99) — riporta DT0 (fluorescente), DT6 (driver LED), DT8 (colore / tunable white) ecc., o -- quando non c'è risposta.
Physical Min LevelLivello minimo di dimmerazione imposto dall'hardware riportato dal gear — letto da QUERY PHYSICAL MIN LEVEL (0x9A), in percentuale.
Max LevelDALI MAX LEVEL configurato — letto da QUERY MAX LEVEL (0xA1); utilizzato come limite superiore durante la scalatura di TapHome 0–100 % su DALI arc power.
Min LevelDALI MIN LEVEL configurato — letto da QUERY MIN LEVEL (0xA2); utilizzato come limite inferiore durante la scalatura di TapHome 0–100 % su DALI arc power.
Power Up LevelLuminosità ripristinata dopo il ripristino dell'alimentazione del bus DALI — letta da QUERY POWER ON LEVEL (0xA3).
System Failure LevelLuminosità adottata quando il bus DALI perde la comunicazione per più di 500 ms — letta da QUERY SYSTEM FAILURE LEVEL (0xA4).
GruppiElenco separato da virgole dei gruppi DALI (0–15) a cui appartiene il gear — decodificato da QUERY GROUPS 0-7 (0xC0) e QUERY GROUPS 8-15 (0xC1); mostra None o ad es. 0,3,7.
Support Lamp FailureSe la lampada / driver supporta il rilevamento dei guasti della lampada — Yes / No / --. Gestisce l'errore Lamp failure! nel readscript periodico.
Support Power FailureSe la lampada / driver supporta il rilevamento dei guasti di alimentazione — Yes / No / --. Gestisce l'errore Power failure! nel readscript periodico.
DALI Version
Bus statistics
Azioni di servizio
Add to GroupAggiunge questo gear a un gruppo DALI (0–15) tramite ADD TO GROUP (0x60+grp) — auto-ripetuto entro 100 ms come richiesto per i comandi di configurazione DALI.
Remove from GroupRimuove questo gear da un gruppo DALI (0–15) tramite REMOVE FROM GROUP (0x70+grp).
Reset to Default SettingsInvia DALI RESET (0x20) — ripristina ogni parametro NVM del gear (livelli max / min / power-on / system-failure, appartenenza al gruppo, scene) al valore predefinito del produttore.
Set Startup LevelsCattura l'arc power corrente e la memorizza come Power On Level e System Failure Level — sequenza STORE ACTUAL LEVEL IN DTR (0x21) → STORE DTR AS POWER ON LEVEL (0x2C) → STORE DTR AS SYSTEM FAILURE LEVEL (0x2D).
Disable fading

Gear 42

Lettura (modulo)
var x := 0; var rx := 0; var y := 0;
if Status > 0
    Status := Status - 1;
    adderror(3, "Gear not responding!");
    return(0);
end

# checkStatus: ReadLevel resets it while the gear answers; statusPoll: QUERY STATUS at least once per 60 runs
checkStatus := checkStatus - 1;
statusPoll := statusPoll - 1;
if checkStatus < 1 or statusPoll < 1
    # an unread answer left in the gateway would be taken for this query: read it away and count it
    x := modbusr(SH, 511, uint16); if (x != 0x8000, cntStale := cntStale + 1);
    modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x90);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    x := modbusr(SH, 511, uint16);
    cntQ := cntQ + 1; if (x = 0x8000, cntNone := cntNone + 1); if (x = 0x20FF, cntColl := cntColl + 1);
    # a single lost answer happens on DALI: ask once more before declaring the gear missing
    if x = 0x8000
        x := modbusr(SH, 511, uint16); if (x != 0x8000, cntStale := cntStale + 1);
        modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x90);
        sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
        x := modbusr(SH, 511, uint16);
        cntQ := cntQ + 1; if (x = 0x8000, cntNone := cntNone + 1); if (x = 0x20FF, cntColl := cntColl + 1);
    end
    if x <= 0xFF
        # a changed failure bit must be read twice the same before it is taken
        if statusSeen = 1 and getbits(x, 0, 2) != getbits(gearStatus, 0, 2)
            y := modbusr(SH, 511, uint16); if (y != 0x8000, cntStale := cntStale + 1);
            modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x90);
            sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
            y := modbusr(SH, 511, uint16);
            cntQ := cntQ + 1; if (y = 0x8000, cntNone := cntNone + 1); if (y = 0x20FF, cntColl := cntColl + 1);
            if y != x
                cntBad := cntBad + 1;
                x := gearStatus;
            end
        end
        if statusSeen = 0
            ignGear := getbit(x, 0);
            ignLamp := getbit(x, 1);
            statusSeen := 1;
        end
        # a bit that clears ends its ignore, so a later failure is raised
        if (getbit(x, 0) = 0, ignGear := 0);
        if (getbit(x, 1) = 0, ignLamp := 0);
        gearStatus := x;
        checkStatus := 60;
        statusPoll := 60;
    else
        if x = 0x8000
            Status := RANDINT(10, 60);
            adderror(3, "Gear not responding!");
            return(0);
        end
    end
end

# messages last one run only, so they are raised from the stored status on every run
if ((getbit(gearStatus, 0) = 1) and (ignGear = 0), adderror(1, "Control gear failure!"));
if ((getbit(gearStatus, 1) = 1) and (ignLamp = 0), adderror(2, "Lamp failure!"));
Inizializzazione
var x := 0; var rx := 0;
# QUERY STATUS 0x90: every reply byte proves the gear is present; 0x8000 = no answer, 0x20FF = bus collision
# an unread answer left in the gateway would be taken for this query: read it away and count it
x := modbusr(SH, 511, uint16); if (x != 0x8000, cntStale := cntStale + 1);
modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x90);
sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
x := modbusr(SH, 511, uint16);
cntQ := cntQ + 1; if (x = 0x8000, cntNone := cntNone + 1); if (x = 0x20FF, cntColl := cntColl + 1);
statusSeen := 0;
if x <= 0xFF
    # failure bits a gear reports from its first answer are its permanent state, not an event: shown, not raised
    gearStatus := x;
    ignGear := getbit(x, 0);
    ignLamp := getbit(x, 1);
    statusSeen := 1;
    Status := 0;
else
    Status := RANDINT(1, 60);
end

if Status = 0
    x := modbusr(SH, 511, uint16); if (x != 0x8000, cntStale := cntStale + 1);
    modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA2);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    x := modbusr(SH, 511, uint16);
    cntQ := cntQ + 1; if (x = 0x8000, cntNone := cntNone + 1); if (x = 0x20FF, cntColl := cntColl + 1);
    if (x <= 0xFE, minLevel := x);

    x := modbusr(SH, 511, uint16); if (x != 0x8000, cntStale := cntStale + 1);
    modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA1);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    x := modbusr(SH, 511, uint16);
    cntQ := cntQ + 1; if (x = 0x8000, cntNone := cntNone + 1); if (x = 0x20FF, cntColl := cntColl + 1);
    if (x <= 0xFE, maxLevel := x);
end
Lettura livello
var x := 0; var rx := 0; var y := 0;
if Status = 0
    if minLevel = 0
        # an unread answer left in the gateway would be taken for this query: read it away and count it
        x := modbusr(SH, 511, uint16); if (x != 0x8000, cntStale := cntStale + 1);
        modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA2);
        sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
        x := modbusr(SH, 511, uint16);
        cntQ := cntQ + 1; if (x = 0x8000, cntNone := cntNone + 1); if (x = 0x20FF, cntColl := cntColl + 1);
        if (x <= 0xFE, minLevel := x);
    end
    x := modbusr(SH, 511, uint16); if (x != 0x8000, cntStale := cntStale + 1);
    modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA0);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    x := modbusr(SH, 511, uint16);
    cntQ := cntQ + 1; if (x = 0x8000, cntNone := cntNone + 1); if (x = 0x20FF, cntColl := cntColl + 1);
    if (x != 0x8000 or rx, checkStatus := 60);
    # 0xFF = MASK, 0x20FF = collision, 0x8000 = no answer: keep the last level instead of a phantom value
    if x > 0xFE
        return(Le);
    end
    # an actual level is 0 or between the gear's min and max: anything else is not this gear's answer
    if x > 0 and x < minLevel
        cntBad := cntBad + 1;
        return(Le);
    end
    # a changed level must be read twice the same before it is taken
    if x != lastRaw
        y := modbusr(SH, 511, uint16); if (y != 0x8000, cntStale := cntStale + 1);
        modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA0);
        sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
        y := modbusr(SH, 511, uint16);
        cntQ := cntQ + 1; if (y = 0x8000, cntNone := cntNone + 1); if (y = 0x20FF, cntColl := cntColl + 1);
        if y != x
            cntBad := cntBad + 1;
            return(Le);
        end
        lastRaw := x;
    end
    return(if(x = 0, 0, linear(x, minLevel, 0.01, maxLevel, 1)));
else
    return(NaN);
end
Scrittura livello
var level := 0;
if(Le > 0, level := round(linear(Le, 0.01, minLevel, 1, maxLevel)));
modbusw(SH, 510, uint16, (ShortAddress << 8) + level );
Attributi di servizio
${xml_short_address}
ShortAddress
${xml_device_type}
var x := 0; var y := 0; var rx := 0; var s := ""; var i := 0;
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x99);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    x := modbusr(SH, 511, uint16);
    if (x < 0xFF, return("DT" + x));
    if x = 0xFF
        while i < 8
            modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA7);
            sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
            y := modbusr(SH, 511, uint16);
            if y < 0xFE
                s := if(s = "", "DT" + y, s + ", DT" + y);
                i := i + 1;
            else
                i := 8;
            end
        loop
        return(if(s = "", "MASK", s));
    end
end

return("--")
Physical Min Level
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x9A);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if (x <= 0xFE, return(round((x / 0xFE) * 100) + " %"));
end

return("--")
Max Level
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA1);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if (x <= 0xFE, return(round((x / 0xFE) * 100) + " %"));
end

return("--")
Min Level
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA2);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if (x <= 0xFE, return(round((x / 0xFE) * 100) + " %"));
end

return("--")
Power Up Level
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA3);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if (x <= 0xFE, return(round((x / 0xFE) * 100) + " %"));
end

return("--")
System Failure Level
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA4);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if (x <= 0xFE, return(round((x / 0xFE) * 100) + " %"));
end

return("--")
${xml_groups}
var x := 0; var rx := 0;
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xC0);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var g1 := modbusr(SH, 511, uint16);
    if (g1 > 0xFF, return("--")); 

    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xC1);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var g2 := modbusr(SH, 511, uint16);
    if (g2 > 0xFF, return("--")); 

    var ret := "";

    if (getbit(g1, 0), ret := ret + "0");
    if (getbit(g1, 1), if (ret = "", ret := "1", ret := ret + ",1"));
    if (getbit(g1, 2), if (ret = "", ret := "2", ret := ret + ",2"));
    if (getbit(g1, 3), if (ret = "", ret := "3", ret := ret + ",3"));
    if (getbit(g1, 4), if (ret = "", ret := "4", ret := ret + ",4"));
    if (getbit(g1, 5), if (ret = "", ret := "5", ret := ret + ",5"));
    if (getbit(g1, 6), if (ret = "", ret := "6", ret := ret + ",6"));
    if (getbit(g1, 7), if (ret = "", ret := "7", ret := ret + ",7"));
    if (getbit(g2, 0), if (ret = "", ret := "8", ret := ret + ",8"));
    if (getbit(g2, 1), if (ret = "", ret := "9", ret := ret + ",9"));
    if (getbit(g2, 2), if (ret = "", ret := "10", ret := ret + ",10"));
    if (getbit(g2, 3), if (ret = "", ret := "11", ret := ret + ",11"));
    if (getbit(g2, 4), if (ret = "", ret := "12", ret := ret + ",12"));
    if (getbit(g2, 5), if (ret = "", ret := "13", ret := ret + ",13"));
    if (getbit(g2, 6), if (ret = "", ret := "14", ret := ret + ",14"));
    if (getbit(g2, 7), if (ret = "", ret := "15", ret := ret + ",15"));

    if (ret = "", return("None"), return(ret));
else
    return("--");
end
DALI Status
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x90);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if x <= 0xFF
        var s := "";
        if (getbit(x, 0), s := if(s = "", "gear failure", s + ", gear failure"));
        if (getbit(x, 1), s := if(s = "", "lamp failure", s + ", lamp failure"));
        if (getbit(x, 2), s := if(s = "", "lamp on", s + ", lamp on"));
        if (getbit(x, 3), s := if(s = "", "limit error", s + ", limit error"));
        if (getbit(x, 4), s := if(s = "", "fade running", s + ", fade running"));
        if (getbit(x, 5), s := if(s = "", "reset state", s + ", reset state"));
        if (getbit(x, 6), s := if(s = "", "missing short address", s + ", missing short address"));
        if (getbit(x, 7), s := if(s = "", "power cycle", s + ", power cycle"));
        var ign := if((ignGear = 1) and (ignLamp = 1), "gear and lamp failure", if(ignGear = 1, "gear failure", if(ignLamp = 1, "lamp failure", "")));
        return(if(s = "", "OK", s) + " (0x" + tostring(x, "X2") + ")" + if(ign = "", "", "; not raised: " + ign + " reported since start"));
    end
end

return("--")
Fade
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA5);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if x <= 0xFF
        var t := getbits(x, 4, 4);
        var ret := if(t = 0, "off", t + " (" + round(sqrt(power(2, t)) * 5) / 10 + " s)");
        modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA8);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
        var e := modbusr(SH, 511, uint16);
        if (t = 0 and e <= 0xFF and e != 0, ret := "extended 0x" + tostring(e, "X2"));
        return("fade time " + ret + ", fade rate " + getbits(x, 0, 4));
    end
end

return("--")
DALI Version
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x97);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if x <= 0xFF
        return(if(x >= 8, "DALI-2 " + getbits(x, 2, 6) + "." + getbits(x, 0, 2), "DALI-1") + " (" + x + ")");
    end
end

return("--")
Bus statistics
return("since start: queries " + cntQ + ", stale answers read away " + cntStale + ", no answer " + cntNone + ", collisions " + cntColl + ", rejected levels " + cntBad)
Azioni di servizio
${xml_add_to_group}
Parametri: Group ID (0–15 grp)
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x60 + grp);
${xml_remove_from_group}
Parametri: Group ID (0–15 grp)
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x70 + grp);
${xml_reset_to_default_settings}
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x20);
${xml_set_startup_levels}
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x21);
sleep(10);
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x2c);
sleep(10);
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x2d);
Disable fading
modbusw(SH, 541, uint16, 0xA300);
sleep(100);
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x2E);
sleep(100);
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x30);
Gear 43 Dimmer Lettura e scrittura

Dispositivo di controllo DALI all'indirizzo breve 43 — dimmer TapHome mappato su DALI arc power 0–100 % tramite H:510 LAMP LEVEL (scrittura) e QUERY ACTUAL LEVEL tramite H:511 (lettura), delimitato dai propri MIN / MAX LEVEL del gear.

Registro: H:511 → H:510 UInt16 Unità: % numeric
Attributi di servizio
Indirizzo breveIndirizzo breve DALI (0–63) target di questo dispositivo — fissato al momento dell'importazione del template e utilizzato nel byte alto di ogni scrittura Modbus.
Device TypeByte device-type DALI restituito da QUERY DEVICE TYPE (0x99) — riporta DT0 (fluorescente), DT6 (driver LED), DT8 (colore / tunable white) ecc., o -- quando non c'è risposta.
Physical Min LevelLivello minimo di dimmerazione imposto dall'hardware riportato dal gear — letto da QUERY PHYSICAL MIN LEVEL (0x9A), in percentuale.
Max LevelDALI MAX LEVEL configurato — letto da QUERY MAX LEVEL (0xA1); utilizzato come limite superiore durante la scalatura di TapHome 0–100 % su DALI arc power.
Min LevelDALI MIN LEVEL configurato — letto da QUERY MIN LEVEL (0xA2); utilizzato come limite inferiore durante la scalatura di TapHome 0–100 % su DALI arc power.
Power Up LevelLuminosità ripristinata dopo il ripristino dell'alimentazione del bus DALI — letta da QUERY POWER ON LEVEL (0xA3).
System Failure LevelLuminosità adottata quando il bus DALI perde la comunicazione per più di 500 ms — letta da QUERY SYSTEM FAILURE LEVEL (0xA4).
GruppiElenco separato da virgole dei gruppi DALI (0–15) a cui appartiene il gear — decodificato da QUERY GROUPS 0-7 (0xC0) e QUERY GROUPS 8-15 (0xC1); mostra None o ad es. 0,3,7.
Support Lamp FailureSe la lampada / driver supporta il rilevamento dei guasti della lampada — Yes / No / --. Gestisce l'errore Lamp failure! nel readscript periodico.
Support Power FailureSe la lampada / driver supporta il rilevamento dei guasti di alimentazione — Yes / No / --. Gestisce l'errore Power failure! nel readscript periodico.
DALI Version
Bus statistics
Azioni di servizio
Add to GroupAggiunge questo gear a un gruppo DALI (0–15) tramite ADD TO GROUP (0x60+grp) — auto-ripetuto entro 100 ms come richiesto per i comandi di configurazione DALI.
Remove from GroupRimuove questo gear da un gruppo DALI (0–15) tramite REMOVE FROM GROUP (0x70+grp).
Reset to Default SettingsInvia DALI RESET (0x20) — ripristina ogni parametro NVM del gear (livelli max / min / power-on / system-failure, appartenenza al gruppo, scene) al valore predefinito del produttore.
Set Startup LevelsCattura l'arc power corrente e la memorizza come Power On Level e System Failure Level — sequenza STORE ACTUAL LEVEL IN DTR (0x21) → STORE DTR AS POWER ON LEVEL (0x2C) → STORE DTR AS SYSTEM FAILURE LEVEL (0x2D).
Disable fading

Gear 43

Lettura (modulo)
var x := 0; var rx := 0; var y := 0;
if Status > 0
    Status := Status - 1;
    adderror(3, "Gear not responding!");
    return(0);
end

# checkStatus: ReadLevel resets it while the gear answers; statusPoll: QUERY STATUS at least once per 60 runs
checkStatus := checkStatus - 1;
statusPoll := statusPoll - 1;
if checkStatus < 1 or statusPoll < 1
    # an unread answer left in the gateway would be taken for this query: read it away and count it
    x := modbusr(SH, 511, uint16); if (x != 0x8000, cntStale := cntStale + 1);
    modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x90);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    x := modbusr(SH, 511, uint16);
    cntQ := cntQ + 1; if (x = 0x8000, cntNone := cntNone + 1); if (x = 0x20FF, cntColl := cntColl + 1);
    # a single lost answer happens on DALI: ask once more before declaring the gear missing
    if x = 0x8000
        x := modbusr(SH, 511, uint16); if (x != 0x8000, cntStale := cntStale + 1);
        modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x90);
        sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
        x := modbusr(SH, 511, uint16);
        cntQ := cntQ + 1; if (x = 0x8000, cntNone := cntNone + 1); if (x = 0x20FF, cntColl := cntColl + 1);
    end
    if x <= 0xFF
        # a changed failure bit must be read twice the same before it is taken
        if statusSeen = 1 and getbits(x, 0, 2) != getbits(gearStatus, 0, 2)
            y := modbusr(SH, 511, uint16); if (y != 0x8000, cntStale := cntStale + 1);
            modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x90);
            sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
            y := modbusr(SH, 511, uint16);
            cntQ := cntQ + 1; if (y = 0x8000, cntNone := cntNone + 1); if (y = 0x20FF, cntColl := cntColl + 1);
            if y != x
                cntBad := cntBad + 1;
                x := gearStatus;
            end
        end
        if statusSeen = 0
            ignGear := getbit(x, 0);
            ignLamp := getbit(x, 1);
            statusSeen := 1;
        end
        # a bit that clears ends its ignore, so a later failure is raised
        if (getbit(x, 0) = 0, ignGear := 0);
        if (getbit(x, 1) = 0, ignLamp := 0);
        gearStatus := x;
        checkStatus := 60;
        statusPoll := 60;
    else
        if x = 0x8000
            Status := RANDINT(10, 60);
            adderror(3, "Gear not responding!");
            return(0);
        end
    end
end

# messages last one run only, so they are raised from the stored status on every run
if ((getbit(gearStatus, 0) = 1) and (ignGear = 0), adderror(1, "Control gear failure!"));
if ((getbit(gearStatus, 1) = 1) and (ignLamp = 0), adderror(2, "Lamp failure!"));
Inizializzazione
var x := 0; var rx := 0;
# QUERY STATUS 0x90: every reply byte proves the gear is present; 0x8000 = no answer, 0x20FF = bus collision
# an unread answer left in the gateway would be taken for this query: read it away and count it
x := modbusr(SH, 511, uint16); if (x != 0x8000, cntStale := cntStale + 1);
modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x90);
sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
x := modbusr(SH, 511, uint16);
cntQ := cntQ + 1; if (x = 0x8000, cntNone := cntNone + 1); if (x = 0x20FF, cntColl := cntColl + 1);
statusSeen := 0;
if x <= 0xFF
    # failure bits a gear reports from its first answer are its permanent state, not an event: shown, not raised
    gearStatus := x;
    ignGear := getbit(x, 0);
    ignLamp := getbit(x, 1);
    statusSeen := 1;
    Status := 0;
else
    Status := RANDINT(1, 60);
end

if Status = 0
    x := modbusr(SH, 511, uint16); if (x != 0x8000, cntStale := cntStale + 1);
    modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA2);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    x := modbusr(SH, 511, uint16);
    cntQ := cntQ + 1; if (x = 0x8000, cntNone := cntNone + 1); if (x = 0x20FF, cntColl := cntColl + 1);
    if (x <= 0xFE, minLevel := x);

    x := modbusr(SH, 511, uint16); if (x != 0x8000, cntStale := cntStale + 1);
    modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA1);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    x := modbusr(SH, 511, uint16);
    cntQ := cntQ + 1; if (x = 0x8000, cntNone := cntNone + 1); if (x = 0x20FF, cntColl := cntColl + 1);
    if (x <= 0xFE, maxLevel := x);
end
Lettura livello
var x := 0; var rx := 0; var y := 0;
if Status = 0
    if minLevel = 0
        # an unread answer left in the gateway would be taken for this query: read it away and count it
        x := modbusr(SH, 511, uint16); if (x != 0x8000, cntStale := cntStale + 1);
        modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA2);
        sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
        x := modbusr(SH, 511, uint16);
        cntQ := cntQ + 1; if (x = 0x8000, cntNone := cntNone + 1); if (x = 0x20FF, cntColl := cntColl + 1);
        if (x <= 0xFE, minLevel := x);
    end
    x := modbusr(SH, 511, uint16); if (x != 0x8000, cntStale := cntStale + 1);
    modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA0);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    x := modbusr(SH, 511, uint16);
    cntQ := cntQ + 1; if (x = 0x8000, cntNone := cntNone + 1); if (x = 0x20FF, cntColl := cntColl + 1);
    if (x != 0x8000 or rx, checkStatus := 60);
    # 0xFF = MASK, 0x20FF = collision, 0x8000 = no answer: keep the last level instead of a phantom value
    if x > 0xFE
        return(Le);
    end
    # an actual level is 0 or between the gear's min and max: anything else is not this gear's answer
    if x > 0 and x < minLevel
        cntBad := cntBad + 1;
        return(Le);
    end
    # a changed level must be read twice the same before it is taken
    if x != lastRaw
        y := modbusr(SH, 511, uint16); if (y != 0x8000, cntStale := cntStale + 1);
        modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA0);
        sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
        y := modbusr(SH, 511, uint16);
        cntQ := cntQ + 1; if (y = 0x8000, cntNone := cntNone + 1); if (y = 0x20FF, cntColl := cntColl + 1);
        if y != x
            cntBad := cntBad + 1;
            return(Le);
        end
        lastRaw := x;
    end
    return(if(x = 0, 0, linear(x, minLevel, 0.01, maxLevel, 1)));
else
    return(NaN);
end
Scrittura livello
var level := 0;
if(Le > 0, level := round(linear(Le, 0.01, minLevel, 1, maxLevel)));
modbusw(SH, 510, uint16, (ShortAddress << 8) + level );
Attributi di servizio
${xml_short_address}
ShortAddress
${xml_device_type}
var x := 0; var y := 0; var rx := 0; var s := ""; var i := 0;
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x99);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    x := modbusr(SH, 511, uint16);
    if (x < 0xFF, return("DT" + x));
    if x = 0xFF
        while i < 8
            modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA7);
            sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
            y := modbusr(SH, 511, uint16);
            if y < 0xFE
                s := if(s = "", "DT" + y, s + ", DT" + y);
                i := i + 1;
            else
                i := 8;
            end
        loop
        return(if(s = "", "MASK", s));
    end
end

return("--")
Physical Min Level
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x9A);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if (x <= 0xFE, return(round((x / 0xFE) * 100) + " %"));
end

return("--")
Max Level
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA1);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if (x <= 0xFE, return(round((x / 0xFE) * 100) + " %"));
end

return("--")
Min Level
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA2);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if (x <= 0xFE, return(round((x / 0xFE) * 100) + " %"));
end

return("--")
Power Up Level
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA3);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if (x <= 0xFE, return(round((x / 0xFE) * 100) + " %"));
end

return("--")
System Failure Level
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA4);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if (x <= 0xFE, return(round((x / 0xFE) * 100) + " %"));
end

return("--")
${xml_groups}
var x := 0; var rx := 0;
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xC0);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var g1 := modbusr(SH, 511, uint16);
    if (g1 > 0xFF, return("--")); 

    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xC1);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var g2 := modbusr(SH, 511, uint16);
    if (g2 > 0xFF, return("--")); 

    var ret := "";

    if (getbit(g1, 0), ret := ret + "0");
    if (getbit(g1, 1), if (ret = "", ret := "1", ret := ret + ",1"));
    if (getbit(g1, 2), if (ret = "", ret := "2", ret := ret + ",2"));
    if (getbit(g1, 3), if (ret = "", ret := "3", ret := ret + ",3"));
    if (getbit(g1, 4), if (ret = "", ret := "4", ret := ret + ",4"));
    if (getbit(g1, 5), if (ret = "", ret := "5", ret := ret + ",5"));
    if (getbit(g1, 6), if (ret = "", ret := "6", ret := ret + ",6"));
    if (getbit(g1, 7), if (ret = "", ret := "7", ret := ret + ",7"));
    if (getbit(g2, 0), if (ret = "", ret := "8", ret := ret + ",8"));
    if (getbit(g2, 1), if (ret = "", ret := "9", ret := ret + ",9"));
    if (getbit(g2, 2), if (ret = "", ret := "10", ret := ret + ",10"));
    if (getbit(g2, 3), if (ret = "", ret := "11", ret := ret + ",11"));
    if (getbit(g2, 4), if (ret = "", ret := "12", ret := ret + ",12"));
    if (getbit(g2, 5), if (ret = "", ret := "13", ret := ret + ",13"));
    if (getbit(g2, 6), if (ret = "", ret := "14", ret := ret + ",14"));
    if (getbit(g2, 7), if (ret = "", ret := "15", ret := ret + ",15"));

    if (ret = "", return("None"), return(ret));
else
    return("--");
end
DALI Status
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x90);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if x <= 0xFF
        var s := "";
        if (getbit(x, 0), s := if(s = "", "gear failure", s + ", gear failure"));
        if (getbit(x, 1), s := if(s = "", "lamp failure", s + ", lamp failure"));
        if (getbit(x, 2), s := if(s = "", "lamp on", s + ", lamp on"));
        if (getbit(x, 3), s := if(s = "", "limit error", s + ", limit error"));
        if (getbit(x, 4), s := if(s = "", "fade running", s + ", fade running"));
        if (getbit(x, 5), s := if(s = "", "reset state", s + ", reset state"));
        if (getbit(x, 6), s := if(s = "", "missing short address", s + ", missing short address"));
        if (getbit(x, 7), s := if(s = "", "power cycle", s + ", power cycle"));
        var ign := if((ignGear = 1) and (ignLamp = 1), "gear and lamp failure", if(ignGear = 1, "gear failure", if(ignLamp = 1, "lamp failure", "")));
        return(if(s = "", "OK", s) + " (0x" + tostring(x, "X2") + ")" + if(ign = "", "", "; not raised: " + ign + " reported since start"));
    end
end

return("--")
Fade
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA5);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if x <= 0xFF
        var t := getbits(x, 4, 4);
        var ret := if(t = 0, "off", t + " (" + round(sqrt(power(2, t)) * 5) / 10 + " s)");
        modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA8);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
        var e := modbusr(SH, 511, uint16);
        if (t = 0 and e <= 0xFF and e != 0, ret := "extended 0x" + tostring(e, "X2"));
        return("fade time " + ret + ", fade rate " + getbits(x, 0, 4));
    end
end

return("--")
DALI Version
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x97);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if x <= 0xFF
        return(if(x >= 8, "DALI-2 " + getbits(x, 2, 6) + "." + getbits(x, 0, 2), "DALI-1") + " (" + x + ")");
    end
end

return("--")
Bus statistics
return("since start: queries " + cntQ + ", stale answers read away " + cntStale + ", no answer " + cntNone + ", collisions " + cntColl + ", rejected levels " + cntBad)
Azioni di servizio
${xml_add_to_group}
Parametri: Group ID (0–15 grp)
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x60 + grp);
${xml_remove_from_group}
Parametri: Group ID (0–15 grp)
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x70 + grp);
${xml_reset_to_default_settings}
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x20);
${xml_set_startup_levels}
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x21);
sleep(10);
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x2c);
sleep(10);
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x2d);
Disable fading
modbusw(SH, 541, uint16, 0xA300);
sleep(100);
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x2E);
sleep(100);
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x30);
Gear 44 Dimmer Lettura e scrittura

Dispositivo di controllo DALI all'indirizzo breve 44 — dimmer TapHome mappato su DALI arc power 0–100 % tramite H:510 LAMP LEVEL (scrittura) e QUERY ACTUAL LEVEL tramite H:511 (lettura), delimitato dai propri MIN / MAX LEVEL del gear.

Registro: H:511 → H:510 UInt16 Unità: % numeric
Attributi di servizio
Indirizzo breveIndirizzo breve DALI (0–63) target di questo dispositivo — fissato al momento dell'importazione del template e utilizzato nel byte alto di ogni scrittura Modbus.
Device TypeByte device-type DALI restituito da QUERY DEVICE TYPE (0x99) — riporta DT0 (fluorescente), DT6 (driver LED), DT8 (colore / tunable white) ecc., o -- quando non c'è risposta.
Physical Min LevelLivello minimo di dimmerazione imposto dall'hardware riportato dal gear — letto da QUERY PHYSICAL MIN LEVEL (0x9A), in percentuale.
Max LevelDALI MAX LEVEL configurato — letto da QUERY MAX LEVEL (0xA1); utilizzato come limite superiore durante la scalatura di TapHome 0–100 % su DALI arc power.
Min LevelDALI MIN LEVEL configurato — letto da QUERY MIN LEVEL (0xA2); utilizzato come limite inferiore durante la scalatura di TapHome 0–100 % su DALI arc power.
Power Up LevelLuminosità ripristinata dopo il ripristino dell'alimentazione del bus DALI — letta da QUERY POWER ON LEVEL (0xA3).
System Failure LevelLuminosità adottata quando il bus DALI perde la comunicazione per più di 500 ms — letta da QUERY SYSTEM FAILURE LEVEL (0xA4).
GruppiElenco separato da virgole dei gruppi DALI (0–15) a cui appartiene il gear — decodificato da QUERY GROUPS 0-7 (0xC0) e QUERY GROUPS 8-15 (0xC1); mostra None o ad es. 0,3,7.
Support Lamp FailureSe la lampada / driver supporta il rilevamento dei guasti della lampada — Yes / No / --. Gestisce l'errore Lamp failure! nel readscript periodico.
Support Power FailureSe la lampada / driver supporta il rilevamento dei guasti di alimentazione — Yes / No / --. Gestisce l'errore Power failure! nel readscript periodico.
DALI Version
Bus statistics
Azioni di servizio
Add to GroupAggiunge questo gear a un gruppo DALI (0–15) tramite ADD TO GROUP (0x60+grp) — auto-ripetuto entro 100 ms come richiesto per i comandi di configurazione DALI.
Remove from GroupRimuove questo gear da un gruppo DALI (0–15) tramite REMOVE FROM GROUP (0x70+grp).
Reset to Default SettingsInvia DALI RESET (0x20) — ripristina ogni parametro NVM del gear (livelli max / min / power-on / system-failure, appartenenza al gruppo, scene) al valore predefinito del produttore.
Set Startup LevelsCattura l'arc power corrente e la memorizza come Power On Level e System Failure Level — sequenza STORE ACTUAL LEVEL IN DTR (0x21) → STORE DTR AS POWER ON LEVEL (0x2C) → STORE DTR AS SYSTEM FAILURE LEVEL (0x2D).
Disable fading

Gear 44

Lettura (modulo)
var x := 0; var rx := 0; var y := 0;
if Status > 0
    Status := Status - 1;
    adderror(3, "Gear not responding!");
    return(0);
end

# checkStatus: ReadLevel resets it while the gear answers; statusPoll: QUERY STATUS at least once per 60 runs
checkStatus := checkStatus - 1;
statusPoll := statusPoll - 1;
if checkStatus < 1 or statusPoll < 1
    # an unread answer left in the gateway would be taken for this query: read it away and count it
    x := modbusr(SH, 511, uint16); if (x != 0x8000, cntStale := cntStale + 1);
    modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x90);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    x := modbusr(SH, 511, uint16);
    cntQ := cntQ + 1; if (x = 0x8000, cntNone := cntNone + 1); if (x = 0x20FF, cntColl := cntColl + 1);
    # a single lost answer happens on DALI: ask once more before declaring the gear missing
    if x = 0x8000
        x := modbusr(SH, 511, uint16); if (x != 0x8000, cntStale := cntStale + 1);
        modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x90);
        sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
        x := modbusr(SH, 511, uint16);
        cntQ := cntQ + 1; if (x = 0x8000, cntNone := cntNone + 1); if (x = 0x20FF, cntColl := cntColl + 1);
    end
    if x <= 0xFF
        # a changed failure bit must be read twice the same before it is taken
        if statusSeen = 1 and getbits(x, 0, 2) != getbits(gearStatus, 0, 2)
            y := modbusr(SH, 511, uint16); if (y != 0x8000, cntStale := cntStale + 1);
            modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x90);
            sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
            y := modbusr(SH, 511, uint16);
            cntQ := cntQ + 1; if (y = 0x8000, cntNone := cntNone + 1); if (y = 0x20FF, cntColl := cntColl + 1);
            if y != x
                cntBad := cntBad + 1;
                x := gearStatus;
            end
        end
        if statusSeen = 0
            ignGear := getbit(x, 0);
            ignLamp := getbit(x, 1);
            statusSeen := 1;
        end
        # a bit that clears ends its ignore, so a later failure is raised
        if (getbit(x, 0) = 0, ignGear := 0);
        if (getbit(x, 1) = 0, ignLamp := 0);
        gearStatus := x;
        checkStatus := 60;
        statusPoll := 60;
    else
        if x = 0x8000
            Status := RANDINT(10, 60);
            adderror(3, "Gear not responding!");
            return(0);
        end
    end
end

# messages last one run only, so they are raised from the stored status on every run
if ((getbit(gearStatus, 0) = 1) and (ignGear = 0), adderror(1, "Control gear failure!"));
if ((getbit(gearStatus, 1) = 1) and (ignLamp = 0), adderror(2, "Lamp failure!"));
Inizializzazione
var x := 0; var rx := 0;
# QUERY STATUS 0x90: every reply byte proves the gear is present; 0x8000 = no answer, 0x20FF = bus collision
# an unread answer left in the gateway would be taken for this query: read it away and count it
x := modbusr(SH, 511, uint16); if (x != 0x8000, cntStale := cntStale + 1);
modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x90);
sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
x := modbusr(SH, 511, uint16);
cntQ := cntQ + 1; if (x = 0x8000, cntNone := cntNone + 1); if (x = 0x20FF, cntColl := cntColl + 1);
statusSeen := 0;
if x <= 0xFF
    # failure bits a gear reports from its first answer are its permanent state, not an event: shown, not raised
    gearStatus := x;
    ignGear := getbit(x, 0);
    ignLamp := getbit(x, 1);
    statusSeen := 1;
    Status := 0;
else
    Status := RANDINT(1, 60);
end

if Status = 0
    x := modbusr(SH, 511, uint16); if (x != 0x8000, cntStale := cntStale + 1);
    modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA2);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    x := modbusr(SH, 511, uint16);
    cntQ := cntQ + 1; if (x = 0x8000, cntNone := cntNone + 1); if (x = 0x20FF, cntColl := cntColl + 1);
    if (x <= 0xFE, minLevel := x);

    x := modbusr(SH, 511, uint16); if (x != 0x8000, cntStale := cntStale + 1);
    modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA1);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    x := modbusr(SH, 511, uint16);
    cntQ := cntQ + 1; if (x = 0x8000, cntNone := cntNone + 1); if (x = 0x20FF, cntColl := cntColl + 1);
    if (x <= 0xFE, maxLevel := x);
end
Lettura livello
var x := 0; var rx := 0; var y := 0;
if Status = 0
    if minLevel = 0
        # an unread answer left in the gateway would be taken for this query: read it away and count it
        x := modbusr(SH, 511, uint16); if (x != 0x8000, cntStale := cntStale + 1);
        modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA2);
        sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
        x := modbusr(SH, 511, uint16);
        cntQ := cntQ + 1; if (x = 0x8000, cntNone := cntNone + 1); if (x = 0x20FF, cntColl := cntColl + 1);
        if (x <= 0xFE, minLevel := x);
    end
    x := modbusr(SH, 511, uint16); if (x != 0x8000, cntStale := cntStale + 1);
    modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA0);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    x := modbusr(SH, 511, uint16);
    cntQ := cntQ + 1; if (x = 0x8000, cntNone := cntNone + 1); if (x = 0x20FF, cntColl := cntColl + 1);
    if (x != 0x8000 or rx, checkStatus := 60);
    # 0xFF = MASK, 0x20FF = collision, 0x8000 = no answer: keep the last level instead of a phantom value
    if x > 0xFE
        return(Le);
    end
    # an actual level is 0 or between the gear's min and max: anything else is not this gear's answer
    if x > 0 and x < minLevel
        cntBad := cntBad + 1;
        return(Le);
    end
    # a changed level must be read twice the same before it is taken
    if x != lastRaw
        y := modbusr(SH, 511, uint16); if (y != 0x8000, cntStale := cntStale + 1);
        modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA0);
        sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
        y := modbusr(SH, 511, uint16);
        cntQ := cntQ + 1; if (y = 0x8000, cntNone := cntNone + 1); if (y = 0x20FF, cntColl := cntColl + 1);
        if y != x
            cntBad := cntBad + 1;
            return(Le);
        end
        lastRaw := x;
    end
    return(if(x = 0, 0, linear(x, minLevel, 0.01, maxLevel, 1)));
else
    return(NaN);
end
Scrittura livello
var level := 0;
if(Le > 0, level := round(linear(Le, 0.01, minLevel, 1, maxLevel)));
modbusw(SH, 510, uint16, (ShortAddress << 8) + level );
Attributi di servizio
${xml_short_address}
ShortAddress
${xml_device_type}
var x := 0; var y := 0; var rx := 0; var s := ""; var i := 0;
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x99);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    x := modbusr(SH, 511, uint16);
    if (x < 0xFF, return("DT" + x));
    if x = 0xFF
        while i < 8
            modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA7);
            sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
            y := modbusr(SH, 511, uint16);
            if y < 0xFE
                s := if(s = "", "DT" + y, s + ", DT" + y);
                i := i + 1;
            else
                i := 8;
            end
        loop
        return(if(s = "", "MASK", s));
    end
end

return("--")
Physical Min Level
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x9A);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if (x <= 0xFE, return(round((x / 0xFE) * 100) + " %"));
end

return("--")
Max Level
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA1);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if (x <= 0xFE, return(round((x / 0xFE) * 100) + " %"));
end

return("--")
Min Level
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA2);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if (x <= 0xFE, return(round((x / 0xFE) * 100) + " %"));
end

return("--")
Power Up Level
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA3);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if (x <= 0xFE, return(round((x / 0xFE) * 100) + " %"));
end

return("--")
System Failure Level
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA4);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if (x <= 0xFE, return(round((x / 0xFE) * 100) + " %"));
end

return("--")
${xml_groups}
var x := 0; var rx := 0;
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xC0);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var g1 := modbusr(SH, 511, uint16);
    if (g1 > 0xFF, return("--")); 

    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xC1);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var g2 := modbusr(SH, 511, uint16);
    if (g2 > 0xFF, return("--")); 

    var ret := "";

    if (getbit(g1, 0), ret := ret + "0");
    if (getbit(g1, 1), if (ret = "", ret := "1", ret := ret + ",1"));
    if (getbit(g1, 2), if (ret = "", ret := "2", ret := ret + ",2"));
    if (getbit(g1, 3), if (ret = "", ret := "3", ret := ret + ",3"));
    if (getbit(g1, 4), if (ret = "", ret := "4", ret := ret + ",4"));
    if (getbit(g1, 5), if (ret = "", ret := "5", ret := ret + ",5"));
    if (getbit(g1, 6), if (ret = "", ret := "6", ret := ret + ",6"));
    if (getbit(g1, 7), if (ret = "", ret := "7", ret := ret + ",7"));
    if (getbit(g2, 0), if (ret = "", ret := "8", ret := ret + ",8"));
    if (getbit(g2, 1), if (ret = "", ret := "9", ret := ret + ",9"));
    if (getbit(g2, 2), if (ret = "", ret := "10", ret := ret + ",10"));
    if (getbit(g2, 3), if (ret = "", ret := "11", ret := ret + ",11"));
    if (getbit(g2, 4), if (ret = "", ret := "12", ret := ret + ",12"));
    if (getbit(g2, 5), if (ret = "", ret := "13", ret := ret + ",13"));
    if (getbit(g2, 6), if (ret = "", ret := "14", ret := ret + ",14"));
    if (getbit(g2, 7), if (ret = "", ret := "15", ret := ret + ",15"));

    if (ret = "", return("None"), return(ret));
else
    return("--");
end
DALI Status
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x90);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if x <= 0xFF
        var s := "";
        if (getbit(x, 0), s := if(s = "", "gear failure", s + ", gear failure"));
        if (getbit(x, 1), s := if(s = "", "lamp failure", s + ", lamp failure"));
        if (getbit(x, 2), s := if(s = "", "lamp on", s + ", lamp on"));
        if (getbit(x, 3), s := if(s = "", "limit error", s + ", limit error"));
        if (getbit(x, 4), s := if(s = "", "fade running", s + ", fade running"));
        if (getbit(x, 5), s := if(s = "", "reset state", s + ", reset state"));
        if (getbit(x, 6), s := if(s = "", "missing short address", s + ", missing short address"));
        if (getbit(x, 7), s := if(s = "", "power cycle", s + ", power cycle"));
        var ign := if((ignGear = 1) and (ignLamp = 1), "gear and lamp failure", if(ignGear = 1, "gear failure", if(ignLamp = 1, "lamp failure", "")));
        return(if(s = "", "OK", s) + " (0x" + tostring(x, "X2") + ")" + if(ign = "", "", "; not raised: " + ign + " reported since start"));
    end
end

return("--")
Fade
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA5);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if x <= 0xFF
        var t := getbits(x, 4, 4);
        var ret := if(t = 0, "off", t + " (" + round(sqrt(power(2, t)) * 5) / 10 + " s)");
        modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA8);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
        var e := modbusr(SH, 511, uint16);
        if (t = 0 and e <= 0xFF and e != 0, ret := "extended 0x" + tostring(e, "X2"));
        return("fade time " + ret + ", fade rate " + getbits(x, 0, 4));
    end
end

return("--")
DALI Version
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x97);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if x <= 0xFF
        return(if(x >= 8, "DALI-2 " + getbits(x, 2, 6) + "." + getbits(x, 0, 2), "DALI-1") + " (" + x + ")");
    end
end

return("--")
Bus statistics
return("since start: queries " + cntQ + ", stale answers read away " + cntStale + ", no answer " + cntNone + ", collisions " + cntColl + ", rejected levels " + cntBad)
Azioni di servizio
${xml_add_to_group}
Parametri: Group ID (0–15 grp)
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x60 + grp);
${xml_remove_from_group}
Parametri: Group ID (0–15 grp)
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x70 + grp);
${xml_reset_to_default_settings}
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x20);
${xml_set_startup_levels}
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x21);
sleep(10);
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x2c);
sleep(10);
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x2d);
Disable fading
modbusw(SH, 541, uint16, 0xA300);
sleep(100);
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x2E);
sleep(100);
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x30);
Gear 45 Dimmer Lettura e scrittura

Dispositivo di controllo DALI all'indirizzo breve 45 — dimmer TapHome mappato su DALI arc power 0–100 % tramite H:510 LAMP LEVEL (scrittura) e QUERY ACTUAL LEVEL tramite H:511 (lettura), delimitato dai propri MIN / MAX LEVEL del gear.

Registro: H:511 → H:510 UInt16 Unità: % numeric
Attributi di servizio
Indirizzo breveIndirizzo breve DALI (0–63) target di questo dispositivo — fissato al momento dell'importazione del template e utilizzato nel byte alto di ogni scrittura Modbus.
Device TypeByte device-type DALI restituito da QUERY DEVICE TYPE (0x99) — riporta DT0 (fluorescente), DT6 (driver LED), DT8 (colore / tunable white) ecc., o -- quando non c'è risposta.
Physical Min LevelLivello minimo di dimmerazione imposto dall'hardware riportato dal gear — letto da QUERY PHYSICAL MIN LEVEL (0x9A), in percentuale.
Max LevelDALI MAX LEVEL configurato — letto da QUERY MAX LEVEL (0xA1); utilizzato come limite superiore durante la scalatura di TapHome 0–100 % su DALI arc power.
Min LevelDALI MIN LEVEL configurato — letto da QUERY MIN LEVEL (0xA2); utilizzato come limite inferiore durante la scalatura di TapHome 0–100 % su DALI arc power.
Power Up LevelLuminosità ripristinata dopo il ripristino dell'alimentazione del bus DALI — letta da QUERY POWER ON LEVEL (0xA3).
System Failure LevelLuminosità adottata quando il bus DALI perde la comunicazione per più di 500 ms — letta da QUERY SYSTEM FAILURE LEVEL (0xA4).
GruppiElenco separato da virgole dei gruppi DALI (0–15) a cui appartiene il gear — decodificato da QUERY GROUPS 0-7 (0xC0) e QUERY GROUPS 8-15 (0xC1); mostra None o ad es. 0,3,7.
Support Lamp FailureSe la lampada / driver supporta il rilevamento dei guasti della lampada — Yes / No / --. Gestisce l'errore Lamp failure! nel readscript periodico.
Support Power FailureSe la lampada / driver supporta il rilevamento dei guasti di alimentazione — Yes / No / --. Gestisce l'errore Power failure! nel readscript periodico.
DALI Version
Bus statistics
Azioni di servizio
Add to GroupAggiunge questo gear a un gruppo DALI (0–15) tramite ADD TO GROUP (0x60+grp) — auto-ripetuto entro 100 ms come richiesto per i comandi di configurazione DALI.
Remove from GroupRimuove questo gear da un gruppo DALI (0–15) tramite REMOVE FROM GROUP (0x70+grp).
Reset to Default SettingsInvia DALI RESET (0x20) — ripristina ogni parametro NVM del gear (livelli max / min / power-on / system-failure, appartenenza al gruppo, scene) al valore predefinito del produttore.
Set Startup LevelsCattura l'arc power corrente e la memorizza come Power On Level e System Failure Level — sequenza STORE ACTUAL LEVEL IN DTR (0x21) → STORE DTR AS POWER ON LEVEL (0x2C) → STORE DTR AS SYSTEM FAILURE LEVEL (0x2D).
Disable fading

Gear 45

Lettura (modulo)
var x := 0; var rx := 0; var y := 0;
if Status > 0
    Status := Status - 1;
    adderror(3, "Gear not responding!");
    return(0);
end

# checkStatus: ReadLevel resets it while the gear answers; statusPoll: QUERY STATUS at least once per 60 runs
checkStatus := checkStatus - 1;
statusPoll := statusPoll - 1;
if checkStatus < 1 or statusPoll < 1
    # an unread answer left in the gateway would be taken for this query: read it away and count it
    x := modbusr(SH, 511, uint16); if (x != 0x8000, cntStale := cntStale + 1);
    modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x90);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    x := modbusr(SH, 511, uint16);
    cntQ := cntQ + 1; if (x = 0x8000, cntNone := cntNone + 1); if (x = 0x20FF, cntColl := cntColl + 1);
    # a single lost answer happens on DALI: ask once more before declaring the gear missing
    if x = 0x8000
        x := modbusr(SH, 511, uint16); if (x != 0x8000, cntStale := cntStale + 1);
        modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x90);
        sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
        x := modbusr(SH, 511, uint16);
        cntQ := cntQ + 1; if (x = 0x8000, cntNone := cntNone + 1); if (x = 0x20FF, cntColl := cntColl + 1);
    end
    if x <= 0xFF
        # a changed failure bit must be read twice the same before it is taken
        if statusSeen = 1 and getbits(x, 0, 2) != getbits(gearStatus, 0, 2)
            y := modbusr(SH, 511, uint16); if (y != 0x8000, cntStale := cntStale + 1);
            modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x90);
            sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
            y := modbusr(SH, 511, uint16);
            cntQ := cntQ + 1; if (y = 0x8000, cntNone := cntNone + 1); if (y = 0x20FF, cntColl := cntColl + 1);
            if y != x
                cntBad := cntBad + 1;
                x := gearStatus;
            end
        end
        if statusSeen = 0
            ignGear := getbit(x, 0);
            ignLamp := getbit(x, 1);
            statusSeen := 1;
        end
        # a bit that clears ends its ignore, so a later failure is raised
        if (getbit(x, 0) = 0, ignGear := 0);
        if (getbit(x, 1) = 0, ignLamp := 0);
        gearStatus := x;
        checkStatus := 60;
        statusPoll := 60;
    else
        if x = 0x8000
            Status := RANDINT(10, 60);
            adderror(3, "Gear not responding!");
            return(0);
        end
    end
end

# messages last one run only, so they are raised from the stored status on every run
if ((getbit(gearStatus, 0) = 1) and (ignGear = 0), adderror(1, "Control gear failure!"));
if ((getbit(gearStatus, 1) = 1) and (ignLamp = 0), adderror(2, "Lamp failure!"));
Inizializzazione
var x := 0; var rx := 0;
# QUERY STATUS 0x90: every reply byte proves the gear is present; 0x8000 = no answer, 0x20FF = bus collision
# an unread answer left in the gateway would be taken for this query: read it away and count it
x := modbusr(SH, 511, uint16); if (x != 0x8000, cntStale := cntStale + 1);
modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x90);
sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
x := modbusr(SH, 511, uint16);
cntQ := cntQ + 1; if (x = 0x8000, cntNone := cntNone + 1); if (x = 0x20FF, cntColl := cntColl + 1);
statusSeen := 0;
if x <= 0xFF
    # failure bits a gear reports from its first answer are its permanent state, not an event: shown, not raised
    gearStatus := x;
    ignGear := getbit(x, 0);
    ignLamp := getbit(x, 1);
    statusSeen := 1;
    Status := 0;
else
    Status := RANDINT(1, 60);
end

if Status = 0
    x := modbusr(SH, 511, uint16); if (x != 0x8000, cntStale := cntStale + 1);
    modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA2);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    x := modbusr(SH, 511, uint16);
    cntQ := cntQ + 1; if (x = 0x8000, cntNone := cntNone + 1); if (x = 0x20FF, cntColl := cntColl + 1);
    if (x <= 0xFE, minLevel := x);

    x := modbusr(SH, 511, uint16); if (x != 0x8000, cntStale := cntStale + 1);
    modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA1);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    x := modbusr(SH, 511, uint16);
    cntQ := cntQ + 1; if (x = 0x8000, cntNone := cntNone + 1); if (x = 0x20FF, cntColl := cntColl + 1);
    if (x <= 0xFE, maxLevel := x);
end
Lettura livello
var x := 0; var rx := 0; var y := 0;
if Status = 0
    if minLevel = 0
        # an unread answer left in the gateway would be taken for this query: read it away and count it
        x := modbusr(SH, 511, uint16); if (x != 0x8000, cntStale := cntStale + 1);
        modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA2);
        sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
        x := modbusr(SH, 511, uint16);
        cntQ := cntQ + 1; if (x = 0x8000, cntNone := cntNone + 1); if (x = 0x20FF, cntColl := cntColl + 1);
        if (x <= 0xFE, minLevel := x);
    end
    x := modbusr(SH, 511, uint16); if (x != 0x8000, cntStale := cntStale + 1);
    modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA0);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    x := modbusr(SH, 511, uint16);
    cntQ := cntQ + 1; if (x = 0x8000, cntNone := cntNone + 1); if (x = 0x20FF, cntColl := cntColl + 1);
    if (x != 0x8000 or rx, checkStatus := 60);
    # 0xFF = MASK, 0x20FF = collision, 0x8000 = no answer: keep the last level instead of a phantom value
    if x > 0xFE
        return(Le);
    end
    # an actual level is 0 or between the gear's min and max: anything else is not this gear's answer
    if x > 0 and x < minLevel
        cntBad := cntBad + 1;
        return(Le);
    end
    # a changed level must be read twice the same before it is taken
    if x != lastRaw
        y := modbusr(SH, 511, uint16); if (y != 0x8000, cntStale := cntStale + 1);
        modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA0);
        sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
        y := modbusr(SH, 511, uint16);
        cntQ := cntQ + 1; if (y = 0x8000, cntNone := cntNone + 1); if (y = 0x20FF, cntColl := cntColl + 1);
        if y != x
            cntBad := cntBad + 1;
            return(Le);
        end
        lastRaw := x;
    end
    return(if(x = 0, 0, linear(x, minLevel, 0.01, maxLevel, 1)));
else
    return(NaN);
end
Scrittura livello
var level := 0;
if(Le > 0, level := round(linear(Le, 0.01, minLevel, 1, maxLevel)));
modbusw(SH, 510, uint16, (ShortAddress << 8) + level );
Attributi di servizio
${xml_short_address}
ShortAddress
${xml_device_type}
var x := 0; var y := 0; var rx := 0; var s := ""; var i := 0;
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x99);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    x := modbusr(SH, 511, uint16);
    if (x < 0xFF, return("DT" + x));
    if x = 0xFF
        while i < 8
            modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA7);
            sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
            y := modbusr(SH, 511, uint16);
            if y < 0xFE
                s := if(s = "", "DT" + y, s + ", DT" + y);
                i := i + 1;
            else
                i := 8;
            end
        loop
        return(if(s = "", "MASK", s));
    end
end

return("--")
Physical Min Level
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x9A);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if (x <= 0xFE, return(round((x / 0xFE) * 100) + " %"));
end

return("--")
Max Level
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA1);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if (x <= 0xFE, return(round((x / 0xFE) * 100) + " %"));
end

return("--")
Min Level
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA2);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if (x <= 0xFE, return(round((x / 0xFE) * 100) + " %"));
end

return("--")
Power Up Level
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA3);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if (x <= 0xFE, return(round((x / 0xFE) * 100) + " %"));
end

return("--")
System Failure Level
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA4);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if (x <= 0xFE, return(round((x / 0xFE) * 100) + " %"));
end

return("--")
${xml_groups}
var x := 0; var rx := 0;
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xC0);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var g1 := modbusr(SH, 511, uint16);
    if (g1 > 0xFF, return("--")); 

    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xC1);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var g2 := modbusr(SH, 511, uint16);
    if (g2 > 0xFF, return("--")); 

    var ret := "";

    if (getbit(g1, 0), ret := ret + "0");
    if (getbit(g1, 1), if (ret = "", ret := "1", ret := ret + ",1"));
    if (getbit(g1, 2), if (ret = "", ret := "2", ret := ret + ",2"));
    if (getbit(g1, 3), if (ret = "", ret := "3", ret := ret + ",3"));
    if (getbit(g1, 4), if (ret = "", ret := "4", ret := ret + ",4"));
    if (getbit(g1, 5), if (ret = "", ret := "5", ret := ret + ",5"));
    if (getbit(g1, 6), if (ret = "", ret := "6", ret := ret + ",6"));
    if (getbit(g1, 7), if (ret = "", ret := "7", ret := ret + ",7"));
    if (getbit(g2, 0), if (ret = "", ret := "8", ret := ret + ",8"));
    if (getbit(g2, 1), if (ret = "", ret := "9", ret := ret + ",9"));
    if (getbit(g2, 2), if (ret = "", ret := "10", ret := ret + ",10"));
    if (getbit(g2, 3), if (ret = "", ret := "11", ret := ret + ",11"));
    if (getbit(g2, 4), if (ret = "", ret := "12", ret := ret + ",12"));
    if (getbit(g2, 5), if (ret = "", ret := "13", ret := ret + ",13"));
    if (getbit(g2, 6), if (ret = "", ret := "14", ret := ret + ",14"));
    if (getbit(g2, 7), if (ret = "", ret := "15", ret := ret + ",15"));

    if (ret = "", return("None"), return(ret));
else
    return("--");
end
DALI Status
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x90);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if x <= 0xFF
        var s := "";
        if (getbit(x, 0), s := if(s = "", "gear failure", s + ", gear failure"));
        if (getbit(x, 1), s := if(s = "", "lamp failure", s + ", lamp failure"));
        if (getbit(x, 2), s := if(s = "", "lamp on", s + ", lamp on"));
        if (getbit(x, 3), s := if(s = "", "limit error", s + ", limit error"));
        if (getbit(x, 4), s := if(s = "", "fade running", s + ", fade running"));
        if (getbit(x, 5), s := if(s = "", "reset state", s + ", reset state"));
        if (getbit(x, 6), s := if(s = "", "missing short address", s + ", missing short address"));
        if (getbit(x, 7), s := if(s = "", "power cycle", s + ", power cycle"));
        var ign := if((ignGear = 1) and (ignLamp = 1), "gear and lamp failure", if(ignGear = 1, "gear failure", if(ignLamp = 1, "lamp failure", "")));
        return(if(s = "", "OK", s) + " (0x" + tostring(x, "X2") + ")" + if(ign = "", "", "; not raised: " + ign + " reported since start"));
    end
end

return("--")
Fade
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA5);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if x <= 0xFF
        var t := getbits(x, 4, 4);
        var ret := if(t = 0, "off", t + " (" + round(sqrt(power(2, t)) * 5) / 10 + " s)");
        modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA8);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
        var e := modbusr(SH, 511, uint16);
        if (t = 0 and e <= 0xFF and e != 0, ret := "extended 0x" + tostring(e, "X2"));
        return("fade time " + ret + ", fade rate " + getbits(x, 0, 4));
    end
end

return("--")
DALI Version
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x97);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if x <= 0xFF
        return(if(x >= 8, "DALI-2 " + getbits(x, 2, 6) + "." + getbits(x, 0, 2), "DALI-1") + " (" + x + ")");
    end
end

return("--")
Bus statistics
return("since start: queries " + cntQ + ", stale answers read away " + cntStale + ", no answer " + cntNone + ", collisions " + cntColl + ", rejected levels " + cntBad)
Azioni di servizio
${xml_add_to_group}
Parametri: Group ID (0–15 grp)
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x60 + grp);
${xml_remove_from_group}
Parametri: Group ID (0–15 grp)
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x70 + grp);
${xml_reset_to_default_settings}
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x20);
${xml_set_startup_levels}
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x21);
sleep(10);
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x2c);
sleep(10);
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x2d);
Disable fading
modbusw(SH, 541, uint16, 0xA300);
sleep(100);
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x2E);
sleep(100);
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x30);
Gear 46 Dimmer Lettura e scrittura

Dispositivo di controllo DALI all'indirizzo breve 46 — dimmer TapHome mappato su DALI arc power 0–100 % tramite H:510 LAMP LEVEL (scrittura) e QUERY ACTUAL LEVEL tramite H:511 (lettura), delimitato dai propri MIN / MAX LEVEL del gear.

Registro: H:511 → H:510 UInt16 Unità: % numeric
Attributi di servizio
Indirizzo breveIndirizzo breve DALI (0–63) target di questo dispositivo — fissato al momento dell'importazione del template e utilizzato nel byte alto di ogni scrittura Modbus.
Device TypeByte device-type DALI restituito da QUERY DEVICE TYPE (0x99) — riporta DT0 (fluorescente), DT6 (driver LED), DT8 (colore / tunable white) ecc., o -- quando non c'è risposta.
Physical Min LevelLivello minimo di dimmerazione imposto dall'hardware riportato dal gear — letto da QUERY PHYSICAL MIN LEVEL (0x9A), in percentuale.
Max LevelDALI MAX LEVEL configurato — letto da QUERY MAX LEVEL (0xA1); utilizzato come limite superiore durante la scalatura di TapHome 0–100 % su DALI arc power.
Min LevelDALI MIN LEVEL configurato — letto da QUERY MIN LEVEL (0xA2); utilizzato come limite inferiore durante la scalatura di TapHome 0–100 % su DALI arc power.
Power Up LevelLuminosità ripristinata dopo il ripristino dell'alimentazione del bus DALI — letta da QUERY POWER ON LEVEL (0xA3).
System Failure LevelLuminosità adottata quando il bus DALI perde la comunicazione per più di 500 ms — letta da QUERY SYSTEM FAILURE LEVEL (0xA4).
GruppiElenco separato da virgole dei gruppi DALI (0–15) a cui appartiene il gear — decodificato da QUERY GROUPS 0-7 (0xC0) e QUERY GROUPS 8-15 (0xC1); mostra None o ad es. 0,3,7.
Support Lamp FailureSe la lampada / driver supporta il rilevamento dei guasti della lampada — Yes / No / --. Gestisce l'errore Lamp failure! nel readscript periodico.
Support Power FailureSe la lampada / driver supporta il rilevamento dei guasti di alimentazione — Yes / No / --. Gestisce l'errore Power failure! nel readscript periodico.
DALI Version
Bus statistics
Azioni di servizio
Add to GroupAggiunge questo gear a un gruppo DALI (0–15) tramite ADD TO GROUP (0x60+grp) — auto-ripetuto entro 100 ms come richiesto per i comandi di configurazione DALI.
Remove from GroupRimuove questo gear da un gruppo DALI (0–15) tramite REMOVE FROM GROUP (0x70+grp).
Reset to Default SettingsInvia DALI RESET (0x20) — ripristina ogni parametro NVM del gear (livelli max / min / power-on / system-failure, appartenenza al gruppo, scene) al valore predefinito del produttore.
Set Startup LevelsCattura l'arc power corrente e la memorizza come Power On Level e System Failure Level — sequenza STORE ACTUAL LEVEL IN DTR (0x21) → STORE DTR AS POWER ON LEVEL (0x2C) → STORE DTR AS SYSTEM FAILURE LEVEL (0x2D).
Disable fading

Gear 46

Lettura (modulo)
var x := 0; var rx := 0; var y := 0;
if Status > 0
    Status := Status - 1;
    adderror(3, "Gear not responding!");
    return(0);
end

# checkStatus: ReadLevel resets it while the gear answers; statusPoll: QUERY STATUS at least once per 60 runs
checkStatus := checkStatus - 1;
statusPoll := statusPoll - 1;
if checkStatus < 1 or statusPoll < 1
    # an unread answer left in the gateway would be taken for this query: read it away and count it
    x := modbusr(SH, 511, uint16); if (x != 0x8000, cntStale := cntStale + 1);
    modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x90);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    x := modbusr(SH, 511, uint16);
    cntQ := cntQ + 1; if (x = 0x8000, cntNone := cntNone + 1); if (x = 0x20FF, cntColl := cntColl + 1);
    # a single lost answer happens on DALI: ask once more before declaring the gear missing
    if x = 0x8000
        x := modbusr(SH, 511, uint16); if (x != 0x8000, cntStale := cntStale + 1);
        modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x90);
        sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
        x := modbusr(SH, 511, uint16);
        cntQ := cntQ + 1; if (x = 0x8000, cntNone := cntNone + 1); if (x = 0x20FF, cntColl := cntColl + 1);
    end
    if x <= 0xFF
        # a changed failure bit must be read twice the same before it is taken
        if statusSeen = 1 and getbits(x, 0, 2) != getbits(gearStatus, 0, 2)
            y := modbusr(SH, 511, uint16); if (y != 0x8000, cntStale := cntStale + 1);
            modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x90);
            sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
            y := modbusr(SH, 511, uint16);
            cntQ := cntQ + 1; if (y = 0x8000, cntNone := cntNone + 1); if (y = 0x20FF, cntColl := cntColl + 1);
            if y != x
                cntBad := cntBad + 1;
                x := gearStatus;
            end
        end
        if statusSeen = 0
            ignGear := getbit(x, 0);
            ignLamp := getbit(x, 1);
            statusSeen := 1;
        end
        # a bit that clears ends its ignore, so a later failure is raised
        if (getbit(x, 0) = 0, ignGear := 0);
        if (getbit(x, 1) = 0, ignLamp := 0);
        gearStatus := x;
        checkStatus := 60;
        statusPoll := 60;
    else
        if x = 0x8000
            Status := RANDINT(10, 60);
            adderror(3, "Gear not responding!");
            return(0);
        end
    end
end

# messages last one run only, so they are raised from the stored status on every run
if ((getbit(gearStatus, 0) = 1) and (ignGear = 0), adderror(1, "Control gear failure!"));
if ((getbit(gearStatus, 1) = 1) and (ignLamp = 0), adderror(2, "Lamp failure!"));
Inizializzazione
var x := 0; var rx := 0;
# QUERY STATUS 0x90: every reply byte proves the gear is present; 0x8000 = no answer, 0x20FF = bus collision
# an unread answer left in the gateway would be taken for this query: read it away and count it
x := modbusr(SH, 511, uint16); if (x != 0x8000, cntStale := cntStale + 1);
modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x90);
sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
x := modbusr(SH, 511, uint16);
cntQ := cntQ + 1; if (x = 0x8000, cntNone := cntNone + 1); if (x = 0x20FF, cntColl := cntColl + 1);
statusSeen := 0;
if x <= 0xFF
    # failure bits a gear reports from its first answer are its permanent state, not an event: shown, not raised
    gearStatus := x;
    ignGear := getbit(x, 0);
    ignLamp := getbit(x, 1);
    statusSeen := 1;
    Status := 0;
else
    Status := RANDINT(1, 60);
end

if Status = 0
    x := modbusr(SH, 511, uint16); if (x != 0x8000, cntStale := cntStale + 1);
    modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA2);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    x := modbusr(SH, 511, uint16);
    cntQ := cntQ + 1; if (x = 0x8000, cntNone := cntNone + 1); if (x = 0x20FF, cntColl := cntColl + 1);
    if (x <= 0xFE, minLevel := x);

    x := modbusr(SH, 511, uint16); if (x != 0x8000, cntStale := cntStale + 1);
    modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA1);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    x := modbusr(SH, 511, uint16);
    cntQ := cntQ + 1; if (x = 0x8000, cntNone := cntNone + 1); if (x = 0x20FF, cntColl := cntColl + 1);
    if (x <= 0xFE, maxLevel := x);
end
Lettura livello
var x := 0; var rx := 0; var y := 0;
if Status = 0
    if minLevel = 0
        # an unread answer left in the gateway would be taken for this query: read it away and count it
        x := modbusr(SH, 511, uint16); if (x != 0x8000, cntStale := cntStale + 1);
        modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA2);
        sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
        x := modbusr(SH, 511, uint16);
        cntQ := cntQ + 1; if (x = 0x8000, cntNone := cntNone + 1); if (x = 0x20FF, cntColl := cntColl + 1);
        if (x <= 0xFE, minLevel := x);
    end
    x := modbusr(SH, 511, uint16); if (x != 0x8000, cntStale := cntStale + 1);
    modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA0);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    x := modbusr(SH, 511, uint16);
    cntQ := cntQ + 1; if (x = 0x8000, cntNone := cntNone + 1); if (x = 0x20FF, cntColl := cntColl + 1);
    if (x != 0x8000 or rx, checkStatus := 60);
    # 0xFF = MASK, 0x20FF = collision, 0x8000 = no answer: keep the last level instead of a phantom value
    if x > 0xFE
        return(Le);
    end
    # an actual level is 0 or between the gear's min and max: anything else is not this gear's answer
    if x > 0 and x < minLevel
        cntBad := cntBad + 1;
        return(Le);
    end
    # a changed level must be read twice the same before it is taken
    if x != lastRaw
        y := modbusr(SH, 511, uint16); if (y != 0x8000, cntStale := cntStale + 1);
        modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA0);
        sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
        y := modbusr(SH, 511, uint16);
        cntQ := cntQ + 1; if (y = 0x8000, cntNone := cntNone + 1); if (y = 0x20FF, cntColl := cntColl + 1);
        if y != x
            cntBad := cntBad + 1;
            return(Le);
        end
        lastRaw := x;
    end
    return(if(x = 0, 0, linear(x, minLevel, 0.01, maxLevel, 1)));
else
    return(NaN);
end
Scrittura livello
var level := 0;
if(Le > 0, level := round(linear(Le, 0.01, minLevel, 1, maxLevel)));
modbusw(SH, 510, uint16, (ShortAddress << 8) + level );
Attributi di servizio
${xml_short_address}
ShortAddress
${xml_device_type}
var x := 0; var y := 0; var rx := 0; var s := ""; var i := 0;
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x99);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    x := modbusr(SH, 511, uint16);
    if (x < 0xFF, return("DT" + x));
    if x = 0xFF
        while i < 8
            modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA7);
            sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
            y := modbusr(SH, 511, uint16);
            if y < 0xFE
                s := if(s = "", "DT" + y, s + ", DT" + y);
                i := i + 1;
            else
                i := 8;
            end
        loop
        return(if(s = "", "MASK", s));
    end
end

return("--")
Physical Min Level
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x9A);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if (x <= 0xFE, return(round((x / 0xFE) * 100) + " %"));
end

return("--")
Max Level
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA1);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if (x <= 0xFE, return(round((x / 0xFE) * 100) + " %"));
end

return("--")
Min Level
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA2);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if (x <= 0xFE, return(round((x / 0xFE) * 100) + " %"));
end

return("--")
Power Up Level
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA3);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if (x <= 0xFE, return(round((x / 0xFE) * 100) + " %"));
end

return("--")
System Failure Level
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA4);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if (x <= 0xFE, return(round((x / 0xFE) * 100) + " %"));
end

return("--")
${xml_groups}
var x := 0; var rx := 0;
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xC0);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var g1 := modbusr(SH, 511, uint16);
    if (g1 > 0xFF, return("--")); 

    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xC1);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var g2 := modbusr(SH, 511, uint16);
    if (g2 > 0xFF, return("--")); 

    var ret := "";

    if (getbit(g1, 0), ret := ret + "0");
    if (getbit(g1, 1), if (ret = "", ret := "1", ret := ret + ",1"));
    if (getbit(g1, 2), if (ret = "", ret := "2", ret := ret + ",2"));
    if (getbit(g1, 3), if (ret = "", ret := "3", ret := ret + ",3"));
    if (getbit(g1, 4), if (ret = "", ret := "4", ret := ret + ",4"));
    if (getbit(g1, 5), if (ret = "", ret := "5", ret := ret + ",5"));
    if (getbit(g1, 6), if (ret = "", ret := "6", ret := ret + ",6"));
    if (getbit(g1, 7), if (ret = "", ret := "7", ret := ret + ",7"));
    if (getbit(g2, 0), if (ret = "", ret := "8", ret := ret + ",8"));
    if (getbit(g2, 1), if (ret = "", ret := "9", ret := ret + ",9"));
    if (getbit(g2, 2), if (ret = "", ret := "10", ret := ret + ",10"));
    if (getbit(g2, 3), if (ret = "", ret := "11", ret := ret + ",11"));
    if (getbit(g2, 4), if (ret = "", ret := "12", ret := ret + ",12"));
    if (getbit(g2, 5), if (ret = "", ret := "13", ret := ret + ",13"));
    if (getbit(g2, 6), if (ret = "", ret := "14", ret := ret + ",14"));
    if (getbit(g2, 7), if (ret = "", ret := "15", ret := ret + ",15"));

    if (ret = "", return("None"), return(ret));
else
    return("--");
end
DALI Status
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x90);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if x <= 0xFF
        var s := "";
        if (getbit(x, 0), s := if(s = "", "gear failure", s + ", gear failure"));
        if (getbit(x, 1), s := if(s = "", "lamp failure", s + ", lamp failure"));
        if (getbit(x, 2), s := if(s = "", "lamp on", s + ", lamp on"));
        if (getbit(x, 3), s := if(s = "", "limit error", s + ", limit error"));
        if (getbit(x, 4), s := if(s = "", "fade running", s + ", fade running"));
        if (getbit(x, 5), s := if(s = "", "reset state", s + ", reset state"));
        if (getbit(x, 6), s := if(s = "", "missing short address", s + ", missing short address"));
        if (getbit(x, 7), s := if(s = "", "power cycle", s + ", power cycle"));
        var ign := if((ignGear = 1) and (ignLamp = 1), "gear and lamp failure", if(ignGear = 1, "gear failure", if(ignLamp = 1, "lamp failure", "")));
        return(if(s = "", "OK", s) + " (0x" + tostring(x, "X2") + ")" + if(ign = "", "", "; not raised: " + ign + " reported since start"));
    end
end

return("--")
Fade
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA5);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if x <= 0xFF
        var t := getbits(x, 4, 4);
        var ret := if(t = 0, "off", t + " (" + round(sqrt(power(2, t)) * 5) / 10 + " s)");
        modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA8);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
        var e := modbusr(SH, 511, uint16);
        if (t = 0 and e <= 0xFF and e != 0, ret := "extended 0x" + tostring(e, "X2"));
        return("fade time " + ret + ", fade rate " + getbits(x, 0, 4));
    end
end

return("--")
DALI Version
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x97);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if x <= 0xFF
        return(if(x >= 8, "DALI-2 " + getbits(x, 2, 6) + "." + getbits(x, 0, 2), "DALI-1") + " (" + x + ")");
    end
end

return("--")
Bus statistics
return("since start: queries " + cntQ + ", stale answers read away " + cntStale + ", no answer " + cntNone + ", collisions " + cntColl + ", rejected levels " + cntBad)
Azioni di servizio
${xml_add_to_group}
Parametri: Group ID (0–15 grp)
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x60 + grp);
${xml_remove_from_group}
Parametri: Group ID (0–15 grp)
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x70 + grp);
${xml_reset_to_default_settings}
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x20);
${xml_set_startup_levels}
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x21);
sleep(10);
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x2c);
sleep(10);
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x2d);
Disable fading
modbusw(SH, 541, uint16, 0xA300);
sleep(100);
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x2E);
sleep(100);
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x30);
Gear 47 Dimmer Lettura e scrittura

Dispositivo di controllo DALI all'indirizzo breve 47 — dimmer TapHome mappato su DALI arc power 0–100 % tramite H:510 LAMP LEVEL (scrittura) e QUERY ACTUAL LEVEL tramite H:511 (lettura), delimitato dai propri MIN / MAX LEVEL del gear.

Registro: H:511 → H:510 UInt16 Unità: % numeric
Attributi di servizio
Indirizzo breveIndirizzo breve DALI (0–63) target di questo dispositivo — fissato al momento dell'importazione del template e utilizzato nel byte alto di ogni scrittura Modbus.
Device TypeByte device-type DALI restituito da QUERY DEVICE TYPE (0x99) — riporta DT0 (fluorescente), DT6 (driver LED), DT8 (colore / tunable white) ecc., o -- quando non c'è risposta.
Physical Min LevelLivello minimo di dimmerazione imposto dall'hardware riportato dal gear — letto da QUERY PHYSICAL MIN LEVEL (0x9A), in percentuale.
Max LevelDALI MAX LEVEL configurato — letto da QUERY MAX LEVEL (0xA1); utilizzato come limite superiore durante la scalatura di TapHome 0–100 % su DALI arc power.
Min LevelDALI MIN LEVEL configurato — letto da QUERY MIN LEVEL (0xA2); utilizzato come limite inferiore durante la scalatura di TapHome 0–100 % su DALI arc power.
Power Up LevelLuminosità ripristinata dopo il ripristino dell'alimentazione del bus DALI — letta da QUERY POWER ON LEVEL (0xA3).
System Failure LevelLuminosità adottata quando il bus DALI perde la comunicazione per più di 500 ms — letta da QUERY SYSTEM FAILURE LEVEL (0xA4).
GruppiElenco separato da virgole dei gruppi DALI (0–15) a cui appartiene il gear — decodificato da QUERY GROUPS 0-7 (0xC0) e QUERY GROUPS 8-15 (0xC1); mostra None o ad es. 0,3,7.
Support Lamp FailureSe la lampada / driver supporta il rilevamento dei guasti della lampada — Yes / No / --. Gestisce l'errore Lamp failure! nel readscript periodico.
Support Power FailureSe la lampada / driver supporta il rilevamento dei guasti di alimentazione — Yes / No / --. Gestisce l'errore Power failure! nel readscript periodico.
DALI Version
Bus statistics
Azioni di servizio
Add to GroupAggiunge questo gear a un gruppo DALI (0–15) tramite ADD TO GROUP (0x60+grp) — auto-ripetuto entro 100 ms come richiesto per i comandi di configurazione DALI.
Remove from GroupRimuove questo gear da un gruppo DALI (0–15) tramite REMOVE FROM GROUP (0x70+grp).
Reset to Default SettingsInvia DALI RESET (0x20) — ripristina ogni parametro NVM del gear (livelli max / min / power-on / system-failure, appartenenza al gruppo, scene) al valore predefinito del produttore.
Set Startup LevelsCattura l'arc power corrente e la memorizza come Power On Level e System Failure Level — sequenza STORE ACTUAL LEVEL IN DTR (0x21) → STORE DTR AS POWER ON LEVEL (0x2C) → STORE DTR AS SYSTEM FAILURE LEVEL (0x2D).
Disable fading

Gear 47

Lettura (modulo)
var x := 0; var rx := 0; var y := 0;
if Status > 0
    Status := Status - 1;
    adderror(3, "Gear not responding!");
    return(0);
end

# checkStatus: ReadLevel resets it while the gear answers; statusPoll: QUERY STATUS at least once per 60 runs
checkStatus := checkStatus - 1;
statusPoll := statusPoll - 1;
if checkStatus < 1 or statusPoll < 1
    # an unread answer left in the gateway would be taken for this query: read it away and count it
    x := modbusr(SH, 511, uint16); if (x != 0x8000, cntStale := cntStale + 1);
    modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x90);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    x := modbusr(SH, 511, uint16);
    cntQ := cntQ + 1; if (x = 0x8000, cntNone := cntNone + 1); if (x = 0x20FF, cntColl := cntColl + 1);
    # a single lost answer happens on DALI: ask once more before declaring the gear missing
    if x = 0x8000
        x := modbusr(SH, 511, uint16); if (x != 0x8000, cntStale := cntStale + 1);
        modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x90);
        sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
        x := modbusr(SH, 511, uint16);
        cntQ := cntQ + 1; if (x = 0x8000, cntNone := cntNone + 1); if (x = 0x20FF, cntColl := cntColl + 1);
    end
    if x <= 0xFF
        # a changed failure bit must be read twice the same before it is taken
        if statusSeen = 1 and getbits(x, 0, 2) != getbits(gearStatus, 0, 2)
            y := modbusr(SH, 511, uint16); if (y != 0x8000, cntStale := cntStale + 1);
            modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x90);
            sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
            y := modbusr(SH, 511, uint16);
            cntQ := cntQ + 1; if (y = 0x8000, cntNone := cntNone + 1); if (y = 0x20FF, cntColl := cntColl + 1);
            if y != x
                cntBad := cntBad + 1;
                x := gearStatus;
            end
        end
        if statusSeen = 0
            ignGear := getbit(x, 0);
            ignLamp := getbit(x, 1);
            statusSeen := 1;
        end
        # a bit that clears ends its ignore, so a later failure is raised
        if (getbit(x, 0) = 0, ignGear := 0);
        if (getbit(x, 1) = 0, ignLamp := 0);
        gearStatus := x;
        checkStatus := 60;
        statusPoll := 60;
    else
        if x = 0x8000
            Status := RANDINT(10, 60);
            adderror(3, "Gear not responding!");
            return(0);
        end
    end
end

# messages last one run only, so they are raised from the stored status on every run
if ((getbit(gearStatus, 0) = 1) and (ignGear = 0), adderror(1, "Control gear failure!"));
if ((getbit(gearStatus, 1) = 1) and (ignLamp = 0), adderror(2, "Lamp failure!"));
Inizializzazione
var x := 0; var rx := 0;
# QUERY STATUS 0x90: every reply byte proves the gear is present; 0x8000 = no answer, 0x20FF = bus collision
# an unread answer left in the gateway would be taken for this query: read it away and count it
x := modbusr(SH, 511, uint16); if (x != 0x8000, cntStale := cntStale + 1);
modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x90);
sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
x := modbusr(SH, 511, uint16);
cntQ := cntQ + 1; if (x = 0x8000, cntNone := cntNone + 1); if (x = 0x20FF, cntColl := cntColl + 1);
statusSeen := 0;
if x <= 0xFF
    # failure bits a gear reports from its first answer are its permanent state, not an event: shown, not raised
    gearStatus := x;
    ignGear := getbit(x, 0);
    ignLamp := getbit(x, 1);
    statusSeen := 1;
    Status := 0;
else
    Status := RANDINT(1, 60);
end

if Status = 0
    x := modbusr(SH, 511, uint16); if (x != 0x8000, cntStale := cntStale + 1);
    modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA2);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    x := modbusr(SH, 511, uint16);
    cntQ := cntQ + 1; if (x = 0x8000, cntNone := cntNone + 1); if (x = 0x20FF, cntColl := cntColl + 1);
    if (x <= 0xFE, minLevel := x);

    x := modbusr(SH, 511, uint16); if (x != 0x8000, cntStale := cntStale + 1);
    modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA1);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    x := modbusr(SH, 511, uint16);
    cntQ := cntQ + 1; if (x = 0x8000, cntNone := cntNone + 1); if (x = 0x20FF, cntColl := cntColl + 1);
    if (x <= 0xFE, maxLevel := x);
end
Lettura livello
var x := 0; var rx := 0; var y := 0;
if Status = 0
    if minLevel = 0
        # an unread answer left in the gateway would be taken for this query: read it away and count it
        x := modbusr(SH, 511, uint16); if (x != 0x8000, cntStale := cntStale + 1);
        modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA2);
        sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
        x := modbusr(SH, 511, uint16);
        cntQ := cntQ + 1; if (x = 0x8000, cntNone := cntNone + 1); if (x = 0x20FF, cntColl := cntColl + 1);
        if (x <= 0xFE, minLevel := x);
    end
    x := modbusr(SH, 511, uint16); if (x != 0x8000, cntStale := cntStale + 1);
    modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA0);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    x := modbusr(SH, 511, uint16);
    cntQ := cntQ + 1; if (x = 0x8000, cntNone := cntNone + 1); if (x = 0x20FF, cntColl := cntColl + 1);
    if (x != 0x8000 or rx, checkStatus := 60);
    # 0xFF = MASK, 0x20FF = collision, 0x8000 = no answer: keep the last level instead of a phantom value
    if x > 0xFE
        return(Le);
    end
    # an actual level is 0 or between the gear's min and max: anything else is not this gear's answer
    if x > 0 and x < minLevel
        cntBad := cntBad + 1;
        return(Le);
    end
    # a changed level must be read twice the same before it is taken
    if x != lastRaw
        y := modbusr(SH, 511, uint16); if (y != 0x8000, cntStale := cntStale + 1);
        modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA0);
        sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
        y := modbusr(SH, 511, uint16);
        cntQ := cntQ + 1; if (y = 0x8000, cntNone := cntNone + 1); if (y = 0x20FF, cntColl := cntColl + 1);
        if y != x
            cntBad := cntBad + 1;
            return(Le);
        end
        lastRaw := x;
    end
    return(if(x = 0, 0, linear(x, minLevel, 0.01, maxLevel, 1)));
else
    return(NaN);
end
Scrittura livello
var level := 0;
if(Le > 0, level := round(linear(Le, 0.01, minLevel, 1, maxLevel)));
modbusw(SH, 510, uint16, (ShortAddress << 8) + level );
Attributi di servizio
${xml_short_address}
ShortAddress
${xml_device_type}
var x := 0; var y := 0; var rx := 0; var s := ""; var i := 0;
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x99);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    x := modbusr(SH, 511, uint16);
    if (x < 0xFF, return("DT" + x));
    if x = 0xFF
        while i < 8
            modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA7);
            sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
            y := modbusr(SH, 511, uint16);
            if y < 0xFE
                s := if(s = "", "DT" + y, s + ", DT" + y);
                i := i + 1;
            else
                i := 8;
            end
        loop
        return(if(s = "", "MASK", s));
    end
end

return("--")
Physical Min Level
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x9A);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if (x <= 0xFE, return(round((x / 0xFE) * 100) + " %"));
end

return("--")
Max Level
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA1);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if (x <= 0xFE, return(round((x / 0xFE) * 100) + " %"));
end

return("--")
Min Level
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA2);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if (x <= 0xFE, return(round((x / 0xFE) * 100) + " %"));
end

return("--")
Power Up Level
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA3);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if (x <= 0xFE, return(round((x / 0xFE) * 100) + " %"));
end

return("--")
System Failure Level
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA4);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if (x <= 0xFE, return(round((x / 0xFE) * 100) + " %"));
end

return("--")
${xml_groups}
var x := 0; var rx := 0;
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xC0);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var g1 := modbusr(SH, 511, uint16);
    if (g1 > 0xFF, return("--")); 

    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xC1);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var g2 := modbusr(SH, 511, uint16);
    if (g2 > 0xFF, return("--")); 

    var ret := "";

    if (getbit(g1, 0), ret := ret + "0");
    if (getbit(g1, 1), if (ret = "", ret := "1", ret := ret + ",1"));
    if (getbit(g1, 2), if (ret = "", ret := "2", ret := ret + ",2"));
    if (getbit(g1, 3), if (ret = "", ret := "3", ret := ret + ",3"));
    if (getbit(g1, 4), if (ret = "", ret := "4", ret := ret + ",4"));
    if (getbit(g1, 5), if (ret = "", ret := "5", ret := ret + ",5"));
    if (getbit(g1, 6), if (ret = "", ret := "6", ret := ret + ",6"));
    if (getbit(g1, 7), if (ret = "", ret := "7", ret := ret + ",7"));
    if (getbit(g2, 0), if (ret = "", ret := "8", ret := ret + ",8"));
    if (getbit(g2, 1), if (ret = "", ret := "9", ret := ret + ",9"));
    if (getbit(g2, 2), if (ret = "", ret := "10", ret := ret + ",10"));
    if (getbit(g2, 3), if (ret = "", ret := "11", ret := ret + ",11"));
    if (getbit(g2, 4), if (ret = "", ret := "12", ret := ret + ",12"));
    if (getbit(g2, 5), if (ret = "", ret := "13", ret := ret + ",13"));
    if (getbit(g2, 6), if (ret = "", ret := "14", ret := ret + ",14"));
    if (getbit(g2, 7), if (ret = "", ret := "15", ret := ret + ",15"));

    if (ret = "", return("None"), return(ret));
else
    return("--");
end
DALI Status
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x90);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if x <= 0xFF
        var s := "";
        if (getbit(x, 0), s := if(s = "", "gear failure", s + ", gear failure"));
        if (getbit(x, 1), s := if(s = "", "lamp failure", s + ", lamp failure"));
        if (getbit(x, 2), s := if(s = "", "lamp on", s + ", lamp on"));
        if (getbit(x, 3), s := if(s = "", "limit error", s + ", limit error"));
        if (getbit(x, 4), s := if(s = "", "fade running", s + ", fade running"));
        if (getbit(x, 5), s := if(s = "", "reset state", s + ", reset state"));
        if (getbit(x, 6), s := if(s = "", "missing short address", s + ", missing short address"));
        if (getbit(x, 7), s := if(s = "", "power cycle", s + ", power cycle"));
        var ign := if((ignGear = 1) and (ignLamp = 1), "gear and lamp failure", if(ignGear = 1, "gear failure", if(ignLamp = 1, "lamp failure", "")));
        return(if(s = "", "OK", s) + " (0x" + tostring(x, "X2") + ")" + if(ign = "", "", "; not raised: " + ign + " reported since start"));
    end
end

return("--")
Fade
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA5);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if x <= 0xFF
        var t := getbits(x, 4, 4);
        var ret := if(t = 0, "off", t + " (" + round(sqrt(power(2, t)) * 5) / 10 + " s)");
        modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA8);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
        var e := modbusr(SH, 511, uint16);
        if (t = 0 and e <= 0xFF and e != 0, ret := "extended 0x" + tostring(e, "X2"));
        return("fade time " + ret + ", fade rate " + getbits(x, 0, 4));
    end
end

return("--")
DALI Version
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x97);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if x <= 0xFF
        return(if(x >= 8, "DALI-2 " + getbits(x, 2, 6) + "." + getbits(x, 0, 2), "DALI-1") + " (" + x + ")");
    end
end

return("--")
Bus statistics
return("since start: queries " + cntQ + ", stale answers read away " + cntStale + ", no answer " + cntNone + ", collisions " + cntColl + ", rejected levels " + cntBad)
Azioni di servizio
${xml_add_to_group}
Parametri: Group ID (0–15 grp)
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x60 + grp);
${xml_remove_from_group}
Parametri: Group ID (0–15 grp)
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x70 + grp);
${xml_reset_to_default_settings}
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x20);
${xml_set_startup_levels}
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x21);
sleep(10);
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x2c);
sleep(10);
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x2d);
Disable fading
modbusw(SH, 541, uint16, 0xA300);
sleep(100);
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x2E);
sleep(100);
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x30);
Gear 48 Dimmer Lettura e scrittura

Dispositivo di controllo DALI all'indirizzo breve 48 — dimmer TapHome mappato su DALI arc power 0–100 % tramite H:510 LAMP LEVEL (scrittura) e QUERY ACTUAL LEVEL tramite H:511 (lettura), delimitato dai propri MIN / MAX LEVEL del gear.

Registro: H:511 → H:510 UInt16 Unità: % numeric
Attributi di servizio
Indirizzo breveIndirizzo breve DALI (0–63) target di questo dispositivo — fissato al momento dell'importazione del template e utilizzato nel byte alto di ogni scrittura Modbus.
Device TypeByte device-type DALI restituito da QUERY DEVICE TYPE (0x99) — riporta DT0 (fluorescente), DT6 (driver LED), DT8 (colore / tunable white) ecc., o -- quando non c'è risposta.
Physical Min LevelLivello minimo di dimmerazione imposto dall'hardware riportato dal gear — letto da QUERY PHYSICAL MIN LEVEL (0x9A), in percentuale.
Max LevelDALI MAX LEVEL configurato — letto da QUERY MAX LEVEL (0xA1); utilizzato come limite superiore durante la scalatura di TapHome 0–100 % su DALI arc power.
Min LevelDALI MIN LEVEL configurato — letto da QUERY MIN LEVEL (0xA2); utilizzato come limite inferiore durante la scalatura di TapHome 0–100 % su DALI arc power.
Power Up LevelLuminosità ripristinata dopo il ripristino dell'alimentazione del bus DALI — letta da QUERY POWER ON LEVEL (0xA3).
System Failure LevelLuminosità adottata quando il bus DALI perde la comunicazione per più di 500 ms — letta da QUERY SYSTEM FAILURE LEVEL (0xA4).
GruppiElenco separato da virgole dei gruppi DALI (0–15) a cui appartiene il gear — decodificato da QUERY GROUPS 0-7 (0xC0) e QUERY GROUPS 8-15 (0xC1); mostra None o ad es. 0,3,7.
Support Lamp FailureSe la lampada / driver supporta il rilevamento dei guasti della lampada — Yes / No / --. Gestisce l'errore Lamp failure! nel readscript periodico.
Support Power FailureSe la lampada / driver supporta il rilevamento dei guasti di alimentazione — Yes / No / --. Gestisce l'errore Power failure! nel readscript periodico.
DALI Version
Bus statistics
Azioni di servizio
Add to GroupAggiunge questo gear a un gruppo DALI (0–15) tramite ADD TO GROUP (0x60+grp) — auto-ripetuto entro 100 ms come richiesto per i comandi di configurazione DALI.
Remove from GroupRimuove questo gear da un gruppo DALI (0–15) tramite REMOVE FROM GROUP (0x70+grp).
Reset to Default SettingsInvia DALI RESET (0x20) — ripristina ogni parametro NVM del gear (livelli max / min / power-on / system-failure, appartenenza al gruppo, scene) al valore predefinito del produttore.
Set Startup LevelsCattura l'arc power corrente e la memorizza come Power On Level e System Failure Level — sequenza STORE ACTUAL LEVEL IN DTR (0x21) → STORE DTR AS POWER ON LEVEL (0x2C) → STORE DTR AS SYSTEM FAILURE LEVEL (0x2D).
Disable fading

Gear 48

Lettura (modulo)
var x := 0; var rx := 0; var y := 0;
if Status > 0
    Status := Status - 1;
    adderror(3, "Gear not responding!");
    return(0);
end

# checkStatus: ReadLevel resets it while the gear answers; statusPoll: QUERY STATUS at least once per 60 runs
checkStatus := checkStatus - 1;
statusPoll := statusPoll - 1;
if checkStatus < 1 or statusPoll < 1
    # an unread answer left in the gateway would be taken for this query: read it away and count it
    x := modbusr(SH, 511, uint16); if (x != 0x8000, cntStale := cntStale + 1);
    modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x90);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    x := modbusr(SH, 511, uint16);
    cntQ := cntQ + 1; if (x = 0x8000, cntNone := cntNone + 1); if (x = 0x20FF, cntColl := cntColl + 1);
    # a single lost answer happens on DALI: ask once more before declaring the gear missing
    if x = 0x8000
        x := modbusr(SH, 511, uint16); if (x != 0x8000, cntStale := cntStale + 1);
        modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x90);
        sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
        x := modbusr(SH, 511, uint16);
        cntQ := cntQ + 1; if (x = 0x8000, cntNone := cntNone + 1); if (x = 0x20FF, cntColl := cntColl + 1);
    end
    if x <= 0xFF
        # a changed failure bit must be read twice the same before it is taken
        if statusSeen = 1 and getbits(x, 0, 2) != getbits(gearStatus, 0, 2)
            y := modbusr(SH, 511, uint16); if (y != 0x8000, cntStale := cntStale + 1);
            modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x90);
            sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
            y := modbusr(SH, 511, uint16);
            cntQ := cntQ + 1; if (y = 0x8000, cntNone := cntNone + 1); if (y = 0x20FF, cntColl := cntColl + 1);
            if y != x
                cntBad := cntBad + 1;
                x := gearStatus;
            end
        end
        if statusSeen = 0
            ignGear := getbit(x, 0);
            ignLamp := getbit(x, 1);
            statusSeen := 1;
        end
        # a bit that clears ends its ignore, so a later failure is raised
        if (getbit(x, 0) = 0, ignGear := 0);
        if (getbit(x, 1) = 0, ignLamp := 0);
        gearStatus := x;
        checkStatus := 60;
        statusPoll := 60;
    else
        if x = 0x8000
            Status := RANDINT(10, 60);
            adderror(3, "Gear not responding!");
            return(0);
        end
    end
end

# messages last one run only, so they are raised from the stored status on every run
if ((getbit(gearStatus, 0) = 1) and (ignGear = 0), adderror(1, "Control gear failure!"));
if ((getbit(gearStatus, 1) = 1) and (ignLamp = 0), adderror(2, "Lamp failure!"));
Inizializzazione
var x := 0; var rx := 0;
# QUERY STATUS 0x90: every reply byte proves the gear is present; 0x8000 = no answer, 0x20FF = bus collision
# an unread answer left in the gateway would be taken for this query: read it away and count it
x := modbusr(SH, 511, uint16); if (x != 0x8000, cntStale := cntStale + 1);
modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x90);
sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
x := modbusr(SH, 511, uint16);
cntQ := cntQ + 1; if (x = 0x8000, cntNone := cntNone + 1); if (x = 0x20FF, cntColl := cntColl + 1);
statusSeen := 0;
if x <= 0xFF
    # failure bits a gear reports from its first answer are its permanent state, not an event: shown, not raised
    gearStatus := x;
    ignGear := getbit(x, 0);
    ignLamp := getbit(x, 1);
    statusSeen := 1;
    Status := 0;
else
    Status := RANDINT(1, 60);
end

if Status = 0
    x := modbusr(SH, 511, uint16); if (x != 0x8000, cntStale := cntStale + 1);
    modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA2);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    x := modbusr(SH, 511, uint16);
    cntQ := cntQ + 1; if (x = 0x8000, cntNone := cntNone + 1); if (x = 0x20FF, cntColl := cntColl + 1);
    if (x <= 0xFE, minLevel := x);

    x := modbusr(SH, 511, uint16); if (x != 0x8000, cntStale := cntStale + 1);
    modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA1);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    x := modbusr(SH, 511, uint16);
    cntQ := cntQ + 1; if (x = 0x8000, cntNone := cntNone + 1); if (x = 0x20FF, cntColl := cntColl + 1);
    if (x <= 0xFE, maxLevel := x);
end
Lettura livello
var x := 0; var rx := 0; var y := 0;
if Status = 0
    if minLevel = 0
        # an unread answer left in the gateway would be taken for this query: read it away and count it
        x := modbusr(SH, 511, uint16); if (x != 0x8000, cntStale := cntStale + 1);
        modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA2);
        sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
        x := modbusr(SH, 511, uint16);
        cntQ := cntQ + 1; if (x = 0x8000, cntNone := cntNone + 1); if (x = 0x20FF, cntColl := cntColl + 1);
        if (x <= 0xFE, minLevel := x);
    end
    x := modbusr(SH, 511, uint16); if (x != 0x8000, cntStale := cntStale + 1);
    modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA0);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    x := modbusr(SH, 511, uint16);
    cntQ := cntQ + 1; if (x = 0x8000, cntNone := cntNone + 1); if (x = 0x20FF, cntColl := cntColl + 1);
    if (x != 0x8000 or rx, checkStatus := 60);
    # 0xFF = MASK, 0x20FF = collision, 0x8000 = no answer: keep the last level instead of a phantom value
    if x > 0xFE
        return(Le);
    end
    # an actual level is 0 or between the gear's min and max: anything else is not this gear's answer
    if x > 0 and x < minLevel
        cntBad := cntBad + 1;
        return(Le);
    end
    # a changed level must be read twice the same before it is taken
    if x != lastRaw
        y := modbusr(SH, 511, uint16); if (y != 0x8000, cntStale := cntStale + 1);
        modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA0);
        sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
        y := modbusr(SH, 511, uint16);
        cntQ := cntQ + 1; if (y = 0x8000, cntNone := cntNone + 1); if (y = 0x20FF, cntColl := cntColl + 1);
        if y != x
            cntBad := cntBad + 1;
            return(Le);
        end
        lastRaw := x;
    end
    return(if(x = 0, 0, linear(x, minLevel, 0.01, maxLevel, 1)));
else
    return(NaN);
end
Scrittura livello
var level := 0;
if(Le > 0, level := round(linear(Le, 0.01, minLevel, 1, maxLevel)));
modbusw(SH, 510, uint16, (ShortAddress << 8) + level );
Attributi di servizio
${xml_short_address}
ShortAddress
${xml_device_type}
var x := 0; var y := 0; var rx := 0; var s := ""; var i := 0;
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x99);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    x := modbusr(SH, 511, uint16);
    if (x < 0xFF, return("DT" + x));
    if x = 0xFF
        while i < 8
            modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA7);
            sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
            y := modbusr(SH, 511, uint16);
            if y < 0xFE
                s := if(s = "", "DT" + y, s + ", DT" + y);
                i := i + 1;
            else
                i := 8;
            end
        loop
        return(if(s = "", "MASK", s));
    end
end

return("--")
Physical Min Level
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x9A);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if (x <= 0xFE, return(round((x / 0xFE) * 100) + " %"));
end

return("--")
Max Level
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA1);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if (x <= 0xFE, return(round((x / 0xFE) * 100) + " %"));
end

return("--")
Min Level
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA2);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if (x <= 0xFE, return(round((x / 0xFE) * 100) + " %"));
end

return("--")
Power Up Level
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA3);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if (x <= 0xFE, return(round((x / 0xFE) * 100) + " %"));
end

return("--")
System Failure Level
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA4);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if (x <= 0xFE, return(round((x / 0xFE) * 100) + " %"));
end

return("--")
${xml_groups}
var x := 0; var rx := 0;
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xC0);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var g1 := modbusr(SH, 511, uint16);
    if (g1 > 0xFF, return("--")); 

    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xC1);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var g2 := modbusr(SH, 511, uint16);
    if (g2 > 0xFF, return("--")); 

    var ret := "";

    if (getbit(g1, 0), ret := ret + "0");
    if (getbit(g1, 1), if (ret = "", ret := "1", ret := ret + ",1"));
    if (getbit(g1, 2), if (ret = "", ret := "2", ret := ret + ",2"));
    if (getbit(g1, 3), if (ret = "", ret := "3", ret := ret + ",3"));
    if (getbit(g1, 4), if (ret = "", ret := "4", ret := ret + ",4"));
    if (getbit(g1, 5), if (ret = "", ret := "5", ret := ret + ",5"));
    if (getbit(g1, 6), if (ret = "", ret := "6", ret := ret + ",6"));
    if (getbit(g1, 7), if (ret = "", ret := "7", ret := ret + ",7"));
    if (getbit(g2, 0), if (ret = "", ret := "8", ret := ret + ",8"));
    if (getbit(g2, 1), if (ret = "", ret := "9", ret := ret + ",9"));
    if (getbit(g2, 2), if (ret = "", ret := "10", ret := ret + ",10"));
    if (getbit(g2, 3), if (ret = "", ret := "11", ret := ret + ",11"));
    if (getbit(g2, 4), if (ret = "", ret := "12", ret := ret + ",12"));
    if (getbit(g2, 5), if (ret = "", ret := "13", ret := ret + ",13"));
    if (getbit(g2, 6), if (ret = "", ret := "14", ret := ret + ",14"));
    if (getbit(g2, 7), if (ret = "", ret := "15", ret := ret + ",15"));

    if (ret = "", return("None"), return(ret));
else
    return("--");
end
DALI Status
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x90);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if x <= 0xFF
        var s := "";
        if (getbit(x, 0), s := if(s = "", "gear failure", s + ", gear failure"));
        if (getbit(x, 1), s := if(s = "", "lamp failure", s + ", lamp failure"));
        if (getbit(x, 2), s := if(s = "", "lamp on", s + ", lamp on"));
        if (getbit(x, 3), s := if(s = "", "limit error", s + ", limit error"));
        if (getbit(x, 4), s := if(s = "", "fade running", s + ", fade running"));
        if (getbit(x, 5), s := if(s = "", "reset state", s + ", reset state"));
        if (getbit(x, 6), s := if(s = "", "missing short address", s + ", missing short address"));
        if (getbit(x, 7), s := if(s = "", "power cycle", s + ", power cycle"));
        var ign := if((ignGear = 1) and (ignLamp = 1), "gear and lamp failure", if(ignGear = 1, "gear failure", if(ignLamp = 1, "lamp failure", "")));
        return(if(s = "", "OK", s) + " (0x" + tostring(x, "X2") + ")" + if(ign = "", "", "; not raised: " + ign + " reported since start"));
    end
end

return("--")
Fade
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA5);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if x <= 0xFF
        var t := getbits(x, 4, 4);
        var ret := if(t = 0, "off", t + " (" + round(sqrt(power(2, t)) * 5) / 10 + " s)");
        modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA8);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
        var e := modbusr(SH, 511, uint16);
        if (t = 0 and e <= 0xFF and e != 0, ret := "extended 0x" + tostring(e, "X2"));
        return("fade time " + ret + ", fade rate " + getbits(x, 0, 4));
    end
end

return("--")
DALI Version
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x97);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if x <= 0xFF
        return(if(x >= 8, "DALI-2 " + getbits(x, 2, 6) + "." + getbits(x, 0, 2), "DALI-1") + " (" + x + ")");
    end
end

return("--")
Bus statistics
return("since start: queries " + cntQ + ", stale answers read away " + cntStale + ", no answer " + cntNone + ", collisions " + cntColl + ", rejected levels " + cntBad)
Azioni di servizio
${xml_add_to_group}
Parametri: Group ID (0–15 grp)
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x60 + grp);
${xml_remove_from_group}
Parametri: Group ID (0–15 grp)
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x70 + grp);
${xml_reset_to_default_settings}
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x20);
${xml_set_startup_levels}
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x21);
sleep(10);
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x2c);
sleep(10);
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x2d);
Disable fading
modbusw(SH, 541, uint16, 0xA300);
sleep(100);
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x2E);
sleep(100);
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x30);
Gear 49 Dimmer Lettura e scrittura

Dispositivo di controllo DALI all'indirizzo breve 49 — dimmer TapHome mappato su DALI arc power 0–100 % tramite H:510 LAMP LEVEL (scrittura) e QUERY ACTUAL LEVEL tramite H:511 (lettura), delimitato dai propri MIN / MAX LEVEL del gear.

Registro: H:511 → H:510 UInt16 Unità: % numeric
Attributi di servizio
Indirizzo breveIndirizzo breve DALI (0–63) target di questo dispositivo — fissato al momento dell'importazione del template e utilizzato nel byte alto di ogni scrittura Modbus.
Device TypeByte device-type DALI restituito da QUERY DEVICE TYPE (0x99) — riporta DT0 (fluorescente), DT6 (driver LED), DT8 (colore / tunable white) ecc., o -- quando non c'è risposta.
Physical Min LevelLivello minimo di dimmerazione imposto dall'hardware riportato dal gear — letto da QUERY PHYSICAL MIN LEVEL (0x9A), in percentuale.
Max LevelDALI MAX LEVEL configurato — letto da QUERY MAX LEVEL (0xA1); utilizzato come limite superiore durante la scalatura di TapHome 0–100 % su DALI arc power.
Min LevelDALI MIN LEVEL configurato — letto da QUERY MIN LEVEL (0xA2); utilizzato come limite inferiore durante la scalatura di TapHome 0–100 % su DALI arc power.
Power Up LevelLuminosità ripristinata dopo il ripristino dell'alimentazione del bus DALI — letta da QUERY POWER ON LEVEL (0xA3).
System Failure LevelLuminosità adottata quando il bus DALI perde la comunicazione per più di 500 ms — letta da QUERY SYSTEM FAILURE LEVEL (0xA4).
GruppiElenco separato da virgole dei gruppi DALI (0–15) a cui appartiene il gear — decodificato da QUERY GROUPS 0-7 (0xC0) e QUERY GROUPS 8-15 (0xC1); mostra None o ad es. 0,3,7.
Support Lamp FailureSe la lampada / driver supporta il rilevamento dei guasti della lampada — Yes / No / --. Gestisce l'errore Lamp failure! nel readscript periodico.
Support Power FailureSe la lampada / driver supporta il rilevamento dei guasti di alimentazione — Yes / No / --. Gestisce l'errore Power failure! nel readscript periodico.
DALI Version
Bus statistics
Azioni di servizio
Add to GroupAggiunge questo gear a un gruppo DALI (0–15) tramite ADD TO GROUP (0x60+grp) — auto-ripetuto entro 100 ms come richiesto per i comandi di configurazione DALI.
Remove from GroupRimuove questo gear da un gruppo DALI (0–15) tramite REMOVE FROM GROUP (0x70+grp).
Reset to Default SettingsInvia DALI RESET (0x20) — ripristina ogni parametro NVM del gear (livelli max / min / power-on / system-failure, appartenenza al gruppo, scene) al valore predefinito del produttore.
Set Startup LevelsCattura l'arc power corrente e la memorizza come Power On Level e System Failure Level — sequenza STORE ACTUAL LEVEL IN DTR (0x21) → STORE DTR AS POWER ON LEVEL (0x2C) → STORE DTR AS SYSTEM FAILURE LEVEL (0x2D).
Disable fading

Gear 49

Lettura (modulo)
var x := 0; var rx := 0; var y := 0;
if Status > 0
    Status := Status - 1;
    adderror(3, "Gear not responding!");
    return(0);
end

# checkStatus: ReadLevel resets it while the gear answers; statusPoll: QUERY STATUS at least once per 60 runs
checkStatus := checkStatus - 1;
statusPoll := statusPoll - 1;
if checkStatus < 1 or statusPoll < 1
    # an unread answer left in the gateway would be taken for this query: read it away and count it
    x := modbusr(SH, 511, uint16); if (x != 0x8000, cntStale := cntStale + 1);
    modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x90);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    x := modbusr(SH, 511, uint16);
    cntQ := cntQ + 1; if (x = 0x8000, cntNone := cntNone + 1); if (x = 0x20FF, cntColl := cntColl + 1);
    # a single lost answer happens on DALI: ask once more before declaring the gear missing
    if x = 0x8000
        x := modbusr(SH, 511, uint16); if (x != 0x8000, cntStale := cntStale + 1);
        modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x90);
        sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
        x := modbusr(SH, 511, uint16);
        cntQ := cntQ + 1; if (x = 0x8000, cntNone := cntNone + 1); if (x = 0x20FF, cntColl := cntColl + 1);
    end
    if x <= 0xFF
        # a changed failure bit must be read twice the same before it is taken
        if statusSeen = 1 and getbits(x, 0, 2) != getbits(gearStatus, 0, 2)
            y := modbusr(SH, 511, uint16); if (y != 0x8000, cntStale := cntStale + 1);
            modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x90);
            sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
            y := modbusr(SH, 511, uint16);
            cntQ := cntQ + 1; if (y = 0x8000, cntNone := cntNone + 1); if (y = 0x20FF, cntColl := cntColl + 1);
            if y != x
                cntBad := cntBad + 1;
                x := gearStatus;
            end
        end
        if statusSeen = 0
            ignGear := getbit(x, 0);
            ignLamp := getbit(x, 1);
            statusSeen := 1;
        end
        # a bit that clears ends its ignore, so a later failure is raised
        if (getbit(x, 0) = 0, ignGear := 0);
        if (getbit(x, 1) = 0, ignLamp := 0);
        gearStatus := x;
        checkStatus := 60;
        statusPoll := 60;
    else
        if x = 0x8000
            Status := RANDINT(10, 60);
            adderror(3, "Gear not responding!");
            return(0);
        end
    end
end

# messages last one run only, so they are raised from the stored status on every run
if ((getbit(gearStatus, 0) = 1) and (ignGear = 0), adderror(1, "Control gear failure!"));
if ((getbit(gearStatus, 1) = 1) and (ignLamp = 0), adderror(2, "Lamp failure!"));
Inizializzazione
var x := 0; var rx := 0;
# QUERY STATUS 0x90: every reply byte proves the gear is present; 0x8000 = no answer, 0x20FF = bus collision
# an unread answer left in the gateway would be taken for this query: read it away and count it
x := modbusr(SH, 511, uint16); if (x != 0x8000, cntStale := cntStale + 1);
modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x90);
sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
x := modbusr(SH, 511, uint16);
cntQ := cntQ + 1; if (x = 0x8000, cntNone := cntNone + 1); if (x = 0x20FF, cntColl := cntColl + 1);
statusSeen := 0;
if x <= 0xFF
    # failure bits a gear reports from its first answer are its permanent state, not an event: shown, not raised
    gearStatus := x;
    ignGear := getbit(x, 0);
    ignLamp := getbit(x, 1);
    statusSeen := 1;
    Status := 0;
else
    Status := RANDINT(1, 60);
end

if Status = 0
    x := modbusr(SH, 511, uint16); if (x != 0x8000, cntStale := cntStale + 1);
    modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA2);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    x := modbusr(SH, 511, uint16);
    cntQ := cntQ + 1; if (x = 0x8000, cntNone := cntNone + 1); if (x = 0x20FF, cntColl := cntColl + 1);
    if (x <= 0xFE, minLevel := x);

    x := modbusr(SH, 511, uint16); if (x != 0x8000, cntStale := cntStale + 1);
    modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA1);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    x := modbusr(SH, 511, uint16);
    cntQ := cntQ + 1; if (x = 0x8000, cntNone := cntNone + 1); if (x = 0x20FF, cntColl := cntColl + 1);
    if (x <= 0xFE, maxLevel := x);
end
Lettura livello
var x := 0; var rx := 0; var y := 0;
if Status = 0
    if minLevel = 0
        # an unread answer left in the gateway would be taken for this query: read it away and count it
        x := modbusr(SH, 511, uint16); if (x != 0x8000, cntStale := cntStale + 1);
        modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA2);
        sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
        x := modbusr(SH, 511, uint16);
        cntQ := cntQ + 1; if (x = 0x8000, cntNone := cntNone + 1); if (x = 0x20FF, cntColl := cntColl + 1);
        if (x <= 0xFE, minLevel := x);
    end
    x := modbusr(SH, 511, uint16); if (x != 0x8000, cntStale := cntStale + 1);
    modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA0);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    x := modbusr(SH, 511, uint16);
    cntQ := cntQ + 1; if (x = 0x8000, cntNone := cntNone + 1); if (x = 0x20FF, cntColl := cntColl + 1);
    if (x != 0x8000 or rx, checkStatus := 60);
    # 0xFF = MASK, 0x20FF = collision, 0x8000 = no answer: keep the last level instead of a phantom value
    if x > 0xFE
        return(Le);
    end
    # an actual level is 0 or between the gear's min and max: anything else is not this gear's answer
    if x > 0 and x < minLevel
        cntBad := cntBad + 1;
        return(Le);
    end
    # a changed level must be read twice the same before it is taken
    if x != lastRaw
        y := modbusr(SH, 511, uint16); if (y != 0x8000, cntStale := cntStale + 1);
        modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA0);
        sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
        y := modbusr(SH, 511, uint16);
        cntQ := cntQ + 1; if (y = 0x8000, cntNone := cntNone + 1); if (y = 0x20FF, cntColl := cntColl + 1);
        if y != x
            cntBad := cntBad + 1;
            return(Le);
        end
        lastRaw := x;
    end
    return(if(x = 0, 0, linear(x, minLevel, 0.01, maxLevel, 1)));
else
    return(NaN);
end
Scrittura livello
var level := 0;
if(Le > 0, level := round(linear(Le, 0.01, minLevel, 1, maxLevel)));
modbusw(SH, 510, uint16, (ShortAddress << 8) + level );
Attributi di servizio
${xml_short_address}
ShortAddress
${xml_device_type}
var x := 0; var y := 0; var rx := 0; var s := ""; var i := 0;
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x99);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    x := modbusr(SH, 511, uint16);
    if (x < 0xFF, return("DT" + x));
    if x = 0xFF
        while i < 8
            modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA7);
            sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
            y := modbusr(SH, 511, uint16);
            if y < 0xFE
                s := if(s = "", "DT" + y, s + ", DT" + y);
                i := i + 1;
            else
                i := 8;
            end
        loop
        return(if(s = "", "MASK", s));
    end
end

return("--")
Physical Min Level
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x9A);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if (x <= 0xFE, return(round((x / 0xFE) * 100) + " %"));
end

return("--")
Max Level
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA1);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if (x <= 0xFE, return(round((x / 0xFE) * 100) + " %"));
end

return("--")
Min Level
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA2);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if (x <= 0xFE, return(round((x / 0xFE) * 100) + " %"));
end

return("--")
Power Up Level
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA3);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if (x <= 0xFE, return(round((x / 0xFE) * 100) + " %"));
end

return("--")
System Failure Level
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA4);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if (x <= 0xFE, return(round((x / 0xFE) * 100) + " %"));
end

return("--")
${xml_groups}
var x := 0; var rx := 0;
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xC0);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var g1 := modbusr(SH, 511, uint16);
    if (g1 > 0xFF, return("--")); 

    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xC1);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var g2 := modbusr(SH, 511, uint16);
    if (g2 > 0xFF, return("--")); 

    var ret := "";

    if (getbit(g1, 0), ret := ret + "0");
    if (getbit(g1, 1), if (ret = "", ret := "1", ret := ret + ",1"));
    if (getbit(g1, 2), if (ret = "", ret := "2", ret := ret + ",2"));
    if (getbit(g1, 3), if (ret = "", ret := "3", ret := ret + ",3"));
    if (getbit(g1, 4), if (ret = "", ret := "4", ret := ret + ",4"));
    if (getbit(g1, 5), if (ret = "", ret := "5", ret := ret + ",5"));
    if (getbit(g1, 6), if (ret = "", ret := "6", ret := ret + ",6"));
    if (getbit(g1, 7), if (ret = "", ret := "7", ret := ret + ",7"));
    if (getbit(g2, 0), if (ret = "", ret := "8", ret := ret + ",8"));
    if (getbit(g2, 1), if (ret = "", ret := "9", ret := ret + ",9"));
    if (getbit(g2, 2), if (ret = "", ret := "10", ret := ret + ",10"));
    if (getbit(g2, 3), if (ret = "", ret := "11", ret := ret + ",11"));
    if (getbit(g2, 4), if (ret = "", ret := "12", ret := ret + ",12"));
    if (getbit(g2, 5), if (ret = "", ret := "13", ret := ret + ",13"));
    if (getbit(g2, 6), if (ret = "", ret := "14", ret := ret + ",14"));
    if (getbit(g2, 7), if (ret = "", ret := "15", ret := ret + ",15"));

    if (ret = "", return("None"), return(ret));
else
    return("--");
end
DALI Status
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x90);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if x <= 0xFF
        var s := "";
        if (getbit(x, 0), s := if(s = "", "gear failure", s + ", gear failure"));
        if (getbit(x, 1), s := if(s = "", "lamp failure", s + ", lamp failure"));
        if (getbit(x, 2), s := if(s = "", "lamp on", s + ", lamp on"));
        if (getbit(x, 3), s := if(s = "", "limit error", s + ", limit error"));
        if (getbit(x, 4), s := if(s = "", "fade running", s + ", fade running"));
        if (getbit(x, 5), s := if(s = "", "reset state", s + ", reset state"));
        if (getbit(x, 6), s := if(s = "", "missing short address", s + ", missing short address"));
        if (getbit(x, 7), s := if(s = "", "power cycle", s + ", power cycle"));
        var ign := if((ignGear = 1) and (ignLamp = 1), "gear and lamp failure", if(ignGear = 1, "gear failure", if(ignLamp = 1, "lamp failure", "")));
        return(if(s = "", "OK", s) + " (0x" + tostring(x, "X2") + ")" + if(ign = "", "", "; not raised: " + ign + " reported since start"));
    end
end

return("--")
Fade
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA5);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if x <= 0xFF
        var t := getbits(x, 4, 4);
        var ret := if(t = 0, "off", t + " (" + round(sqrt(power(2, t)) * 5) / 10 + " s)");
        modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA8);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
        var e := modbusr(SH, 511, uint16);
        if (t = 0 and e <= 0xFF and e != 0, ret := "extended 0x" + tostring(e, "X2"));
        return("fade time " + ret + ", fade rate " + getbits(x, 0, 4));
    end
end

return("--")
DALI Version
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x97);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if x <= 0xFF
        return(if(x >= 8, "DALI-2 " + getbits(x, 2, 6) + "." + getbits(x, 0, 2), "DALI-1") + " (" + x + ")");
    end
end

return("--")
Bus statistics
return("since start: queries " + cntQ + ", stale answers read away " + cntStale + ", no answer " + cntNone + ", collisions " + cntColl + ", rejected levels " + cntBad)
Azioni di servizio
${xml_add_to_group}
Parametri: Group ID (0–15 grp)
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x60 + grp);
${xml_remove_from_group}
Parametri: Group ID (0–15 grp)
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x70 + grp);
${xml_reset_to_default_settings}
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x20);
${xml_set_startup_levels}
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x21);
sleep(10);
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x2c);
sleep(10);
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x2d);
Disable fading
modbusw(SH, 541, uint16, 0xA300);
sleep(100);
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x2E);
sleep(100);
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x30);
Gear 50 Dimmer Lettura e scrittura

Dispositivo di controllo DALI all'indirizzo breve 50 — dimmer TapHome mappato su DALI arc power 0–100 % tramite H:510 LAMP LEVEL (scrittura) e QUERY ACTUAL LEVEL tramite H:511 (lettura), delimitato dai propri MIN / MAX LEVEL del gear.

Registro: H:511 → H:510 UInt16 Unità: % numeric
Attributi di servizio
Indirizzo breveIndirizzo breve DALI (0–63) target di questo dispositivo — fissato al momento dell'importazione del template e utilizzato nel byte alto di ogni scrittura Modbus.
Device TypeByte device-type DALI restituito da QUERY DEVICE TYPE (0x99) — riporta DT0 (fluorescente), DT6 (driver LED), DT8 (colore / tunable white) ecc., o -- quando non c'è risposta.
Physical Min LevelLivello minimo di dimmerazione imposto dall'hardware riportato dal gear — letto da QUERY PHYSICAL MIN LEVEL (0x9A), in percentuale.
Max LevelDALI MAX LEVEL configurato — letto da QUERY MAX LEVEL (0xA1); utilizzato come limite superiore durante la scalatura di TapHome 0–100 % su DALI arc power.
Min LevelDALI MIN LEVEL configurato — letto da QUERY MIN LEVEL (0xA2); utilizzato come limite inferiore durante la scalatura di TapHome 0–100 % su DALI arc power.
Power Up LevelLuminosità ripristinata dopo il ripristino dell'alimentazione del bus DALI — letta da QUERY POWER ON LEVEL (0xA3).
System Failure LevelLuminosità adottata quando il bus DALI perde la comunicazione per più di 500 ms — letta da QUERY SYSTEM FAILURE LEVEL (0xA4).
GruppiElenco separato da virgole dei gruppi DALI (0–15) a cui appartiene il gear — decodificato da QUERY GROUPS 0-7 (0xC0) e QUERY GROUPS 8-15 (0xC1); mostra None o ad es. 0,3,7.
Support Lamp FailureSe la lampada / driver supporta il rilevamento dei guasti della lampada — Yes / No / --. Gestisce l'errore Lamp failure! nel readscript periodico.
Support Power FailureSe la lampada / driver supporta il rilevamento dei guasti di alimentazione — Yes / No / --. Gestisce l'errore Power failure! nel readscript periodico.
DALI Version
Bus statistics
Azioni di servizio
Add to GroupAggiunge questo gear a un gruppo DALI (0–15) tramite ADD TO GROUP (0x60+grp) — auto-ripetuto entro 100 ms come richiesto per i comandi di configurazione DALI.
Remove from GroupRimuove questo gear da un gruppo DALI (0–15) tramite REMOVE FROM GROUP (0x70+grp).
Reset to Default SettingsInvia DALI RESET (0x20) — ripristina ogni parametro NVM del gear (livelli max / min / power-on / system-failure, appartenenza al gruppo, scene) al valore predefinito del produttore.
Set Startup LevelsCattura l'arc power corrente e la memorizza come Power On Level e System Failure Level — sequenza STORE ACTUAL LEVEL IN DTR (0x21) → STORE DTR AS POWER ON LEVEL (0x2C) → STORE DTR AS SYSTEM FAILURE LEVEL (0x2D).
Disable fading

Gear 50

Lettura (modulo)
var x := 0; var rx := 0; var y := 0;
if Status > 0
    Status := Status - 1;
    adderror(3, "Gear not responding!");
    return(0);
end

# checkStatus: ReadLevel resets it while the gear answers; statusPoll: QUERY STATUS at least once per 60 runs
checkStatus := checkStatus - 1;
statusPoll := statusPoll - 1;
if checkStatus < 1 or statusPoll < 1
    # an unread answer left in the gateway would be taken for this query: read it away and count it
    x := modbusr(SH, 511, uint16); if (x != 0x8000, cntStale := cntStale + 1);
    modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x90);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    x := modbusr(SH, 511, uint16);
    cntQ := cntQ + 1; if (x = 0x8000, cntNone := cntNone + 1); if (x = 0x20FF, cntColl := cntColl + 1);
    # a single lost answer happens on DALI: ask once more before declaring the gear missing
    if x = 0x8000
        x := modbusr(SH, 511, uint16); if (x != 0x8000, cntStale := cntStale + 1);
        modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x90);
        sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
        x := modbusr(SH, 511, uint16);
        cntQ := cntQ + 1; if (x = 0x8000, cntNone := cntNone + 1); if (x = 0x20FF, cntColl := cntColl + 1);
    end
    if x <= 0xFF
        # a changed failure bit must be read twice the same before it is taken
        if statusSeen = 1 and getbits(x, 0, 2) != getbits(gearStatus, 0, 2)
            y := modbusr(SH, 511, uint16); if (y != 0x8000, cntStale := cntStale + 1);
            modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x90);
            sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
            y := modbusr(SH, 511, uint16);
            cntQ := cntQ + 1; if (y = 0x8000, cntNone := cntNone + 1); if (y = 0x20FF, cntColl := cntColl + 1);
            if y != x
                cntBad := cntBad + 1;
                x := gearStatus;
            end
        end
        if statusSeen = 0
            ignGear := getbit(x, 0);
            ignLamp := getbit(x, 1);
            statusSeen := 1;
        end
        # a bit that clears ends its ignore, so a later failure is raised
        if (getbit(x, 0) = 0, ignGear := 0);
        if (getbit(x, 1) = 0, ignLamp := 0);
        gearStatus := x;
        checkStatus := 60;
        statusPoll := 60;
    else
        if x = 0x8000
            Status := RANDINT(10, 60);
            adderror(3, "Gear not responding!");
            return(0);
        end
    end
end

# messages last one run only, so they are raised from the stored status on every run
if ((getbit(gearStatus, 0) = 1) and (ignGear = 0), adderror(1, "Control gear failure!"));
if ((getbit(gearStatus, 1) = 1) and (ignLamp = 0), adderror(2, "Lamp failure!"));
Inizializzazione
var x := 0; var rx := 0;
# QUERY STATUS 0x90: every reply byte proves the gear is present; 0x8000 = no answer, 0x20FF = bus collision
# an unread answer left in the gateway would be taken for this query: read it away and count it
x := modbusr(SH, 511, uint16); if (x != 0x8000, cntStale := cntStale + 1);
modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x90);
sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
x := modbusr(SH, 511, uint16);
cntQ := cntQ + 1; if (x = 0x8000, cntNone := cntNone + 1); if (x = 0x20FF, cntColl := cntColl + 1);
statusSeen := 0;
if x <= 0xFF
    # failure bits a gear reports from its first answer are its permanent state, not an event: shown, not raised
    gearStatus := x;
    ignGear := getbit(x, 0);
    ignLamp := getbit(x, 1);
    statusSeen := 1;
    Status := 0;
else
    Status := RANDINT(1, 60);
end

if Status = 0
    x := modbusr(SH, 511, uint16); if (x != 0x8000, cntStale := cntStale + 1);
    modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA2);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    x := modbusr(SH, 511, uint16);
    cntQ := cntQ + 1; if (x = 0x8000, cntNone := cntNone + 1); if (x = 0x20FF, cntColl := cntColl + 1);
    if (x <= 0xFE, minLevel := x);

    x := modbusr(SH, 511, uint16); if (x != 0x8000, cntStale := cntStale + 1);
    modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA1);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    x := modbusr(SH, 511, uint16);
    cntQ := cntQ + 1; if (x = 0x8000, cntNone := cntNone + 1); if (x = 0x20FF, cntColl := cntColl + 1);
    if (x <= 0xFE, maxLevel := x);
end
Lettura livello
var x := 0; var rx := 0; var y := 0;
if Status = 0
    if minLevel = 0
        # an unread answer left in the gateway would be taken for this query: read it away and count it
        x := modbusr(SH, 511, uint16); if (x != 0x8000, cntStale := cntStale + 1);
        modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA2);
        sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
        x := modbusr(SH, 511, uint16);
        cntQ := cntQ + 1; if (x = 0x8000, cntNone := cntNone + 1); if (x = 0x20FF, cntColl := cntColl + 1);
        if (x <= 0xFE, minLevel := x);
    end
    x := modbusr(SH, 511, uint16); if (x != 0x8000, cntStale := cntStale + 1);
    modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA0);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    x := modbusr(SH, 511, uint16);
    cntQ := cntQ + 1; if (x = 0x8000, cntNone := cntNone + 1); if (x = 0x20FF, cntColl := cntColl + 1);
    if (x != 0x8000 or rx, checkStatus := 60);
    # 0xFF = MASK, 0x20FF = collision, 0x8000 = no answer: keep the last level instead of a phantom value
    if x > 0xFE
        return(Le);
    end
    # an actual level is 0 or between the gear's min and max: anything else is not this gear's answer
    if x > 0 and x < minLevel
        cntBad := cntBad + 1;
        return(Le);
    end
    # a changed level must be read twice the same before it is taken
    if x != lastRaw
        y := modbusr(SH, 511, uint16); if (y != 0x8000, cntStale := cntStale + 1);
        modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA0);
        sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
        y := modbusr(SH, 511, uint16);
        cntQ := cntQ + 1; if (y = 0x8000, cntNone := cntNone + 1); if (y = 0x20FF, cntColl := cntColl + 1);
        if y != x
            cntBad := cntBad + 1;
            return(Le);
        end
        lastRaw := x;
    end
    return(if(x = 0, 0, linear(x, minLevel, 0.01, maxLevel, 1)));
else
    return(NaN);
end
Scrittura livello
var level := 0;
if(Le > 0, level := round(linear(Le, 0.01, minLevel, 1, maxLevel)));
modbusw(SH, 510, uint16, (ShortAddress << 8) + level );
Attributi di servizio
${xml_short_address}
ShortAddress
${xml_device_type}
var x := 0; var y := 0; var rx := 0; var s := ""; var i := 0;
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x99);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    x := modbusr(SH, 511, uint16);
    if (x < 0xFF, return("DT" + x));
    if x = 0xFF
        while i < 8
            modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA7);
            sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
            y := modbusr(SH, 511, uint16);
            if y < 0xFE
                s := if(s = "", "DT" + y, s + ", DT" + y);
                i := i + 1;
            else
                i := 8;
            end
        loop
        return(if(s = "", "MASK", s));
    end
end

return("--")
Physical Min Level
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x9A);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if (x <= 0xFE, return(round((x / 0xFE) * 100) + " %"));
end

return("--")
Max Level
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA1);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if (x <= 0xFE, return(round((x / 0xFE) * 100) + " %"));
end

return("--")
Min Level
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA2);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if (x <= 0xFE, return(round((x / 0xFE) * 100) + " %"));
end

return("--")
Power Up Level
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA3);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if (x <= 0xFE, return(round((x / 0xFE) * 100) + " %"));
end

return("--")
System Failure Level
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA4);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if (x <= 0xFE, return(round((x / 0xFE) * 100) + " %"));
end

return("--")
${xml_groups}
var x := 0; var rx := 0;
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xC0);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var g1 := modbusr(SH, 511, uint16);
    if (g1 > 0xFF, return("--")); 

    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xC1);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var g2 := modbusr(SH, 511, uint16);
    if (g2 > 0xFF, return("--")); 

    var ret := "";

    if (getbit(g1, 0), ret := ret + "0");
    if (getbit(g1, 1), if (ret = "", ret := "1", ret := ret + ",1"));
    if (getbit(g1, 2), if (ret = "", ret := "2", ret := ret + ",2"));
    if (getbit(g1, 3), if (ret = "", ret := "3", ret := ret + ",3"));
    if (getbit(g1, 4), if (ret = "", ret := "4", ret := ret + ",4"));
    if (getbit(g1, 5), if (ret = "", ret := "5", ret := ret + ",5"));
    if (getbit(g1, 6), if (ret = "", ret := "6", ret := ret + ",6"));
    if (getbit(g1, 7), if (ret = "", ret := "7", ret := ret + ",7"));
    if (getbit(g2, 0), if (ret = "", ret := "8", ret := ret + ",8"));
    if (getbit(g2, 1), if (ret = "", ret := "9", ret := ret + ",9"));
    if (getbit(g2, 2), if (ret = "", ret := "10", ret := ret + ",10"));
    if (getbit(g2, 3), if (ret = "", ret := "11", ret := ret + ",11"));
    if (getbit(g2, 4), if (ret = "", ret := "12", ret := ret + ",12"));
    if (getbit(g2, 5), if (ret = "", ret := "13", ret := ret + ",13"));
    if (getbit(g2, 6), if (ret = "", ret := "14", ret := ret + ",14"));
    if (getbit(g2, 7), if (ret = "", ret := "15", ret := ret + ",15"));

    if (ret = "", return("None"), return(ret));
else
    return("--");
end
DALI Status
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x90);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if x <= 0xFF
        var s := "";
        if (getbit(x, 0), s := if(s = "", "gear failure", s + ", gear failure"));
        if (getbit(x, 1), s := if(s = "", "lamp failure", s + ", lamp failure"));
        if (getbit(x, 2), s := if(s = "", "lamp on", s + ", lamp on"));
        if (getbit(x, 3), s := if(s = "", "limit error", s + ", limit error"));
        if (getbit(x, 4), s := if(s = "", "fade running", s + ", fade running"));
        if (getbit(x, 5), s := if(s = "", "reset state", s + ", reset state"));
        if (getbit(x, 6), s := if(s = "", "missing short address", s + ", missing short address"));
        if (getbit(x, 7), s := if(s = "", "power cycle", s + ", power cycle"));
        var ign := if((ignGear = 1) and (ignLamp = 1), "gear and lamp failure", if(ignGear = 1, "gear failure", if(ignLamp = 1, "lamp failure", "")));
        return(if(s = "", "OK", s) + " (0x" + tostring(x, "X2") + ")" + if(ign = "", "", "; not raised: " + ign + " reported since start"));
    end
end

return("--")
Fade
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA5);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if x <= 0xFF
        var t := getbits(x, 4, 4);
        var ret := if(t = 0, "off", t + " (" + round(sqrt(power(2, t)) * 5) / 10 + " s)");
        modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA8);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
        var e := modbusr(SH, 511, uint16);
        if (t = 0 and e <= 0xFF and e != 0, ret := "extended 0x" + tostring(e, "X2"));
        return("fade time " + ret + ", fade rate " + getbits(x, 0, 4));
    end
end

return("--")
DALI Version
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x97);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if x <= 0xFF
        return(if(x >= 8, "DALI-2 " + getbits(x, 2, 6) + "." + getbits(x, 0, 2), "DALI-1") + " (" + x + ")");
    end
end

return("--")
Bus statistics
return("since start: queries " + cntQ + ", stale answers read away " + cntStale + ", no answer " + cntNone + ", collisions " + cntColl + ", rejected levels " + cntBad)
Azioni di servizio
${xml_add_to_group}
Parametri: Group ID (0–15 grp)
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x60 + grp);
${xml_remove_from_group}
Parametri: Group ID (0–15 grp)
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x70 + grp);
${xml_reset_to_default_settings}
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x20);
${xml_set_startup_levels}
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x21);
sleep(10);
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x2c);
sleep(10);
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x2d);
Disable fading
modbusw(SH, 541, uint16, 0xA300);
sleep(100);
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x2E);
sleep(100);
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x30);
Gear 51 Dimmer Lettura e scrittura

Dispositivo di controllo DALI all'indirizzo breve 51 — dimmer TapHome mappato su DALI arc power 0–100 % tramite H:510 LAMP LEVEL (scrittura) e QUERY ACTUAL LEVEL tramite H:511 (lettura), delimitato dai propri MIN / MAX LEVEL del gear.

Registro: H:511 → H:510 UInt16 Unità: % numeric
Attributi di servizio
Indirizzo breveIndirizzo breve DALI (0–63) target di questo dispositivo — fissato al momento dell'importazione del template e utilizzato nel byte alto di ogni scrittura Modbus.
Device TypeByte device-type DALI restituito da QUERY DEVICE TYPE (0x99) — riporta DT0 (fluorescente), DT6 (driver LED), DT8 (colore / tunable white) ecc., o -- quando non c'è risposta.
Physical Min LevelLivello minimo di dimmerazione imposto dall'hardware riportato dal gear — letto da QUERY PHYSICAL MIN LEVEL (0x9A), in percentuale.
Max LevelDALI MAX LEVEL configurato — letto da QUERY MAX LEVEL (0xA1); utilizzato come limite superiore durante la scalatura di TapHome 0–100 % su DALI arc power.
Min LevelDALI MIN LEVEL configurato — letto da QUERY MIN LEVEL (0xA2); utilizzato come limite inferiore durante la scalatura di TapHome 0–100 % su DALI arc power.
Power Up LevelLuminosità ripristinata dopo il ripristino dell'alimentazione del bus DALI — letta da QUERY POWER ON LEVEL (0xA3).
System Failure LevelLuminosità adottata quando il bus DALI perde la comunicazione per più di 500 ms — letta da QUERY SYSTEM FAILURE LEVEL (0xA4).
GruppiElenco separato da virgole dei gruppi DALI (0–15) a cui appartiene il gear — decodificato da QUERY GROUPS 0-7 (0xC0) e QUERY GROUPS 8-15 (0xC1); mostra None o ad es. 0,3,7.
Support Lamp FailureSe la lampada / driver supporta il rilevamento dei guasti della lampada — Yes / No / --. Gestisce l'errore Lamp failure! nel readscript periodico.
Support Power FailureSe la lampada / driver supporta il rilevamento dei guasti di alimentazione — Yes / No / --. Gestisce l'errore Power failure! nel readscript periodico.
DALI Version
Bus statistics
Azioni di servizio
Add to GroupAggiunge questo gear a un gruppo DALI (0–15) tramite ADD TO GROUP (0x60+grp) — auto-ripetuto entro 100 ms come richiesto per i comandi di configurazione DALI.
Remove from GroupRimuove questo gear da un gruppo DALI (0–15) tramite REMOVE FROM GROUP (0x70+grp).
Reset to Default SettingsInvia DALI RESET (0x20) — ripristina ogni parametro NVM del gear (livelli max / min / power-on / system-failure, appartenenza al gruppo, scene) al valore predefinito del produttore.
Set Startup LevelsCattura l'arc power corrente e la memorizza come Power On Level e System Failure Level — sequenza STORE ACTUAL LEVEL IN DTR (0x21) → STORE DTR AS POWER ON LEVEL (0x2C) → STORE DTR AS SYSTEM FAILURE LEVEL (0x2D).
Disable fading

Gear 51

Lettura (modulo)
var x := 0; var rx := 0; var y := 0;
if Status > 0
    Status := Status - 1;
    adderror(3, "Gear not responding!");
    return(0);
end

# checkStatus: ReadLevel resets it while the gear answers; statusPoll: QUERY STATUS at least once per 60 runs
checkStatus := checkStatus - 1;
statusPoll := statusPoll - 1;
if checkStatus < 1 or statusPoll < 1
    # an unread answer left in the gateway would be taken for this query: read it away and count it
    x := modbusr(SH, 511, uint16); if (x != 0x8000, cntStale := cntStale + 1);
    modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x90);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    x := modbusr(SH, 511, uint16);
    cntQ := cntQ + 1; if (x = 0x8000, cntNone := cntNone + 1); if (x = 0x20FF, cntColl := cntColl + 1);
    # a single lost answer happens on DALI: ask once more before declaring the gear missing
    if x = 0x8000
        x := modbusr(SH, 511, uint16); if (x != 0x8000, cntStale := cntStale + 1);
        modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x90);
        sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
        x := modbusr(SH, 511, uint16);
        cntQ := cntQ + 1; if (x = 0x8000, cntNone := cntNone + 1); if (x = 0x20FF, cntColl := cntColl + 1);
    end
    if x <= 0xFF
        # a changed failure bit must be read twice the same before it is taken
        if statusSeen = 1 and getbits(x, 0, 2) != getbits(gearStatus, 0, 2)
            y := modbusr(SH, 511, uint16); if (y != 0x8000, cntStale := cntStale + 1);
            modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x90);
            sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
            y := modbusr(SH, 511, uint16);
            cntQ := cntQ + 1; if (y = 0x8000, cntNone := cntNone + 1); if (y = 0x20FF, cntColl := cntColl + 1);
            if y != x
                cntBad := cntBad + 1;
                x := gearStatus;
            end
        end
        if statusSeen = 0
            ignGear := getbit(x, 0);
            ignLamp := getbit(x, 1);
            statusSeen := 1;
        end
        # a bit that clears ends its ignore, so a later failure is raised
        if (getbit(x, 0) = 0, ignGear := 0);
        if (getbit(x, 1) = 0, ignLamp := 0);
        gearStatus := x;
        checkStatus := 60;
        statusPoll := 60;
    else
        if x = 0x8000
            Status := RANDINT(10, 60);
            adderror(3, "Gear not responding!");
            return(0);
        end
    end
end

# messages last one run only, so they are raised from the stored status on every run
if ((getbit(gearStatus, 0) = 1) and (ignGear = 0), adderror(1, "Control gear failure!"));
if ((getbit(gearStatus, 1) = 1) and (ignLamp = 0), adderror(2, "Lamp failure!"));
Inizializzazione
var x := 0; var rx := 0;
# QUERY STATUS 0x90: every reply byte proves the gear is present; 0x8000 = no answer, 0x20FF = bus collision
# an unread answer left in the gateway would be taken for this query: read it away and count it
x := modbusr(SH, 511, uint16); if (x != 0x8000, cntStale := cntStale + 1);
modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x90);
sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
x := modbusr(SH, 511, uint16);
cntQ := cntQ + 1; if (x = 0x8000, cntNone := cntNone + 1); if (x = 0x20FF, cntColl := cntColl + 1);
statusSeen := 0;
if x <= 0xFF
    # failure bits a gear reports from its first answer are its permanent state, not an event: shown, not raised
    gearStatus := x;
    ignGear := getbit(x, 0);
    ignLamp := getbit(x, 1);
    statusSeen := 1;
    Status := 0;
else
    Status := RANDINT(1, 60);
end

if Status = 0
    x := modbusr(SH, 511, uint16); if (x != 0x8000, cntStale := cntStale + 1);
    modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA2);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    x := modbusr(SH, 511, uint16);
    cntQ := cntQ + 1; if (x = 0x8000, cntNone := cntNone + 1); if (x = 0x20FF, cntColl := cntColl + 1);
    if (x <= 0xFE, minLevel := x);

    x := modbusr(SH, 511, uint16); if (x != 0x8000, cntStale := cntStale + 1);
    modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA1);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    x := modbusr(SH, 511, uint16);
    cntQ := cntQ + 1; if (x = 0x8000, cntNone := cntNone + 1); if (x = 0x20FF, cntColl := cntColl + 1);
    if (x <= 0xFE, maxLevel := x);
end
Lettura livello
var x := 0; var rx := 0; var y := 0;
if Status = 0
    if minLevel = 0
        # an unread answer left in the gateway would be taken for this query: read it away and count it
        x := modbusr(SH, 511, uint16); if (x != 0x8000, cntStale := cntStale + 1);
        modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA2);
        sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
        x := modbusr(SH, 511, uint16);
        cntQ := cntQ + 1; if (x = 0x8000, cntNone := cntNone + 1); if (x = 0x20FF, cntColl := cntColl + 1);
        if (x <= 0xFE, minLevel := x);
    end
    x := modbusr(SH, 511, uint16); if (x != 0x8000, cntStale := cntStale + 1);
    modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA0);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    x := modbusr(SH, 511, uint16);
    cntQ := cntQ + 1; if (x = 0x8000, cntNone := cntNone + 1); if (x = 0x20FF, cntColl := cntColl + 1);
    if (x != 0x8000 or rx, checkStatus := 60);
    # 0xFF = MASK, 0x20FF = collision, 0x8000 = no answer: keep the last level instead of a phantom value
    if x > 0xFE
        return(Le);
    end
    # an actual level is 0 or between the gear's min and max: anything else is not this gear's answer
    if x > 0 and x < minLevel
        cntBad := cntBad + 1;
        return(Le);
    end
    # a changed level must be read twice the same before it is taken
    if x != lastRaw
        y := modbusr(SH, 511, uint16); if (y != 0x8000, cntStale := cntStale + 1);
        modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA0);
        sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
        y := modbusr(SH, 511, uint16);
        cntQ := cntQ + 1; if (y = 0x8000, cntNone := cntNone + 1); if (y = 0x20FF, cntColl := cntColl + 1);
        if y != x
            cntBad := cntBad + 1;
            return(Le);
        end
        lastRaw := x;
    end
    return(if(x = 0, 0, linear(x, minLevel, 0.01, maxLevel, 1)));
else
    return(NaN);
end
Scrittura livello
var level := 0;
if(Le > 0, level := round(linear(Le, 0.01, minLevel, 1, maxLevel)));
modbusw(SH, 510, uint16, (ShortAddress << 8) + level );
Attributi di servizio
${xml_short_address}
ShortAddress
${xml_device_type}
var x := 0; var y := 0; var rx := 0; var s := ""; var i := 0;
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x99);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    x := modbusr(SH, 511, uint16);
    if (x < 0xFF, return("DT" + x));
    if x = 0xFF
        while i < 8
            modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA7);
            sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
            y := modbusr(SH, 511, uint16);
            if y < 0xFE
                s := if(s = "", "DT" + y, s + ", DT" + y);
                i := i + 1;
            else
                i := 8;
            end
        loop
        return(if(s = "", "MASK", s));
    end
end

return("--")
Physical Min Level
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x9A);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if (x <= 0xFE, return(round((x / 0xFE) * 100) + " %"));
end

return("--")
Max Level
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA1);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if (x <= 0xFE, return(round((x / 0xFE) * 100) + " %"));
end

return("--")
Min Level
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA2);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if (x <= 0xFE, return(round((x / 0xFE) * 100) + " %"));
end

return("--")
Power Up Level
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA3);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if (x <= 0xFE, return(round((x / 0xFE) * 100) + " %"));
end

return("--")
System Failure Level
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA4);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if (x <= 0xFE, return(round((x / 0xFE) * 100) + " %"));
end

return("--")
${xml_groups}
var x := 0; var rx := 0;
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xC0);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var g1 := modbusr(SH, 511, uint16);
    if (g1 > 0xFF, return("--")); 

    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xC1);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var g2 := modbusr(SH, 511, uint16);
    if (g2 > 0xFF, return("--")); 

    var ret := "";

    if (getbit(g1, 0), ret := ret + "0");
    if (getbit(g1, 1), if (ret = "", ret := "1", ret := ret + ",1"));
    if (getbit(g1, 2), if (ret = "", ret := "2", ret := ret + ",2"));
    if (getbit(g1, 3), if (ret = "", ret := "3", ret := ret + ",3"));
    if (getbit(g1, 4), if (ret = "", ret := "4", ret := ret + ",4"));
    if (getbit(g1, 5), if (ret = "", ret := "5", ret := ret + ",5"));
    if (getbit(g1, 6), if (ret = "", ret := "6", ret := ret + ",6"));
    if (getbit(g1, 7), if (ret = "", ret := "7", ret := ret + ",7"));
    if (getbit(g2, 0), if (ret = "", ret := "8", ret := ret + ",8"));
    if (getbit(g2, 1), if (ret = "", ret := "9", ret := ret + ",9"));
    if (getbit(g2, 2), if (ret = "", ret := "10", ret := ret + ",10"));
    if (getbit(g2, 3), if (ret = "", ret := "11", ret := ret + ",11"));
    if (getbit(g2, 4), if (ret = "", ret := "12", ret := ret + ",12"));
    if (getbit(g2, 5), if (ret = "", ret := "13", ret := ret + ",13"));
    if (getbit(g2, 6), if (ret = "", ret := "14", ret := ret + ",14"));
    if (getbit(g2, 7), if (ret = "", ret := "15", ret := ret + ",15"));

    if (ret = "", return("None"), return(ret));
else
    return("--");
end
DALI Status
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x90);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if x <= 0xFF
        var s := "";
        if (getbit(x, 0), s := if(s = "", "gear failure", s + ", gear failure"));
        if (getbit(x, 1), s := if(s = "", "lamp failure", s + ", lamp failure"));
        if (getbit(x, 2), s := if(s = "", "lamp on", s + ", lamp on"));
        if (getbit(x, 3), s := if(s = "", "limit error", s + ", limit error"));
        if (getbit(x, 4), s := if(s = "", "fade running", s + ", fade running"));
        if (getbit(x, 5), s := if(s = "", "reset state", s + ", reset state"));
        if (getbit(x, 6), s := if(s = "", "missing short address", s + ", missing short address"));
        if (getbit(x, 7), s := if(s = "", "power cycle", s + ", power cycle"));
        var ign := if((ignGear = 1) and (ignLamp = 1), "gear and lamp failure", if(ignGear = 1, "gear failure", if(ignLamp = 1, "lamp failure", "")));
        return(if(s = "", "OK", s) + " (0x" + tostring(x, "X2") + ")" + if(ign = "", "", "; not raised: " + ign + " reported since start"));
    end
end

return("--")
Fade
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA5);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if x <= 0xFF
        var t := getbits(x, 4, 4);
        var ret := if(t = 0, "off", t + " (" + round(sqrt(power(2, t)) * 5) / 10 + " s)");
        modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA8);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
        var e := modbusr(SH, 511, uint16);
        if (t = 0 and e <= 0xFF and e != 0, ret := "extended 0x" + tostring(e, "X2"));
        return("fade time " + ret + ", fade rate " + getbits(x, 0, 4));
    end
end

return("--")
DALI Version
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x97);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if x <= 0xFF
        return(if(x >= 8, "DALI-2 " + getbits(x, 2, 6) + "." + getbits(x, 0, 2), "DALI-1") + " (" + x + ")");
    end
end

return("--")
Bus statistics
return("since start: queries " + cntQ + ", stale answers read away " + cntStale + ", no answer " + cntNone + ", collisions " + cntColl + ", rejected levels " + cntBad)
Azioni di servizio
${xml_add_to_group}
Parametri: Group ID (0–15 grp)
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x60 + grp);
${xml_remove_from_group}
Parametri: Group ID (0–15 grp)
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x70 + grp);
${xml_reset_to_default_settings}
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x20);
${xml_set_startup_levels}
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x21);
sleep(10);
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x2c);
sleep(10);
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x2d);
Disable fading
modbusw(SH, 541, uint16, 0xA300);
sleep(100);
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x2E);
sleep(100);
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x30);
Gear 52 Dimmer Lettura e scrittura

Dispositivo di controllo DALI all'indirizzo breve 52 — dimmer TapHome mappato su DALI arc power 0–100 % tramite H:510 LAMP LEVEL (scrittura) e QUERY ACTUAL LEVEL tramite H:511 (lettura), delimitato dai propri MIN / MAX LEVEL del gear.

Registro: H:511 → H:510 UInt16 Unità: % numeric
Attributi di servizio
Indirizzo breveIndirizzo breve DALI (0–63) target di questo dispositivo — fissato al momento dell'importazione del template e utilizzato nel byte alto di ogni scrittura Modbus.
Device TypeByte device-type DALI restituito da QUERY DEVICE TYPE (0x99) — riporta DT0 (fluorescente), DT6 (driver LED), DT8 (colore / tunable white) ecc., o -- quando non c'è risposta.
Physical Min LevelLivello minimo di dimmerazione imposto dall'hardware riportato dal gear — letto da QUERY PHYSICAL MIN LEVEL (0x9A), in percentuale.
Max LevelDALI MAX LEVEL configurato — letto da QUERY MAX LEVEL (0xA1); utilizzato come limite superiore durante la scalatura di TapHome 0–100 % su DALI arc power.
Min LevelDALI MIN LEVEL configurato — letto da QUERY MIN LEVEL (0xA2); utilizzato come limite inferiore durante la scalatura di TapHome 0–100 % su DALI arc power.
Power Up LevelLuminosità ripristinata dopo il ripristino dell'alimentazione del bus DALI — letta da QUERY POWER ON LEVEL (0xA3).
System Failure LevelLuminosità adottata quando il bus DALI perde la comunicazione per più di 500 ms — letta da QUERY SYSTEM FAILURE LEVEL (0xA4).
GruppiElenco separato da virgole dei gruppi DALI (0–15) a cui appartiene il gear — decodificato da QUERY GROUPS 0-7 (0xC0) e QUERY GROUPS 8-15 (0xC1); mostra None o ad es. 0,3,7.
Support Lamp FailureSe la lampada / driver supporta il rilevamento dei guasti della lampada — Yes / No / --. Gestisce l'errore Lamp failure! nel readscript periodico.
Support Power FailureSe la lampada / driver supporta il rilevamento dei guasti di alimentazione — Yes / No / --. Gestisce l'errore Power failure! nel readscript periodico.
DALI Version
Bus statistics
Azioni di servizio
Add to GroupAggiunge questo gear a un gruppo DALI (0–15) tramite ADD TO GROUP (0x60+grp) — auto-ripetuto entro 100 ms come richiesto per i comandi di configurazione DALI.
Remove from GroupRimuove questo gear da un gruppo DALI (0–15) tramite REMOVE FROM GROUP (0x70+grp).
Reset to Default SettingsInvia DALI RESET (0x20) — ripristina ogni parametro NVM del gear (livelli max / min / power-on / system-failure, appartenenza al gruppo, scene) al valore predefinito del produttore.
Set Startup LevelsCattura l'arc power corrente e la memorizza come Power On Level e System Failure Level — sequenza STORE ACTUAL LEVEL IN DTR (0x21) → STORE DTR AS POWER ON LEVEL (0x2C) → STORE DTR AS SYSTEM FAILURE LEVEL (0x2D).
Disable fading

Gear 52

Lettura (modulo)
var x := 0; var rx := 0; var y := 0;
if Status > 0
    Status := Status - 1;
    adderror(3, "Gear not responding!");
    return(0);
end

# checkStatus: ReadLevel resets it while the gear answers; statusPoll: QUERY STATUS at least once per 60 runs
checkStatus := checkStatus - 1;
statusPoll := statusPoll - 1;
if checkStatus < 1 or statusPoll < 1
    # an unread answer left in the gateway would be taken for this query: read it away and count it
    x := modbusr(SH, 511, uint16); if (x != 0x8000, cntStale := cntStale + 1);
    modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x90);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    x := modbusr(SH, 511, uint16);
    cntQ := cntQ + 1; if (x = 0x8000, cntNone := cntNone + 1); if (x = 0x20FF, cntColl := cntColl + 1);
    # a single lost answer happens on DALI: ask once more before declaring the gear missing
    if x = 0x8000
        x := modbusr(SH, 511, uint16); if (x != 0x8000, cntStale := cntStale + 1);
        modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x90);
        sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
        x := modbusr(SH, 511, uint16);
        cntQ := cntQ + 1; if (x = 0x8000, cntNone := cntNone + 1); if (x = 0x20FF, cntColl := cntColl + 1);
    end
    if x <= 0xFF
        # a changed failure bit must be read twice the same before it is taken
        if statusSeen = 1 and getbits(x, 0, 2) != getbits(gearStatus, 0, 2)
            y := modbusr(SH, 511, uint16); if (y != 0x8000, cntStale := cntStale + 1);
            modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x90);
            sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
            y := modbusr(SH, 511, uint16);
            cntQ := cntQ + 1; if (y = 0x8000, cntNone := cntNone + 1); if (y = 0x20FF, cntColl := cntColl + 1);
            if y != x
                cntBad := cntBad + 1;
                x := gearStatus;
            end
        end
        if statusSeen = 0
            ignGear := getbit(x, 0);
            ignLamp := getbit(x, 1);
            statusSeen := 1;
        end
        # a bit that clears ends its ignore, so a later failure is raised
        if (getbit(x, 0) = 0, ignGear := 0);
        if (getbit(x, 1) = 0, ignLamp := 0);
        gearStatus := x;
        checkStatus := 60;
        statusPoll := 60;
    else
        if x = 0x8000
            Status := RANDINT(10, 60);
            adderror(3, "Gear not responding!");
            return(0);
        end
    end
end

# messages last one run only, so they are raised from the stored status on every run
if ((getbit(gearStatus, 0) = 1) and (ignGear = 0), adderror(1, "Control gear failure!"));
if ((getbit(gearStatus, 1) = 1) and (ignLamp = 0), adderror(2, "Lamp failure!"));
Inizializzazione
var x := 0; var rx := 0;
# QUERY STATUS 0x90: every reply byte proves the gear is present; 0x8000 = no answer, 0x20FF = bus collision
# an unread answer left in the gateway would be taken for this query: read it away and count it
x := modbusr(SH, 511, uint16); if (x != 0x8000, cntStale := cntStale + 1);
modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x90);
sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
x := modbusr(SH, 511, uint16);
cntQ := cntQ + 1; if (x = 0x8000, cntNone := cntNone + 1); if (x = 0x20FF, cntColl := cntColl + 1);
statusSeen := 0;
if x <= 0xFF
    # failure bits a gear reports from its first answer are its permanent state, not an event: shown, not raised
    gearStatus := x;
    ignGear := getbit(x, 0);
    ignLamp := getbit(x, 1);
    statusSeen := 1;
    Status := 0;
else
    Status := RANDINT(1, 60);
end

if Status = 0
    x := modbusr(SH, 511, uint16); if (x != 0x8000, cntStale := cntStale + 1);
    modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA2);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    x := modbusr(SH, 511, uint16);
    cntQ := cntQ + 1; if (x = 0x8000, cntNone := cntNone + 1); if (x = 0x20FF, cntColl := cntColl + 1);
    if (x <= 0xFE, minLevel := x);

    x := modbusr(SH, 511, uint16); if (x != 0x8000, cntStale := cntStale + 1);
    modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA1);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    x := modbusr(SH, 511, uint16);
    cntQ := cntQ + 1; if (x = 0x8000, cntNone := cntNone + 1); if (x = 0x20FF, cntColl := cntColl + 1);
    if (x <= 0xFE, maxLevel := x);
end
Lettura livello
var x := 0; var rx := 0; var y := 0;
if Status = 0
    if minLevel = 0
        # an unread answer left in the gateway would be taken for this query: read it away and count it
        x := modbusr(SH, 511, uint16); if (x != 0x8000, cntStale := cntStale + 1);
        modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA2);
        sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
        x := modbusr(SH, 511, uint16);
        cntQ := cntQ + 1; if (x = 0x8000, cntNone := cntNone + 1); if (x = 0x20FF, cntColl := cntColl + 1);
        if (x <= 0xFE, minLevel := x);
    end
    x := modbusr(SH, 511, uint16); if (x != 0x8000, cntStale := cntStale + 1);
    modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA0);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    x := modbusr(SH, 511, uint16);
    cntQ := cntQ + 1; if (x = 0x8000, cntNone := cntNone + 1); if (x = 0x20FF, cntColl := cntColl + 1);
    if (x != 0x8000 or rx, checkStatus := 60);
    # 0xFF = MASK, 0x20FF = collision, 0x8000 = no answer: keep the last level instead of a phantom value
    if x > 0xFE
        return(Le);
    end
    # an actual level is 0 or between the gear's min and max: anything else is not this gear's answer
    if x > 0 and x < minLevel
        cntBad := cntBad + 1;
        return(Le);
    end
    # a changed level must be read twice the same before it is taken
    if x != lastRaw
        y := modbusr(SH, 511, uint16); if (y != 0x8000, cntStale := cntStale + 1);
        modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA0);
        sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
        y := modbusr(SH, 511, uint16);
        cntQ := cntQ + 1; if (y = 0x8000, cntNone := cntNone + 1); if (y = 0x20FF, cntColl := cntColl + 1);
        if y != x
            cntBad := cntBad + 1;
            return(Le);
        end
        lastRaw := x;
    end
    return(if(x = 0, 0, linear(x, minLevel, 0.01, maxLevel, 1)));
else
    return(NaN);
end
Scrittura livello
var level := 0;
if(Le > 0, level := round(linear(Le, 0.01, minLevel, 1, maxLevel)));
modbusw(SH, 510, uint16, (ShortAddress << 8) + level );
Attributi di servizio
${xml_short_address}
ShortAddress
${xml_device_type}
var x := 0; var y := 0; var rx := 0; var s := ""; var i := 0;
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x99);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    x := modbusr(SH, 511, uint16);
    if (x < 0xFF, return("DT" + x));
    if x = 0xFF
        while i < 8
            modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA7);
            sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
            y := modbusr(SH, 511, uint16);
            if y < 0xFE
                s := if(s = "", "DT" + y, s + ", DT" + y);
                i := i + 1;
            else
                i := 8;
            end
        loop
        return(if(s = "", "MASK", s));
    end
end

return("--")
Physical Min Level
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x9A);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if (x <= 0xFE, return(round((x / 0xFE) * 100) + " %"));
end

return("--")
Max Level
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA1);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if (x <= 0xFE, return(round((x / 0xFE) * 100) + " %"));
end

return("--")
Min Level
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA2);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if (x <= 0xFE, return(round((x / 0xFE) * 100) + " %"));
end

return("--")
Power Up Level
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA3);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if (x <= 0xFE, return(round((x / 0xFE) * 100) + " %"));
end

return("--")
System Failure Level
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA4);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if (x <= 0xFE, return(round((x / 0xFE) * 100) + " %"));
end

return("--")
${xml_groups}
var x := 0; var rx := 0;
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xC0);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var g1 := modbusr(SH, 511, uint16);
    if (g1 > 0xFF, return("--")); 

    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xC1);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var g2 := modbusr(SH, 511, uint16);
    if (g2 > 0xFF, return("--")); 

    var ret := "";

    if (getbit(g1, 0), ret := ret + "0");
    if (getbit(g1, 1), if (ret = "", ret := "1", ret := ret + ",1"));
    if (getbit(g1, 2), if (ret = "", ret := "2", ret := ret + ",2"));
    if (getbit(g1, 3), if (ret = "", ret := "3", ret := ret + ",3"));
    if (getbit(g1, 4), if (ret = "", ret := "4", ret := ret + ",4"));
    if (getbit(g1, 5), if (ret = "", ret := "5", ret := ret + ",5"));
    if (getbit(g1, 6), if (ret = "", ret := "6", ret := ret + ",6"));
    if (getbit(g1, 7), if (ret = "", ret := "7", ret := ret + ",7"));
    if (getbit(g2, 0), if (ret = "", ret := "8", ret := ret + ",8"));
    if (getbit(g2, 1), if (ret = "", ret := "9", ret := ret + ",9"));
    if (getbit(g2, 2), if (ret = "", ret := "10", ret := ret + ",10"));
    if (getbit(g2, 3), if (ret = "", ret := "11", ret := ret + ",11"));
    if (getbit(g2, 4), if (ret = "", ret := "12", ret := ret + ",12"));
    if (getbit(g2, 5), if (ret = "", ret := "13", ret := ret + ",13"));
    if (getbit(g2, 6), if (ret = "", ret := "14", ret := ret + ",14"));
    if (getbit(g2, 7), if (ret = "", ret := "15", ret := ret + ",15"));

    if (ret = "", return("None"), return(ret));
else
    return("--");
end
DALI Status
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x90);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if x <= 0xFF
        var s := "";
        if (getbit(x, 0), s := if(s = "", "gear failure", s + ", gear failure"));
        if (getbit(x, 1), s := if(s = "", "lamp failure", s + ", lamp failure"));
        if (getbit(x, 2), s := if(s = "", "lamp on", s + ", lamp on"));
        if (getbit(x, 3), s := if(s = "", "limit error", s + ", limit error"));
        if (getbit(x, 4), s := if(s = "", "fade running", s + ", fade running"));
        if (getbit(x, 5), s := if(s = "", "reset state", s + ", reset state"));
        if (getbit(x, 6), s := if(s = "", "missing short address", s + ", missing short address"));
        if (getbit(x, 7), s := if(s = "", "power cycle", s + ", power cycle"));
        var ign := if((ignGear = 1) and (ignLamp = 1), "gear and lamp failure", if(ignGear = 1, "gear failure", if(ignLamp = 1, "lamp failure", "")));
        return(if(s = "", "OK", s) + " (0x" + tostring(x, "X2") + ")" + if(ign = "", "", "; not raised: " + ign + " reported since start"));
    end
end

return("--")
Fade
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA5);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if x <= 0xFF
        var t := getbits(x, 4, 4);
        var ret := if(t = 0, "off", t + " (" + round(sqrt(power(2, t)) * 5) / 10 + " s)");
        modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA8);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
        var e := modbusr(SH, 511, uint16);
        if (t = 0 and e <= 0xFF and e != 0, ret := "extended 0x" + tostring(e, "X2"));
        return("fade time " + ret + ", fade rate " + getbits(x, 0, 4));
    end
end

return("--")
DALI Version
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x97);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if x <= 0xFF
        return(if(x >= 8, "DALI-2 " + getbits(x, 2, 6) + "." + getbits(x, 0, 2), "DALI-1") + " (" + x + ")");
    end
end

return("--")
Bus statistics
return("since start: queries " + cntQ + ", stale answers read away " + cntStale + ", no answer " + cntNone + ", collisions " + cntColl + ", rejected levels " + cntBad)
Azioni di servizio
${xml_add_to_group}
Parametri: Group ID (0–15 grp)
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x60 + grp);
${xml_remove_from_group}
Parametri: Group ID (0–15 grp)
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x70 + grp);
${xml_reset_to_default_settings}
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x20);
${xml_set_startup_levels}
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x21);
sleep(10);
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x2c);
sleep(10);
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x2d);
Disable fading
modbusw(SH, 541, uint16, 0xA300);
sleep(100);
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x2E);
sleep(100);
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x30);
Gear 53 Dimmer Lettura e scrittura

Dispositivo di controllo DALI all'indirizzo breve 53 — dimmer TapHome mappato su DALI arc power 0–100 % tramite H:510 LAMP LEVEL (scrittura) e QUERY ACTUAL LEVEL tramite H:511 (lettura), delimitato dai propri MIN / MAX LEVEL del gear.

Registro: H:511 → H:510 UInt16 Unità: % numeric
Attributi di servizio
Indirizzo breveIndirizzo breve DALI (0–63) target di questo dispositivo — fissato al momento dell'importazione del template e utilizzato nel byte alto di ogni scrittura Modbus.
Device TypeByte device-type DALI restituito da QUERY DEVICE TYPE (0x99) — riporta DT0 (fluorescente), DT6 (driver LED), DT8 (colore / tunable white) ecc., o -- quando non c'è risposta.
Physical Min LevelLivello minimo di dimmerazione imposto dall'hardware riportato dal gear — letto da QUERY PHYSICAL MIN LEVEL (0x9A), in percentuale.
Max LevelDALI MAX LEVEL configurato — letto da QUERY MAX LEVEL (0xA1); utilizzato come limite superiore durante la scalatura di TapHome 0–100 % su DALI arc power.
Min LevelDALI MIN LEVEL configurato — letto da QUERY MIN LEVEL (0xA2); utilizzato come limite inferiore durante la scalatura di TapHome 0–100 % su DALI arc power.
Power Up LevelLuminosità ripristinata dopo il ripristino dell'alimentazione del bus DALI — letta da QUERY POWER ON LEVEL (0xA3).
System Failure LevelLuminosità adottata quando il bus DALI perde la comunicazione per più di 500 ms — letta da QUERY SYSTEM FAILURE LEVEL (0xA4).
GruppiElenco separato da virgole dei gruppi DALI (0–15) a cui appartiene il gear — decodificato da QUERY GROUPS 0-7 (0xC0) e QUERY GROUPS 8-15 (0xC1); mostra None o ad es. 0,3,7.
Support Lamp FailureSe la lampada / driver supporta il rilevamento dei guasti della lampada — Yes / No / --. Gestisce l'errore Lamp failure! nel readscript periodico.
Support Power FailureSe la lampada / driver supporta il rilevamento dei guasti di alimentazione — Yes / No / --. Gestisce l'errore Power failure! nel readscript periodico.
DALI Version
Bus statistics
Azioni di servizio
Add to GroupAggiunge questo gear a un gruppo DALI (0–15) tramite ADD TO GROUP (0x60+grp) — auto-ripetuto entro 100 ms come richiesto per i comandi di configurazione DALI.
Remove from GroupRimuove questo gear da un gruppo DALI (0–15) tramite REMOVE FROM GROUP (0x70+grp).
Reset to Default SettingsInvia DALI RESET (0x20) — ripristina ogni parametro NVM del gear (livelli max / min / power-on / system-failure, appartenenza al gruppo, scene) al valore predefinito del produttore.
Set Startup LevelsCattura l'arc power corrente e la memorizza come Power On Level e System Failure Level — sequenza STORE ACTUAL LEVEL IN DTR (0x21) → STORE DTR AS POWER ON LEVEL (0x2C) → STORE DTR AS SYSTEM FAILURE LEVEL (0x2D).
Disable fading

Gear 53

Lettura (modulo)
var x := 0; var rx := 0; var y := 0;
if Status > 0
    Status := Status - 1;
    adderror(3, "Gear not responding!");
    return(0);
end

# checkStatus: ReadLevel resets it while the gear answers; statusPoll: QUERY STATUS at least once per 60 runs
checkStatus := checkStatus - 1;
statusPoll := statusPoll - 1;
if checkStatus < 1 or statusPoll < 1
    # an unread answer left in the gateway would be taken for this query: read it away and count it
    x := modbusr(SH, 511, uint16); if (x != 0x8000, cntStale := cntStale + 1);
    modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x90);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    x := modbusr(SH, 511, uint16);
    cntQ := cntQ + 1; if (x = 0x8000, cntNone := cntNone + 1); if (x = 0x20FF, cntColl := cntColl + 1);
    # a single lost answer happens on DALI: ask once more before declaring the gear missing
    if x = 0x8000
        x := modbusr(SH, 511, uint16); if (x != 0x8000, cntStale := cntStale + 1);
        modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x90);
        sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
        x := modbusr(SH, 511, uint16);
        cntQ := cntQ + 1; if (x = 0x8000, cntNone := cntNone + 1); if (x = 0x20FF, cntColl := cntColl + 1);
    end
    if x <= 0xFF
        # a changed failure bit must be read twice the same before it is taken
        if statusSeen = 1 and getbits(x, 0, 2) != getbits(gearStatus, 0, 2)
            y := modbusr(SH, 511, uint16); if (y != 0x8000, cntStale := cntStale + 1);
            modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x90);
            sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
            y := modbusr(SH, 511, uint16);
            cntQ := cntQ + 1; if (y = 0x8000, cntNone := cntNone + 1); if (y = 0x20FF, cntColl := cntColl + 1);
            if y != x
                cntBad := cntBad + 1;
                x := gearStatus;
            end
        end
        if statusSeen = 0
            ignGear := getbit(x, 0);
            ignLamp := getbit(x, 1);
            statusSeen := 1;
        end
        # a bit that clears ends its ignore, so a later failure is raised
        if (getbit(x, 0) = 0, ignGear := 0);
        if (getbit(x, 1) = 0, ignLamp := 0);
        gearStatus := x;
        checkStatus := 60;
        statusPoll := 60;
    else
        if x = 0x8000
            Status := RANDINT(10, 60);
            adderror(3, "Gear not responding!");
            return(0);
        end
    end
end

# messages last one run only, so they are raised from the stored status on every run
if ((getbit(gearStatus, 0) = 1) and (ignGear = 0), adderror(1, "Control gear failure!"));
if ((getbit(gearStatus, 1) = 1) and (ignLamp = 0), adderror(2, "Lamp failure!"));
Inizializzazione
var x := 0; var rx := 0;
# QUERY STATUS 0x90: every reply byte proves the gear is present; 0x8000 = no answer, 0x20FF = bus collision
# an unread answer left in the gateway would be taken for this query: read it away and count it
x := modbusr(SH, 511, uint16); if (x != 0x8000, cntStale := cntStale + 1);
modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x90);
sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
x := modbusr(SH, 511, uint16);
cntQ := cntQ + 1; if (x = 0x8000, cntNone := cntNone + 1); if (x = 0x20FF, cntColl := cntColl + 1);
statusSeen := 0;
if x <= 0xFF
    # failure bits a gear reports from its first answer are its permanent state, not an event: shown, not raised
    gearStatus := x;
    ignGear := getbit(x, 0);
    ignLamp := getbit(x, 1);
    statusSeen := 1;
    Status := 0;
else
    Status := RANDINT(1, 60);
end

if Status = 0
    x := modbusr(SH, 511, uint16); if (x != 0x8000, cntStale := cntStale + 1);
    modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA2);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    x := modbusr(SH, 511, uint16);
    cntQ := cntQ + 1; if (x = 0x8000, cntNone := cntNone + 1); if (x = 0x20FF, cntColl := cntColl + 1);
    if (x <= 0xFE, minLevel := x);

    x := modbusr(SH, 511, uint16); if (x != 0x8000, cntStale := cntStale + 1);
    modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA1);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    x := modbusr(SH, 511, uint16);
    cntQ := cntQ + 1; if (x = 0x8000, cntNone := cntNone + 1); if (x = 0x20FF, cntColl := cntColl + 1);
    if (x <= 0xFE, maxLevel := x);
end
Lettura livello
var x := 0; var rx := 0; var y := 0;
if Status = 0
    if minLevel = 0
        # an unread answer left in the gateway would be taken for this query: read it away and count it
        x := modbusr(SH, 511, uint16); if (x != 0x8000, cntStale := cntStale + 1);
        modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA2);
        sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
        x := modbusr(SH, 511, uint16);
        cntQ := cntQ + 1; if (x = 0x8000, cntNone := cntNone + 1); if (x = 0x20FF, cntColl := cntColl + 1);
        if (x <= 0xFE, minLevel := x);
    end
    x := modbusr(SH, 511, uint16); if (x != 0x8000, cntStale := cntStale + 1);
    modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA0);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    x := modbusr(SH, 511, uint16);
    cntQ := cntQ + 1; if (x = 0x8000, cntNone := cntNone + 1); if (x = 0x20FF, cntColl := cntColl + 1);
    if (x != 0x8000 or rx, checkStatus := 60);
    # 0xFF = MASK, 0x20FF = collision, 0x8000 = no answer: keep the last level instead of a phantom value
    if x > 0xFE
        return(Le);
    end
    # an actual level is 0 or between the gear's min and max: anything else is not this gear's answer
    if x > 0 and x < minLevel
        cntBad := cntBad + 1;
        return(Le);
    end
    # a changed level must be read twice the same before it is taken
    if x != lastRaw
        y := modbusr(SH, 511, uint16); if (y != 0x8000, cntStale := cntStale + 1);
        modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA0);
        sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
        y := modbusr(SH, 511, uint16);
        cntQ := cntQ + 1; if (y = 0x8000, cntNone := cntNone + 1); if (y = 0x20FF, cntColl := cntColl + 1);
        if y != x
            cntBad := cntBad + 1;
            return(Le);
        end
        lastRaw := x;
    end
    return(if(x = 0, 0, linear(x, minLevel, 0.01, maxLevel, 1)));
else
    return(NaN);
end
Scrittura livello
var level := 0;
if(Le > 0, level := round(linear(Le, 0.01, minLevel, 1, maxLevel)));
modbusw(SH, 510, uint16, (ShortAddress << 8) + level );
Attributi di servizio
${xml_short_address}
ShortAddress
${xml_device_type}
var x := 0; var y := 0; var rx := 0; var s := ""; var i := 0;
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x99);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    x := modbusr(SH, 511, uint16);
    if (x < 0xFF, return("DT" + x));
    if x = 0xFF
        while i < 8
            modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA7);
            sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
            y := modbusr(SH, 511, uint16);
            if y < 0xFE
                s := if(s = "", "DT" + y, s + ", DT" + y);
                i := i + 1;
            else
                i := 8;
            end
        loop
        return(if(s = "", "MASK", s));
    end
end

return("--")
Physical Min Level
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x9A);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if (x <= 0xFE, return(round((x / 0xFE) * 100) + " %"));
end

return("--")
Max Level
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA1);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if (x <= 0xFE, return(round((x / 0xFE) * 100) + " %"));
end

return("--")
Min Level
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA2);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if (x <= 0xFE, return(round((x / 0xFE) * 100) + " %"));
end

return("--")
Power Up Level
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA3);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if (x <= 0xFE, return(round((x / 0xFE) * 100) + " %"));
end

return("--")
System Failure Level
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA4);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if (x <= 0xFE, return(round((x / 0xFE) * 100) + " %"));
end

return("--")
${xml_groups}
var x := 0; var rx := 0;
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xC0);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var g1 := modbusr(SH, 511, uint16);
    if (g1 > 0xFF, return("--")); 

    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xC1);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var g2 := modbusr(SH, 511, uint16);
    if (g2 > 0xFF, return("--")); 

    var ret := "";

    if (getbit(g1, 0), ret := ret + "0");
    if (getbit(g1, 1), if (ret = "", ret := "1", ret := ret + ",1"));
    if (getbit(g1, 2), if (ret = "", ret := "2", ret := ret + ",2"));
    if (getbit(g1, 3), if (ret = "", ret := "3", ret := ret + ",3"));
    if (getbit(g1, 4), if (ret = "", ret := "4", ret := ret + ",4"));
    if (getbit(g1, 5), if (ret = "", ret := "5", ret := ret + ",5"));
    if (getbit(g1, 6), if (ret = "", ret := "6", ret := ret + ",6"));
    if (getbit(g1, 7), if (ret = "", ret := "7", ret := ret + ",7"));
    if (getbit(g2, 0), if (ret = "", ret := "8", ret := ret + ",8"));
    if (getbit(g2, 1), if (ret = "", ret := "9", ret := ret + ",9"));
    if (getbit(g2, 2), if (ret = "", ret := "10", ret := ret + ",10"));
    if (getbit(g2, 3), if (ret = "", ret := "11", ret := ret + ",11"));
    if (getbit(g2, 4), if (ret = "", ret := "12", ret := ret + ",12"));
    if (getbit(g2, 5), if (ret = "", ret := "13", ret := ret + ",13"));
    if (getbit(g2, 6), if (ret = "", ret := "14", ret := ret + ",14"));
    if (getbit(g2, 7), if (ret = "", ret := "15", ret := ret + ",15"));

    if (ret = "", return("None"), return(ret));
else
    return("--");
end
DALI Status
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x90);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if x <= 0xFF
        var s := "";
        if (getbit(x, 0), s := if(s = "", "gear failure", s + ", gear failure"));
        if (getbit(x, 1), s := if(s = "", "lamp failure", s + ", lamp failure"));
        if (getbit(x, 2), s := if(s = "", "lamp on", s + ", lamp on"));
        if (getbit(x, 3), s := if(s = "", "limit error", s + ", limit error"));
        if (getbit(x, 4), s := if(s = "", "fade running", s + ", fade running"));
        if (getbit(x, 5), s := if(s = "", "reset state", s + ", reset state"));
        if (getbit(x, 6), s := if(s = "", "missing short address", s + ", missing short address"));
        if (getbit(x, 7), s := if(s = "", "power cycle", s + ", power cycle"));
        var ign := if((ignGear = 1) and (ignLamp = 1), "gear and lamp failure", if(ignGear = 1, "gear failure", if(ignLamp = 1, "lamp failure", "")));
        return(if(s = "", "OK", s) + " (0x" + tostring(x, "X2") + ")" + if(ign = "", "", "; not raised: " + ign + " reported since start"));
    end
end

return("--")
Fade
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA5);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if x <= 0xFF
        var t := getbits(x, 4, 4);
        var ret := if(t = 0, "off", t + " (" + round(sqrt(power(2, t)) * 5) / 10 + " s)");
        modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA8);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
        var e := modbusr(SH, 511, uint16);
        if (t = 0 and e <= 0xFF and e != 0, ret := "extended 0x" + tostring(e, "X2"));
        return("fade time " + ret + ", fade rate " + getbits(x, 0, 4));
    end
end

return("--")
DALI Version
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x97);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if x <= 0xFF
        return(if(x >= 8, "DALI-2 " + getbits(x, 2, 6) + "." + getbits(x, 0, 2), "DALI-1") + " (" + x + ")");
    end
end

return("--")
Bus statistics
return("since start: queries " + cntQ + ", stale answers read away " + cntStale + ", no answer " + cntNone + ", collisions " + cntColl + ", rejected levels " + cntBad)
Azioni di servizio
${xml_add_to_group}
Parametri: Group ID (0–15 grp)
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x60 + grp);
${xml_remove_from_group}
Parametri: Group ID (0–15 grp)
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x70 + grp);
${xml_reset_to_default_settings}
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x20);
${xml_set_startup_levels}
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x21);
sleep(10);
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x2c);
sleep(10);
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x2d);
Disable fading
modbusw(SH, 541, uint16, 0xA300);
sleep(100);
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x2E);
sleep(100);
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x30);
Gear 54 Dimmer Lettura e scrittura

Dispositivo di controllo DALI all'indirizzo breve 54 — dimmer TapHome mappato su DALI arc power 0–100 % tramite H:510 LAMP LEVEL (scrittura) e QUERY ACTUAL LEVEL tramite H:511 (lettura), delimitato dai propri MIN / MAX LEVEL del gear.

Registro: H:511 → H:510 UInt16 Unità: % numeric
Attributi di servizio
Indirizzo breveIndirizzo breve DALI (0–63) target di questo dispositivo — fissato al momento dell'importazione del template e utilizzato nel byte alto di ogni scrittura Modbus.
Device TypeByte device-type DALI restituito da QUERY DEVICE TYPE (0x99) — riporta DT0 (fluorescente), DT6 (driver LED), DT8 (colore / tunable white) ecc., o -- quando non c'è risposta.
Physical Min LevelLivello minimo di dimmerazione imposto dall'hardware riportato dal gear — letto da QUERY PHYSICAL MIN LEVEL (0x9A), in percentuale.
Max LevelDALI MAX LEVEL configurato — letto da QUERY MAX LEVEL (0xA1); utilizzato come limite superiore durante la scalatura di TapHome 0–100 % su DALI arc power.
Min LevelDALI MIN LEVEL configurato — letto da QUERY MIN LEVEL (0xA2); utilizzato come limite inferiore durante la scalatura di TapHome 0–100 % su DALI arc power.
Power Up LevelLuminosità ripristinata dopo il ripristino dell'alimentazione del bus DALI — letta da QUERY POWER ON LEVEL (0xA3).
System Failure LevelLuminosità adottata quando il bus DALI perde la comunicazione per più di 500 ms — letta da QUERY SYSTEM FAILURE LEVEL (0xA4).
GruppiElenco separato da virgole dei gruppi DALI (0–15) a cui appartiene il gear — decodificato da QUERY GROUPS 0-7 (0xC0) e QUERY GROUPS 8-15 (0xC1); mostra None o ad es. 0,3,7.
Support Lamp FailureSe la lampada / driver supporta il rilevamento dei guasti della lampada — Yes / No / --. Gestisce l'errore Lamp failure! nel readscript periodico.
Support Power FailureSe la lampada / driver supporta il rilevamento dei guasti di alimentazione — Yes / No / --. Gestisce l'errore Power failure! nel readscript periodico.
DALI Version
Bus statistics
Azioni di servizio
Add to GroupAggiunge questo gear a un gruppo DALI (0–15) tramite ADD TO GROUP (0x60+grp) — auto-ripetuto entro 100 ms come richiesto per i comandi di configurazione DALI.
Remove from GroupRimuove questo gear da un gruppo DALI (0–15) tramite REMOVE FROM GROUP (0x70+grp).
Reset to Default SettingsInvia DALI RESET (0x20) — ripristina ogni parametro NVM del gear (livelli max / min / power-on / system-failure, appartenenza al gruppo, scene) al valore predefinito del produttore.
Set Startup LevelsCattura l'arc power corrente e la memorizza come Power On Level e System Failure Level — sequenza STORE ACTUAL LEVEL IN DTR (0x21) → STORE DTR AS POWER ON LEVEL (0x2C) → STORE DTR AS SYSTEM FAILURE LEVEL (0x2D).
Disable fading

Gear 54

Lettura (modulo)
var x := 0; var rx := 0; var y := 0;
if Status > 0
    Status := Status - 1;
    adderror(3, "Gear not responding!");
    return(0);
end

# checkStatus: ReadLevel resets it while the gear answers; statusPoll: QUERY STATUS at least once per 60 runs
checkStatus := checkStatus - 1;
statusPoll := statusPoll - 1;
if checkStatus < 1 or statusPoll < 1
    # an unread answer left in the gateway would be taken for this query: read it away and count it
    x := modbusr(SH, 511, uint16); if (x != 0x8000, cntStale := cntStale + 1);
    modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x90);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    x := modbusr(SH, 511, uint16);
    cntQ := cntQ + 1; if (x = 0x8000, cntNone := cntNone + 1); if (x = 0x20FF, cntColl := cntColl + 1);
    # a single lost answer happens on DALI: ask once more before declaring the gear missing
    if x = 0x8000
        x := modbusr(SH, 511, uint16); if (x != 0x8000, cntStale := cntStale + 1);
        modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x90);
        sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
        x := modbusr(SH, 511, uint16);
        cntQ := cntQ + 1; if (x = 0x8000, cntNone := cntNone + 1); if (x = 0x20FF, cntColl := cntColl + 1);
    end
    if x <= 0xFF
        # a changed failure bit must be read twice the same before it is taken
        if statusSeen = 1 and getbits(x, 0, 2) != getbits(gearStatus, 0, 2)
            y := modbusr(SH, 511, uint16); if (y != 0x8000, cntStale := cntStale + 1);
            modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x90);
            sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
            y := modbusr(SH, 511, uint16);
            cntQ := cntQ + 1; if (y = 0x8000, cntNone := cntNone + 1); if (y = 0x20FF, cntColl := cntColl + 1);
            if y != x
                cntBad := cntBad + 1;
                x := gearStatus;
            end
        end
        if statusSeen = 0
            ignGear := getbit(x, 0);
            ignLamp := getbit(x, 1);
            statusSeen := 1;
        end
        # a bit that clears ends its ignore, so a later failure is raised
        if (getbit(x, 0) = 0, ignGear := 0);
        if (getbit(x, 1) = 0, ignLamp := 0);
        gearStatus := x;
        checkStatus := 60;
        statusPoll := 60;
    else
        if x = 0x8000
            Status := RANDINT(10, 60);
            adderror(3, "Gear not responding!");
            return(0);
        end
    end
end

# messages last one run only, so they are raised from the stored status on every run
if ((getbit(gearStatus, 0) = 1) and (ignGear = 0), adderror(1, "Control gear failure!"));
if ((getbit(gearStatus, 1) = 1) and (ignLamp = 0), adderror(2, "Lamp failure!"));
Inizializzazione
var x := 0; var rx := 0;
# QUERY STATUS 0x90: every reply byte proves the gear is present; 0x8000 = no answer, 0x20FF = bus collision
# an unread answer left in the gateway would be taken for this query: read it away and count it
x := modbusr(SH, 511, uint16); if (x != 0x8000, cntStale := cntStale + 1);
modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x90);
sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
x := modbusr(SH, 511, uint16);
cntQ := cntQ + 1; if (x = 0x8000, cntNone := cntNone + 1); if (x = 0x20FF, cntColl := cntColl + 1);
statusSeen := 0;
if x <= 0xFF
    # failure bits a gear reports from its first answer are its permanent state, not an event: shown, not raised
    gearStatus := x;
    ignGear := getbit(x, 0);
    ignLamp := getbit(x, 1);
    statusSeen := 1;
    Status := 0;
else
    Status := RANDINT(1, 60);
end

if Status = 0
    x := modbusr(SH, 511, uint16); if (x != 0x8000, cntStale := cntStale + 1);
    modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA2);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    x := modbusr(SH, 511, uint16);
    cntQ := cntQ + 1; if (x = 0x8000, cntNone := cntNone + 1); if (x = 0x20FF, cntColl := cntColl + 1);
    if (x <= 0xFE, minLevel := x);

    x := modbusr(SH, 511, uint16); if (x != 0x8000, cntStale := cntStale + 1);
    modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA1);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    x := modbusr(SH, 511, uint16);
    cntQ := cntQ + 1; if (x = 0x8000, cntNone := cntNone + 1); if (x = 0x20FF, cntColl := cntColl + 1);
    if (x <= 0xFE, maxLevel := x);
end
Lettura livello
var x := 0; var rx := 0; var y := 0;
if Status = 0
    if minLevel = 0
        # an unread answer left in the gateway would be taken for this query: read it away and count it
        x := modbusr(SH, 511, uint16); if (x != 0x8000, cntStale := cntStale + 1);
        modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA2);
        sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
        x := modbusr(SH, 511, uint16);
        cntQ := cntQ + 1; if (x = 0x8000, cntNone := cntNone + 1); if (x = 0x20FF, cntColl := cntColl + 1);
        if (x <= 0xFE, minLevel := x);
    end
    x := modbusr(SH, 511, uint16); if (x != 0x8000, cntStale := cntStale + 1);
    modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA0);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    x := modbusr(SH, 511, uint16);
    cntQ := cntQ + 1; if (x = 0x8000, cntNone := cntNone + 1); if (x = 0x20FF, cntColl := cntColl + 1);
    if (x != 0x8000 or rx, checkStatus := 60);
    # 0xFF = MASK, 0x20FF = collision, 0x8000 = no answer: keep the last level instead of a phantom value
    if x > 0xFE
        return(Le);
    end
    # an actual level is 0 or between the gear's min and max: anything else is not this gear's answer
    if x > 0 and x < minLevel
        cntBad := cntBad + 1;
        return(Le);
    end
    # a changed level must be read twice the same before it is taken
    if x != lastRaw
        y := modbusr(SH, 511, uint16); if (y != 0x8000, cntStale := cntStale + 1);
        modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA0);
        sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
        y := modbusr(SH, 511, uint16);
        cntQ := cntQ + 1; if (y = 0x8000, cntNone := cntNone + 1); if (y = 0x20FF, cntColl := cntColl + 1);
        if y != x
            cntBad := cntBad + 1;
            return(Le);
        end
        lastRaw := x;
    end
    return(if(x = 0, 0, linear(x, minLevel, 0.01, maxLevel, 1)));
else
    return(NaN);
end
Scrittura livello
var level := 0;
if(Le > 0, level := round(linear(Le, 0.01, minLevel, 1, maxLevel)));
modbusw(SH, 510, uint16, (ShortAddress << 8) + level );
Attributi di servizio
${xml_short_address}
ShortAddress
${xml_device_type}
var x := 0; var y := 0; var rx := 0; var s := ""; var i := 0;
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x99);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    x := modbusr(SH, 511, uint16);
    if (x < 0xFF, return("DT" + x));
    if x = 0xFF
        while i < 8
            modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA7);
            sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
            y := modbusr(SH, 511, uint16);
            if y < 0xFE
                s := if(s = "", "DT" + y, s + ", DT" + y);
                i := i + 1;
            else
                i := 8;
            end
        loop
        return(if(s = "", "MASK", s));
    end
end

return("--")
Physical Min Level
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x9A);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if (x <= 0xFE, return(round((x / 0xFE) * 100) + " %"));
end

return("--")
Max Level
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA1);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if (x <= 0xFE, return(round((x / 0xFE) * 100) + " %"));
end

return("--")
Min Level
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA2);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if (x <= 0xFE, return(round((x / 0xFE) * 100) + " %"));
end

return("--")
Power Up Level
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA3);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if (x <= 0xFE, return(round((x / 0xFE) * 100) + " %"));
end

return("--")
System Failure Level
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA4);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if (x <= 0xFE, return(round((x / 0xFE) * 100) + " %"));
end

return("--")
${xml_groups}
var x := 0; var rx := 0;
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xC0);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var g1 := modbusr(SH, 511, uint16);
    if (g1 > 0xFF, return("--")); 

    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xC1);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var g2 := modbusr(SH, 511, uint16);
    if (g2 > 0xFF, return("--")); 

    var ret := "";

    if (getbit(g1, 0), ret := ret + "0");
    if (getbit(g1, 1), if (ret = "", ret := "1", ret := ret + ",1"));
    if (getbit(g1, 2), if (ret = "", ret := "2", ret := ret + ",2"));
    if (getbit(g1, 3), if (ret = "", ret := "3", ret := ret + ",3"));
    if (getbit(g1, 4), if (ret = "", ret := "4", ret := ret + ",4"));
    if (getbit(g1, 5), if (ret = "", ret := "5", ret := ret + ",5"));
    if (getbit(g1, 6), if (ret = "", ret := "6", ret := ret + ",6"));
    if (getbit(g1, 7), if (ret = "", ret := "7", ret := ret + ",7"));
    if (getbit(g2, 0), if (ret = "", ret := "8", ret := ret + ",8"));
    if (getbit(g2, 1), if (ret = "", ret := "9", ret := ret + ",9"));
    if (getbit(g2, 2), if (ret = "", ret := "10", ret := ret + ",10"));
    if (getbit(g2, 3), if (ret = "", ret := "11", ret := ret + ",11"));
    if (getbit(g2, 4), if (ret = "", ret := "12", ret := ret + ",12"));
    if (getbit(g2, 5), if (ret = "", ret := "13", ret := ret + ",13"));
    if (getbit(g2, 6), if (ret = "", ret := "14", ret := ret + ",14"));
    if (getbit(g2, 7), if (ret = "", ret := "15", ret := ret + ",15"));

    if (ret = "", return("None"), return(ret));
else
    return("--");
end
DALI Status
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x90);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if x <= 0xFF
        var s := "";
        if (getbit(x, 0), s := if(s = "", "gear failure", s + ", gear failure"));
        if (getbit(x, 1), s := if(s = "", "lamp failure", s + ", lamp failure"));
        if (getbit(x, 2), s := if(s = "", "lamp on", s + ", lamp on"));
        if (getbit(x, 3), s := if(s = "", "limit error", s + ", limit error"));
        if (getbit(x, 4), s := if(s = "", "fade running", s + ", fade running"));
        if (getbit(x, 5), s := if(s = "", "reset state", s + ", reset state"));
        if (getbit(x, 6), s := if(s = "", "missing short address", s + ", missing short address"));
        if (getbit(x, 7), s := if(s = "", "power cycle", s + ", power cycle"));
        var ign := if((ignGear = 1) and (ignLamp = 1), "gear and lamp failure", if(ignGear = 1, "gear failure", if(ignLamp = 1, "lamp failure", "")));
        return(if(s = "", "OK", s) + " (0x" + tostring(x, "X2") + ")" + if(ign = "", "", "; not raised: " + ign + " reported since start"));
    end
end

return("--")
Fade
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA5);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if x <= 0xFF
        var t := getbits(x, 4, 4);
        var ret := if(t = 0, "off", t + " (" + round(sqrt(power(2, t)) * 5) / 10 + " s)");
        modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA8);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
        var e := modbusr(SH, 511, uint16);
        if (t = 0 and e <= 0xFF and e != 0, ret := "extended 0x" + tostring(e, "X2"));
        return("fade time " + ret + ", fade rate " + getbits(x, 0, 4));
    end
end

return("--")
DALI Version
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x97);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if x <= 0xFF
        return(if(x >= 8, "DALI-2 " + getbits(x, 2, 6) + "." + getbits(x, 0, 2), "DALI-1") + " (" + x + ")");
    end
end

return("--")
Bus statistics
return("since start: queries " + cntQ + ", stale answers read away " + cntStale + ", no answer " + cntNone + ", collisions " + cntColl + ", rejected levels " + cntBad)
Azioni di servizio
${xml_add_to_group}
Parametri: Group ID (0–15 grp)
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x60 + grp);
${xml_remove_from_group}
Parametri: Group ID (0–15 grp)
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x70 + grp);
${xml_reset_to_default_settings}
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x20);
${xml_set_startup_levels}
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x21);
sleep(10);
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x2c);
sleep(10);
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x2d);
Disable fading
modbusw(SH, 541, uint16, 0xA300);
sleep(100);
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x2E);
sleep(100);
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x30);
Gear 55 Dimmer Lettura e scrittura

Dispositivo di controllo DALI all'indirizzo breve 55 — dimmer TapHome mappato su DALI arc power 0–100 % tramite H:510 LAMP LEVEL (scrittura) e QUERY ACTUAL LEVEL tramite H:511 (lettura), delimitato dai propri MIN / MAX LEVEL del gear.

Registro: H:511 → H:510 UInt16 Unità: % numeric
Attributi di servizio
Indirizzo breveIndirizzo breve DALI (0–63) target di questo dispositivo — fissato al momento dell'importazione del template e utilizzato nel byte alto di ogni scrittura Modbus.
Device TypeByte device-type DALI restituito da QUERY DEVICE TYPE (0x99) — riporta DT0 (fluorescente), DT6 (driver LED), DT8 (colore / tunable white) ecc., o -- quando non c'è risposta.
Physical Min LevelLivello minimo di dimmerazione imposto dall'hardware riportato dal gear — letto da QUERY PHYSICAL MIN LEVEL (0x9A), in percentuale.
Max LevelDALI MAX LEVEL configurato — letto da QUERY MAX LEVEL (0xA1); utilizzato come limite superiore durante la scalatura di TapHome 0–100 % su DALI arc power.
Min LevelDALI MIN LEVEL configurato — letto da QUERY MIN LEVEL (0xA2); utilizzato come limite inferiore durante la scalatura di TapHome 0–100 % su DALI arc power.
Power Up LevelLuminosità ripristinata dopo il ripristino dell'alimentazione del bus DALI — letta da QUERY POWER ON LEVEL (0xA3).
System Failure LevelLuminosità adottata quando il bus DALI perde la comunicazione per più di 500 ms — letta da QUERY SYSTEM FAILURE LEVEL (0xA4).
GruppiElenco separato da virgole dei gruppi DALI (0–15) a cui appartiene il gear — decodificato da QUERY GROUPS 0-7 (0xC0) e QUERY GROUPS 8-15 (0xC1); mostra None o ad es. 0,3,7.
Support Lamp FailureSe la lampada / driver supporta il rilevamento dei guasti della lampada — Yes / No / --. Gestisce l'errore Lamp failure! nel readscript periodico.
Support Power FailureSe la lampada / driver supporta il rilevamento dei guasti di alimentazione — Yes / No / --. Gestisce l'errore Power failure! nel readscript periodico.
DALI Version
Bus statistics
Azioni di servizio
Add to GroupAggiunge questo gear a un gruppo DALI (0–15) tramite ADD TO GROUP (0x60+grp) — auto-ripetuto entro 100 ms come richiesto per i comandi di configurazione DALI.
Remove from GroupRimuove questo gear da un gruppo DALI (0–15) tramite REMOVE FROM GROUP (0x70+grp).
Reset to Default SettingsInvia DALI RESET (0x20) — ripristina ogni parametro NVM del gear (livelli max / min / power-on / system-failure, appartenenza al gruppo, scene) al valore predefinito del produttore.
Set Startup LevelsCattura l'arc power corrente e la memorizza come Power On Level e System Failure Level — sequenza STORE ACTUAL LEVEL IN DTR (0x21) → STORE DTR AS POWER ON LEVEL (0x2C) → STORE DTR AS SYSTEM FAILURE LEVEL (0x2D).
Disable fading

Gear 55

Lettura (modulo)
var x := 0; var rx := 0; var y := 0;
if Status > 0
    Status := Status - 1;
    adderror(3, "Gear not responding!");
    return(0);
end

# checkStatus: ReadLevel resets it while the gear answers; statusPoll: QUERY STATUS at least once per 60 runs
checkStatus := checkStatus - 1;
statusPoll := statusPoll - 1;
if checkStatus < 1 or statusPoll < 1
    # an unread answer left in the gateway would be taken for this query: read it away and count it
    x := modbusr(SH, 511, uint16); if (x != 0x8000, cntStale := cntStale + 1);
    modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x90);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    x := modbusr(SH, 511, uint16);
    cntQ := cntQ + 1; if (x = 0x8000, cntNone := cntNone + 1); if (x = 0x20FF, cntColl := cntColl + 1);
    # a single lost answer happens on DALI: ask once more before declaring the gear missing
    if x = 0x8000
        x := modbusr(SH, 511, uint16); if (x != 0x8000, cntStale := cntStale + 1);
        modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x90);
        sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
        x := modbusr(SH, 511, uint16);
        cntQ := cntQ + 1; if (x = 0x8000, cntNone := cntNone + 1); if (x = 0x20FF, cntColl := cntColl + 1);
    end
    if x <= 0xFF
        # a changed failure bit must be read twice the same before it is taken
        if statusSeen = 1 and getbits(x, 0, 2) != getbits(gearStatus, 0, 2)
            y := modbusr(SH, 511, uint16); if (y != 0x8000, cntStale := cntStale + 1);
            modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x90);
            sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
            y := modbusr(SH, 511, uint16);
            cntQ := cntQ + 1; if (y = 0x8000, cntNone := cntNone + 1); if (y = 0x20FF, cntColl := cntColl + 1);
            if y != x
                cntBad := cntBad + 1;
                x := gearStatus;
            end
        end
        if statusSeen = 0
            ignGear := getbit(x, 0);
            ignLamp := getbit(x, 1);
            statusSeen := 1;
        end
        # a bit that clears ends its ignore, so a later failure is raised
        if (getbit(x, 0) = 0, ignGear := 0);
        if (getbit(x, 1) = 0, ignLamp := 0);
        gearStatus := x;
        checkStatus := 60;
        statusPoll := 60;
    else
        if x = 0x8000
            Status := RANDINT(10, 60);
            adderror(3, "Gear not responding!");
            return(0);
        end
    end
end

# messages last one run only, so they are raised from the stored status on every run
if ((getbit(gearStatus, 0) = 1) and (ignGear = 0), adderror(1, "Control gear failure!"));
if ((getbit(gearStatus, 1) = 1) and (ignLamp = 0), adderror(2, "Lamp failure!"));
Inizializzazione
var x := 0; var rx := 0;
# QUERY STATUS 0x90: every reply byte proves the gear is present; 0x8000 = no answer, 0x20FF = bus collision
# an unread answer left in the gateway would be taken for this query: read it away and count it
x := modbusr(SH, 511, uint16); if (x != 0x8000, cntStale := cntStale + 1);
modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x90);
sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
x := modbusr(SH, 511, uint16);
cntQ := cntQ + 1; if (x = 0x8000, cntNone := cntNone + 1); if (x = 0x20FF, cntColl := cntColl + 1);
statusSeen := 0;
if x <= 0xFF
    # failure bits a gear reports from its first answer are its permanent state, not an event: shown, not raised
    gearStatus := x;
    ignGear := getbit(x, 0);
    ignLamp := getbit(x, 1);
    statusSeen := 1;
    Status := 0;
else
    Status := RANDINT(1, 60);
end

if Status = 0
    x := modbusr(SH, 511, uint16); if (x != 0x8000, cntStale := cntStale + 1);
    modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA2);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    x := modbusr(SH, 511, uint16);
    cntQ := cntQ + 1; if (x = 0x8000, cntNone := cntNone + 1); if (x = 0x20FF, cntColl := cntColl + 1);
    if (x <= 0xFE, minLevel := x);

    x := modbusr(SH, 511, uint16); if (x != 0x8000, cntStale := cntStale + 1);
    modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA1);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    x := modbusr(SH, 511, uint16);
    cntQ := cntQ + 1; if (x = 0x8000, cntNone := cntNone + 1); if (x = 0x20FF, cntColl := cntColl + 1);
    if (x <= 0xFE, maxLevel := x);
end
Lettura livello
var x := 0; var rx := 0; var y := 0;
if Status = 0
    if minLevel = 0
        # an unread answer left in the gateway would be taken for this query: read it away and count it
        x := modbusr(SH, 511, uint16); if (x != 0x8000, cntStale := cntStale + 1);
        modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA2);
        sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
        x := modbusr(SH, 511, uint16);
        cntQ := cntQ + 1; if (x = 0x8000, cntNone := cntNone + 1); if (x = 0x20FF, cntColl := cntColl + 1);
        if (x <= 0xFE, minLevel := x);
    end
    x := modbusr(SH, 511, uint16); if (x != 0x8000, cntStale := cntStale + 1);
    modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA0);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    x := modbusr(SH, 511, uint16);
    cntQ := cntQ + 1; if (x = 0x8000, cntNone := cntNone + 1); if (x = 0x20FF, cntColl := cntColl + 1);
    if (x != 0x8000 or rx, checkStatus := 60);
    # 0xFF = MASK, 0x20FF = collision, 0x8000 = no answer: keep the last level instead of a phantom value
    if x > 0xFE
        return(Le);
    end
    # an actual level is 0 or between the gear's min and max: anything else is not this gear's answer
    if x > 0 and x < minLevel
        cntBad := cntBad + 1;
        return(Le);
    end
    # a changed level must be read twice the same before it is taken
    if x != lastRaw
        y := modbusr(SH, 511, uint16); if (y != 0x8000, cntStale := cntStale + 1);
        modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA0);
        sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
        y := modbusr(SH, 511, uint16);
        cntQ := cntQ + 1; if (y = 0x8000, cntNone := cntNone + 1); if (y = 0x20FF, cntColl := cntColl + 1);
        if y != x
            cntBad := cntBad + 1;
            return(Le);
        end
        lastRaw := x;
    end
    return(if(x = 0, 0, linear(x, minLevel, 0.01, maxLevel, 1)));
else
    return(NaN);
end
Scrittura livello
var level := 0;
if(Le > 0, level := round(linear(Le, 0.01, minLevel, 1, maxLevel)));
modbusw(SH, 510, uint16, (ShortAddress << 8) + level );
Attributi di servizio
${xml_short_address}
ShortAddress
${xml_device_type}
var x := 0; var y := 0; var rx := 0; var s := ""; var i := 0;
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x99);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    x := modbusr(SH, 511, uint16);
    if (x < 0xFF, return("DT" + x));
    if x = 0xFF
        while i < 8
            modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA7);
            sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
            y := modbusr(SH, 511, uint16);
            if y < 0xFE
                s := if(s = "", "DT" + y, s + ", DT" + y);
                i := i + 1;
            else
                i := 8;
            end
        loop
        return(if(s = "", "MASK", s));
    end
end

return("--")
Physical Min Level
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x9A);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if (x <= 0xFE, return(round((x / 0xFE) * 100) + " %"));
end

return("--")
Max Level
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA1);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if (x <= 0xFE, return(round((x / 0xFE) * 100) + " %"));
end

return("--")
Min Level
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA2);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if (x <= 0xFE, return(round((x / 0xFE) * 100) + " %"));
end

return("--")
Power Up Level
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA3);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if (x <= 0xFE, return(round((x / 0xFE) * 100) + " %"));
end

return("--")
System Failure Level
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA4);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if (x <= 0xFE, return(round((x / 0xFE) * 100) + " %"));
end

return("--")
${xml_groups}
var x := 0; var rx := 0;
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xC0);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var g1 := modbusr(SH, 511, uint16);
    if (g1 > 0xFF, return("--")); 

    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xC1);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var g2 := modbusr(SH, 511, uint16);
    if (g2 > 0xFF, return("--")); 

    var ret := "";

    if (getbit(g1, 0), ret := ret + "0");
    if (getbit(g1, 1), if (ret = "", ret := "1", ret := ret + ",1"));
    if (getbit(g1, 2), if (ret = "", ret := "2", ret := ret + ",2"));
    if (getbit(g1, 3), if (ret = "", ret := "3", ret := ret + ",3"));
    if (getbit(g1, 4), if (ret = "", ret := "4", ret := ret + ",4"));
    if (getbit(g1, 5), if (ret = "", ret := "5", ret := ret + ",5"));
    if (getbit(g1, 6), if (ret = "", ret := "6", ret := ret + ",6"));
    if (getbit(g1, 7), if (ret = "", ret := "7", ret := ret + ",7"));
    if (getbit(g2, 0), if (ret = "", ret := "8", ret := ret + ",8"));
    if (getbit(g2, 1), if (ret = "", ret := "9", ret := ret + ",9"));
    if (getbit(g2, 2), if (ret = "", ret := "10", ret := ret + ",10"));
    if (getbit(g2, 3), if (ret = "", ret := "11", ret := ret + ",11"));
    if (getbit(g2, 4), if (ret = "", ret := "12", ret := ret + ",12"));
    if (getbit(g2, 5), if (ret = "", ret := "13", ret := ret + ",13"));
    if (getbit(g2, 6), if (ret = "", ret := "14", ret := ret + ",14"));
    if (getbit(g2, 7), if (ret = "", ret := "15", ret := ret + ",15"));

    if (ret = "", return("None"), return(ret));
else
    return("--");
end
DALI Status
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x90);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if x <= 0xFF
        var s := "";
        if (getbit(x, 0), s := if(s = "", "gear failure", s + ", gear failure"));
        if (getbit(x, 1), s := if(s = "", "lamp failure", s + ", lamp failure"));
        if (getbit(x, 2), s := if(s = "", "lamp on", s + ", lamp on"));
        if (getbit(x, 3), s := if(s = "", "limit error", s + ", limit error"));
        if (getbit(x, 4), s := if(s = "", "fade running", s + ", fade running"));
        if (getbit(x, 5), s := if(s = "", "reset state", s + ", reset state"));
        if (getbit(x, 6), s := if(s = "", "missing short address", s + ", missing short address"));
        if (getbit(x, 7), s := if(s = "", "power cycle", s + ", power cycle"));
        var ign := if((ignGear = 1) and (ignLamp = 1), "gear and lamp failure", if(ignGear = 1, "gear failure", if(ignLamp = 1, "lamp failure", "")));
        return(if(s = "", "OK", s) + " (0x" + tostring(x, "X2") + ")" + if(ign = "", "", "; not raised: " + ign + " reported since start"));
    end
end

return("--")
Fade
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA5);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if x <= 0xFF
        var t := getbits(x, 4, 4);
        var ret := if(t = 0, "off", t + " (" + round(sqrt(power(2, t)) * 5) / 10 + " s)");
        modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA8);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
        var e := modbusr(SH, 511, uint16);
        if (t = 0 and e <= 0xFF and e != 0, ret := "extended 0x" + tostring(e, "X2"));
        return("fade time " + ret + ", fade rate " + getbits(x, 0, 4));
    end
end

return("--")
DALI Version
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x97);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if x <= 0xFF
        return(if(x >= 8, "DALI-2 " + getbits(x, 2, 6) + "." + getbits(x, 0, 2), "DALI-1") + " (" + x + ")");
    end
end

return("--")
Bus statistics
return("since start: queries " + cntQ + ", stale answers read away " + cntStale + ", no answer " + cntNone + ", collisions " + cntColl + ", rejected levels " + cntBad)
Azioni di servizio
${xml_add_to_group}
Parametri: Group ID (0–15 grp)
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x60 + grp);
${xml_remove_from_group}
Parametri: Group ID (0–15 grp)
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x70 + grp);
${xml_reset_to_default_settings}
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x20);
${xml_set_startup_levels}
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x21);
sleep(10);
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x2c);
sleep(10);
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x2d);
Disable fading
modbusw(SH, 541, uint16, 0xA300);
sleep(100);
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x2E);
sleep(100);
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x30);
Gear 56 Dimmer Lettura e scrittura

Dispositivo di controllo DALI all'indirizzo breve 56 — dimmer TapHome mappato su DALI arc power 0–100 % tramite H:510 LAMP LEVEL (scrittura) e QUERY ACTUAL LEVEL tramite H:511 (lettura), delimitato dai propri MIN / MAX LEVEL del gear.

Registro: H:511 → H:510 UInt16 Unità: % numeric
Attributi di servizio
Indirizzo breveIndirizzo breve DALI (0–63) target di questo dispositivo — fissato al momento dell'importazione del template e utilizzato nel byte alto di ogni scrittura Modbus.
Device TypeByte device-type DALI restituito da QUERY DEVICE TYPE (0x99) — riporta DT0 (fluorescente), DT6 (driver LED), DT8 (colore / tunable white) ecc., o -- quando non c'è risposta.
Physical Min LevelLivello minimo di dimmerazione imposto dall'hardware riportato dal gear — letto da QUERY PHYSICAL MIN LEVEL (0x9A), in percentuale.
Max LevelDALI MAX LEVEL configurato — letto da QUERY MAX LEVEL (0xA1); utilizzato come limite superiore durante la scalatura di TapHome 0–100 % su DALI arc power.
Min LevelDALI MIN LEVEL configurato — letto da QUERY MIN LEVEL (0xA2); utilizzato come limite inferiore durante la scalatura di TapHome 0–100 % su DALI arc power.
Power Up LevelLuminosità ripristinata dopo il ripristino dell'alimentazione del bus DALI — letta da QUERY POWER ON LEVEL (0xA3).
System Failure LevelLuminosità adottata quando il bus DALI perde la comunicazione per più di 500 ms — letta da QUERY SYSTEM FAILURE LEVEL (0xA4).
GruppiElenco separato da virgole dei gruppi DALI (0–15) a cui appartiene il gear — decodificato da QUERY GROUPS 0-7 (0xC0) e QUERY GROUPS 8-15 (0xC1); mostra None o ad es. 0,3,7.
Support Lamp FailureSe la lampada / driver supporta il rilevamento dei guasti della lampada — Yes / No / --. Gestisce l'errore Lamp failure! nel readscript periodico.
Support Power FailureSe la lampada / driver supporta il rilevamento dei guasti di alimentazione — Yes / No / --. Gestisce l'errore Power failure! nel readscript periodico.
DALI Version
Bus statistics
Azioni di servizio
Add to GroupAggiunge questo gear a un gruppo DALI (0–15) tramite ADD TO GROUP (0x60+grp) — auto-ripetuto entro 100 ms come richiesto per i comandi di configurazione DALI.
Remove from GroupRimuove questo gear da un gruppo DALI (0–15) tramite REMOVE FROM GROUP (0x70+grp).
Reset to Default SettingsInvia DALI RESET (0x20) — ripristina ogni parametro NVM del gear (livelli max / min / power-on / system-failure, appartenenza al gruppo, scene) al valore predefinito del produttore.
Set Startup LevelsCattura l'arc power corrente e la memorizza come Power On Level e System Failure Level — sequenza STORE ACTUAL LEVEL IN DTR (0x21) → STORE DTR AS POWER ON LEVEL (0x2C) → STORE DTR AS SYSTEM FAILURE LEVEL (0x2D).
Disable fading

Gear 56

Lettura (modulo)
var x := 0; var rx := 0; var y := 0;
if Status > 0
    Status := Status - 1;
    adderror(3, "Gear not responding!");
    return(0);
end

# checkStatus: ReadLevel resets it while the gear answers; statusPoll: QUERY STATUS at least once per 60 runs
checkStatus := checkStatus - 1;
statusPoll := statusPoll - 1;
if checkStatus < 1 or statusPoll < 1
    # an unread answer left in the gateway would be taken for this query: read it away and count it
    x := modbusr(SH, 511, uint16); if (x != 0x8000, cntStale := cntStale + 1);
    modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x90);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    x := modbusr(SH, 511, uint16);
    cntQ := cntQ + 1; if (x = 0x8000, cntNone := cntNone + 1); if (x = 0x20FF, cntColl := cntColl + 1);
    # a single lost answer happens on DALI: ask once more before declaring the gear missing
    if x = 0x8000
        x := modbusr(SH, 511, uint16); if (x != 0x8000, cntStale := cntStale + 1);
        modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x90);
        sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
        x := modbusr(SH, 511, uint16);
        cntQ := cntQ + 1; if (x = 0x8000, cntNone := cntNone + 1); if (x = 0x20FF, cntColl := cntColl + 1);
    end
    if x <= 0xFF
        # a changed failure bit must be read twice the same before it is taken
        if statusSeen = 1 and getbits(x, 0, 2) != getbits(gearStatus, 0, 2)
            y := modbusr(SH, 511, uint16); if (y != 0x8000, cntStale := cntStale + 1);
            modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x90);
            sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
            y := modbusr(SH, 511, uint16);
            cntQ := cntQ + 1; if (y = 0x8000, cntNone := cntNone + 1); if (y = 0x20FF, cntColl := cntColl + 1);
            if y != x
                cntBad := cntBad + 1;
                x := gearStatus;
            end
        end
        if statusSeen = 0
            ignGear := getbit(x, 0);
            ignLamp := getbit(x, 1);
            statusSeen := 1;
        end
        # a bit that clears ends its ignore, so a later failure is raised
        if (getbit(x, 0) = 0, ignGear := 0);
        if (getbit(x, 1) = 0, ignLamp := 0);
        gearStatus := x;
        checkStatus := 60;
        statusPoll := 60;
    else
        if x = 0x8000
            Status := RANDINT(10, 60);
            adderror(3, "Gear not responding!");
            return(0);
        end
    end
end

# messages last one run only, so they are raised from the stored status on every run
if ((getbit(gearStatus, 0) = 1) and (ignGear = 0), adderror(1, "Control gear failure!"));
if ((getbit(gearStatus, 1) = 1) and (ignLamp = 0), adderror(2, "Lamp failure!"));
Inizializzazione
var x := 0; var rx := 0;
# QUERY STATUS 0x90: every reply byte proves the gear is present; 0x8000 = no answer, 0x20FF = bus collision
# an unread answer left in the gateway would be taken for this query: read it away and count it
x := modbusr(SH, 511, uint16); if (x != 0x8000, cntStale := cntStale + 1);
modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x90);
sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
x := modbusr(SH, 511, uint16);
cntQ := cntQ + 1; if (x = 0x8000, cntNone := cntNone + 1); if (x = 0x20FF, cntColl := cntColl + 1);
statusSeen := 0;
if x <= 0xFF
    # failure bits a gear reports from its first answer are its permanent state, not an event: shown, not raised
    gearStatus := x;
    ignGear := getbit(x, 0);
    ignLamp := getbit(x, 1);
    statusSeen := 1;
    Status := 0;
else
    Status := RANDINT(1, 60);
end

if Status = 0
    x := modbusr(SH, 511, uint16); if (x != 0x8000, cntStale := cntStale + 1);
    modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA2);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    x := modbusr(SH, 511, uint16);
    cntQ := cntQ + 1; if (x = 0x8000, cntNone := cntNone + 1); if (x = 0x20FF, cntColl := cntColl + 1);
    if (x <= 0xFE, minLevel := x);

    x := modbusr(SH, 511, uint16); if (x != 0x8000, cntStale := cntStale + 1);
    modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA1);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    x := modbusr(SH, 511, uint16);
    cntQ := cntQ + 1; if (x = 0x8000, cntNone := cntNone + 1); if (x = 0x20FF, cntColl := cntColl + 1);
    if (x <= 0xFE, maxLevel := x);
end
Lettura livello
var x := 0; var rx := 0; var y := 0;
if Status = 0
    if minLevel = 0
        # an unread answer left in the gateway would be taken for this query: read it away and count it
        x := modbusr(SH, 511, uint16); if (x != 0x8000, cntStale := cntStale + 1);
        modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA2);
        sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
        x := modbusr(SH, 511, uint16);
        cntQ := cntQ + 1; if (x = 0x8000, cntNone := cntNone + 1); if (x = 0x20FF, cntColl := cntColl + 1);
        if (x <= 0xFE, minLevel := x);
    end
    x := modbusr(SH, 511, uint16); if (x != 0x8000, cntStale := cntStale + 1);
    modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA0);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    x := modbusr(SH, 511, uint16);
    cntQ := cntQ + 1; if (x = 0x8000, cntNone := cntNone + 1); if (x = 0x20FF, cntColl := cntColl + 1);
    if (x != 0x8000 or rx, checkStatus := 60);
    # 0xFF = MASK, 0x20FF = collision, 0x8000 = no answer: keep the last level instead of a phantom value
    if x > 0xFE
        return(Le);
    end
    # an actual level is 0 or between the gear's min and max: anything else is not this gear's answer
    if x > 0 and x < minLevel
        cntBad := cntBad + 1;
        return(Le);
    end
    # a changed level must be read twice the same before it is taken
    if x != lastRaw
        y := modbusr(SH, 511, uint16); if (y != 0x8000, cntStale := cntStale + 1);
        modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA0);
        sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
        y := modbusr(SH, 511, uint16);
        cntQ := cntQ + 1; if (y = 0x8000, cntNone := cntNone + 1); if (y = 0x20FF, cntColl := cntColl + 1);
        if y != x
            cntBad := cntBad + 1;
            return(Le);
        end
        lastRaw := x;
    end
    return(if(x = 0, 0, linear(x, minLevel, 0.01, maxLevel, 1)));
else
    return(NaN);
end
Scrittura livello
var level := 0;
if(Le > 0, level := round(linear(Le, 0.01, minLevel, 1, maxLevel)));
modbusw(SH, 510, uint16, (ShortAddress << 8) + level );
Attributi di servizio
${xml_short_address}
ShortAddress
${xml_device_type}
var x := 0; var y := 0; var rx := 0; var s := ""; var i := 0;
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x99);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    x := modbusr(SH, 511, uint16);
    if (x < 0xFF, return("DT" + x));
    if x = 0xFF
        while i < 8
            modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA7);
            sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
            y := modbusr(SH, 511, uint16);
            if y < 0xFE
                s := if(s = "", "DT" + y, s + ", DT" + y);
                i := i + 1;
            else
                i := 8;
            end
        loop
        return(if(s = "", "MASK", s));
    end
end

return("--")
Physical Min Level
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x9A);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if (x <= 0xFE, return(round((x / 0xFE) * 100) + " %"));
end

return("--")
Max Level
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA1);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if (x <= 0xFE, return(round((x / 0xFE) * 100) + " %"));
end

return("--")
Min Level
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA2);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if (x <= 0xFE, return(round((x / 0xFE) * 100) + " %"));
end

return("--")
Power Up Level
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA3);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if (x <= 0xFE, return(round((x / 0xFE) * 100) + " %"));
end

return("--")
System Failure Level
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA4);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if (x <= 0xFE, return(round((x / 0xFE) * 100) + " %"));
end

return("--")
${xml_groups}
var x := 0; var rx := 0;
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xC0);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var g1 := modbusr(SH, 511, uint16);
    if (g1 > 0xFF, return("--")); 

    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xC1);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var g2 := modbusr(SH, 511, uint16);
    if (g2 > 0xFF, return("--")); 

    var ret := "";

    if (getbit(g1, 0), ret := ret + "0");
    if (getbit(g1, 1), if (ret = "", ret := "1", ret := ret + ",1"));
    if (getbit(g1, 2), if (ret = "", ret := "2", ret := ret + ",2"));
    if (getbit(g1, 3), if (ret = "", ret := "3", ret := ret + ",3"));
    if (getbit(g1, 4), if (ret = "", ret := "4", ret := ret + ",4"));
    if (getbit(g1, 5), if (ret = "", ret := "5", ret := ret + ",5"));
    if (getbit(g1, 6), if (ret = "", ret := "6", ret := ret + ",6"));
    if (getbit(g1, 7), if (ret = "", ret := "7", ret := ret + ",7"));
    if (getbit(g2, 0), if (ret = "", ret := "8", ret := ret + ",8"));
    if (getbit(g2, 1), if (ret = "", ret := "9", ret := ret + ",9"));
    if (getbit(g2, 2), if (ret = "", ret := "10", ret := ret + ",10"));
    if (getbit(g2, 3), if (ret = "", ret := "11", ret := ret + ",11"));
    if (getbit(g2, 4), if (ret = "", ret := "12", ret := ret + ",12"));
    if (getbit(g2, 5), if (ret = "", ret := "13", ret := ret + ",13"));
    if (getbit(g2, 6), if (ret = "", ret := "14", ret := ret + ",14"));
    if (getbit(g2, 7), if (ret = "", ret := "15", ret := ret + ",15"));

    if (ret = "", return("None"), return(ret));
else
    return("--");
end
DALI Status
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x90);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if x <= 0xFF
        var s := "";
        if (getbit(x, 0), s := if(s = "", "gear failure", s + ", gear failure"));
        if (getbit(x, 1), s := if(s = "", "lamp failure", s + ", lamp failure"));
        if (getbit(x, 2), s := if(s = "", "lamp on", s + ", lamp on"));
        if (getbit(x, 3), s := if(s = "", "limit error", s + ", limit error"));
        if (getbit(x, 4), s := if(s = "", "fade running", s + ", fade running"));
        if (getbit(x, 5), s := if(s = "", "reset state", s + ", reset state"));
        if (getbit(x, 6), s := if(s = "", "missing short address", s + ", missing short address"));
        if (getbit(x, 7), s := if(s = "", "power cycle", s + ", power cycle"));
        var ign := if((ignGear = 1) and (ignLamp = 1), "gear and lamp failure", if(ignGear = 1, "gear failure", if(ignLamp = 1, "lamp failure", "")));
        return(if(s = "", "OK", s) + " (0x" + tostring(x, "X2") + ")" + if(ign = "", "", "; not raised: " + ign + " reported since start"));
    end
end

return("--")
Fade
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA5);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if x <= 0xFF
        var t := getbits(x, 4, 4);
        var ret := if(t = 0, "off", t + " (" + round(sqrt(power(2, t)) * 5) / 10 + " s)");
        modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA8);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
        var e := modbusr(SH, 511, uint16);
        if (t = 0 and e <= 0xFF and e != 0, ret := "extended 0x" + tostring(e, "X2"));
        return("fade time " + ret + ", fade rate " + getbits(x, 0, 4));
    end
end

return("--")
DALI Version
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x97);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if x <= 0xFF
        return(if(x >= 8, "DALI-2 " + getbits(x, 2, 6) + "." + getbits(x, 0, 2), "DALI-1") + " (" + x + ")");
    end
end

return("--")
Bus statistics
return("since start: queries " + cntQ + ", stale answers read away " + cntStale + ", no answer " + cntNone + ", collisions " + cntColl + ", rejected levels " + cntBad)
Azioni di servizio
${xml_add_to_group}
Parametri: Group ID (0–15 grp)
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x60 + grp);
${xml_remove_from_group}
Parametri: Group ID (0–15 grp)
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x70 + grp);
${xml_reset_to_default_settings}
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x20);
${xml_set_startup_levels}
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x21);
sleep(10);
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x2c);
sleep(10);
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x2d);
Disable fading
modbusw(SH, 541, uint16, 0xA300);
sleep(100);
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x2E);
sleep(100);
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x30);
Gear 57 Dimmer Lettura e scrittura

Dispositivo di controllo DALI all'indirizzo breve 57 — dimmer TapHome mappato su DALI arc power 0–100 % tramite H:510 LAMP LEVEL (scrittura) e QUERY ACTUAL LEVEL tramite H:511 (lettura), delimitato dai propri MIN / MAX LEVEL del gear.

Registro: H:511 → H:510 UInt16 Unità: % numeric
Attributi di servizio
Indirizzo breveIndirizzo breve DALI (0–63) target di questo dispositivo — fissato al momento dell'importazione del template e utilizzato nel byte alto di ogni scrittura Modbus.
Device TypeByte device-type DALI restituito da QUERY DEVICE TYPE (0x99) — riporta DT0 (fluorescente), DT6 (driver LED), DT8 (colore / tunable white) ecc., o -- quando non c'è risposta.
Physical Min LevelLivello minimo di dimmerazione imposto dall'hardware riportato dal gear — letto da QUERY PHYSICAL MIN LEVEL (0x9A), in percentuale.
Max LevelDALI MAX LEVEL configurato — letto da QUERY MAX LEVEL (0xA1); utilizzato come limite superiore durante la scalatura di TapHome 0–100 % su DALI arc power.
Min LevelDALI MIN LEVEL configurato — letto da QUERY MIN LEVEL (0xA2); utilizzato come limite inferiore durante la scalatura di TapHome 0–100 % su DALI arc power.
Power Up LevelLuminosità ripristinata dopo il ripristino dell'alimentazione del bus DALI — letta da QUERY POWER ON LEVEL (0xA3).
System Failure LevelLuminosità adottata quando il bus DALI perde la comunicazione per più di 500 ms — letta da QUERY SYSTEM FAILURE LEVEL (0xA4).
GruppiElenco separato da virgole dei gruppi DALI (0–15) a cui appartiene il gear — decodificato da QUERY GROUPS 0-7 (0xC0) e QUERY GROUPS 8-15 (0xC1); mostra None o ad es. 0,3,7.
Support Lamp FailureSe la lampada / driver supporta il rilevamento dei guasti della lampada — Yes / No / --. Gestisce l'errore Lamp failure! nel readscript periodico.
Support Power FailureSe la lampada / driver supporta il rilevamento dei guasti di alimentazione — Yes / No / --. Gestisce l'errore Power failure! nel readscript periodico.
DALI Version
Bus statistics
Azioni di servizio
Add to GroupAggiunge questo gear a un gruppo DALI (0–15) tramite ADD TO GROUP (0x60+grp) — auto-ripetuto entro 100 ms come richiesto per i comandi di configurazione DALI.
Remove from GroupRimuove questo gear da un gruppo DALI (0–15) tramite REMOVE FROM GROUP (0x70+grp).
Reset to Default SettingsInvia DALI RESET (0x20) — ripristina ogni parametro NVM del gear (livelli max / min / power-on / system-failure, appartenenza al gruppo, scene) al valore predefinito del produttore.
Set Startup LevelsCattura l'arc power corrente e la memorizza come Power On Level e System Failure Level — sequenza STORE ACTUAL LEVEL IN DTR (0x21) → STORE DTR AS POWER ON LEVEL (0x2C) → STORE DTR AS SYSTEM FAILURE LEVEL (0x2D).
Disable fading

Gear 57

Lettura (modulo)
var x := 0; var rx := 0; var y := 0;
if Status > 0
    Status := Status - 1;
    adderror(3, "Gear not responding!");
    return(0);
end

# checkStatus: ReadLevel resets it while the gear answers; statusPoll: QUERY STATUS at least once per 60 runs
checkStatus := checkStatus - 1;
statusPoll := statusPoll - 1;
if checkStatus < 1 or statusPoll < 1
    # an unread answer left in the gateway would be taken for this query: read it away and count it
    x := modbusr(SH, 511, uint16); if (x != 0x8000, cntStale := cntStale + 1);
    modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x90);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    x := modbusr(SH, 511, uint16);
    cntQ := cntQ + 1; if (x = 0x8000, cntNone := cntNone + 1); if (x = 0x20FF, cntColl := cntColl + 1);
    # a single lost answer happens on DALI: ask once more before declaring the gear missing
    if x = 0x8000
        x := modbusr(SH, 511, uint16); if (x != 0x8000, cntStale := cntStale + 1);
        modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x90);
        sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
        x := modbusr(SH, 511, uint16);
        cntQ := cntQ + 1; if (x = 0x8000, cntNone := cntNone + 1); if (x = 0x20FF, cntColl := cntColl + 1);
    end
    if x <= 0xFF
        # a changed failure bit must be read twice the same before it is taken
        if statusSeen = 1 and getbits(x, 0, 2) != getbits(gearStatus, 0, 2)
            y := modbusr(SH, 511, uint16); if (y != 0x8000, cntStale := cntStale + 1);
            modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x90);
            sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
            y := modbusr(SH, 511, uint16);
            cntQ := cntQ + 1; if (y = 0x8000, cntNone := cntNone + 1); if (y = 0x20FF, cntColl := cntColl + 1);
            if y != x
                cntBad := cntBad + 1;
                x := gearStatus;
            end
        end
        if statusSeen = 0
            ignGear := getbit(x, 0);
            ignLamp := getbit(x, 1);
            statusSeen := 1;
        end
        # a bit that clears ends its ignore, so a later failure is raised
        if (getbit(x, 0) = 0, ignGear := 0);
        if (getbit(x, 1) = 0, ignLamp := 0);
        gearStatus := x;
        checkStatus := 60;
        statusPoll := 60;
    else
        if x = 0x8000
            Status := RANDINT(10, 60);
            adderror(3, "Gear not responding!");
            return(0);
        end
    end
end

# messages last one run only, so they are raised from the stored status on every run
if ((getbit(gearStatus, 0) = 1) and (ignGear = 0), adderror(1, "Control gear failure!"));
if ((getbit(gearStatus, 1) = 1) and (ignLamp = 0), adderror(2, "Lamp failure!"));
Inizializzazione
var x := 0; var rx := 0;
# QUERY STATUS 0x90: every reply byte proves the gear is present; 0x8000 = no answer, 0x20FF = bus collision
# an unread answer left in the gateway would be taken for this query: read it away and count it
x := modbusr(SH, 511, uint16); if (x != 0x8000, cntStale := cntStale + 1);
modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x90);
sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
x := modbusr(SH, 511, uint16);
cntQ := cntQ + 1; if (x = 0x8000, cntNone := cntNone + 1); if (x = 0x20FF, cntColl := cntColl + 1);
statusSeen := 0;
if x <= 0xFF
    # failure bits a gear reports from its first answer are its permanent state, not an event: shown, not raised
    gearStatus := x;
    ignGear := getbit(x, 0);
    ignLamp := getbit(x, 1);
    statusSeen := 1;
    Status := 0;
else
    Status := RANDINT(1, 60);
end

if Status = 0
    x := modbusr(SH, 511, uint16); if (x != 0x8000, cntStale := cntStale + 1);
    modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA2);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    x := modbusr(SH, 511, uint16);
    cntQ := cntQ + 1; if (x = 0x8000, cntNone := cntNone + 1); if (x = 0x20FF, cntColl := cntColl + 1);
    if (x <= 0xFE, minLevel := x);

    x := modbusr(SH, 511, uint16); if (x != 0x8000, cntStale := cntStale + 1);
    modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA1);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    x := modbusr(SH, 511, uint16);
    cntQ := cntQ + 1; if (x = 0x8000, cntNone := cntNone + 1); if (x = 0x20FF, cntColl := cntColl + 1);
    if (x <= 0xFE, maxLevel := x);
end
Lettura livello
var x := 0; var rx := 0; var y := 0;
if Status = 0
    if minLevel = 0
        # an unread answer left in the gateway would be taken for this query: read it away and count it
        x := modbusr(SH, 511, uint16); if (x != 0x8000, cntStale := cntStale + 1);
        modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA2);
        sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
        x := modbusr(SH, 511, uint16);
        cntQ := cntQ + 1; if (x = 0x8000, cntNone := cntNone + 1); if (x = 0x20FF, cntColl := cntColl + 1);
        if (x <= 0xFE, minLevel := x);
    end
    x := modbusr(SH, 511, uint16); if (x != 0x8000, cntStale := cntStale + 1);
    modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA0);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    x := modbusr(SH, 511, uint16);
    cntQ := cntQ + 1; if (x = 0x8000, cntNone := cntNone + 1); if (x = 0x20FF, cntColl := cntColl + 1);
    if (x != 0x8000 or rx, checkStatus := 60);
    # 0xFF = MASK, 0x20FF = collision, 0x8000 = no answer: keep the last level instead of a phantom value
    if x > 0xFE
        return(Le);
    end
    # an actual level is 0 or between the gear's min and max: anything else is not this gear's answer
    if x > 0 and x < minLevel
        cntBad := cntBad + 1;
        return(Le);
    end
    # a changed level must be read twice the same before it is taken
    if x != lastRaw
        y := modbusr(SH, 511, uint16); if (y != 0x8000, cntStale := cntStale + 1);
        modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA0);
        sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
        y := modbusr(SH, 511, uint16);
        cntQ := cntQ + 1; if (y = 0x8000, cntNone := cntNone + 1); if (y = 0x20FF, cntColl := cntColl + 1);
        if y != x
            cntBad := cntBad + 1;
            return(Le);
        end
        lastRaw := x;
    end
    return(if(x = 0, 0, linear(x, minLevel, 0.01, maxLevel, 1)));
else
    return(NaN);
end
Scrittura livello
var level := 0;
if(Le > 0, level := round(linear(Le, 0.01, minLevel, 1, maxLevel)));
modbusw(SH, 510, uint16, (ShortAddress << 8) + level );
Attributi di servizio
${xml_short_address}
ShortAddress
${xml_device_type}
var x := 0; var y := 0; var rx := 0; var s := ""; var i := 0;
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x99);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    x := modbusr(SH, 511, uint16);
    if (x < 0xFF, return("DT" + x));
    if x = 0xFF
        while i < 8
            modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA7);
            sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
            y := modbusr(SH, 511, uint16);
            if y < 0xFE
                s := if(s = "", "DT" + y, s + ", DT" + y);
                i := i + 1;
            else
                i := 8;
            end
        loop
        return(if(s = "", "MASK", s));
    end
end

return("--")
Physical Min Level
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x9A);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if (x <= 0xFE, return(round((x / 0xFE) * 100) + " %"));
end

return("--")
Max Level
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA1);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if (x <= 0xFE, return(round((x / 0xFE) * 100) + " %"));
end

return("--")
Min Level
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA2);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if (x <= 0xFE, return(round((x / 0xFE) * 100) + " %"));
end

return("--")
Power Up Level
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA3);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if (x <= 0xFE, return(round((x / 0xFE) * 100) + " %"));
end

return("--")
System Failure Level
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA4);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if (x <= 0xFE, return(round((x / 0xFE) * 100) + " %"));
end

return("--")
${xml_groups}
var x := 0; var rx := 0;
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xC0);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var g1 := modbusr(SH, 511, uint16);
    if (g1 > 0xFF, return("--")); 

    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xC1);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var g2 := modbusr(SH, 511, uint16);
    if (g2 > 0xFF, return("--")); 

    var ret := "";

    if (getbit(g1, 0), ret := ret + "0");
    if (getbit(g1, 1), if (ret = "", ret := "1", ret := ret + ",1"));
    if (getbit(g1, 2), if (ret = "", ret := "2", ret := ret + ",2"));
    if (getbit(g1, 3), if (ret = "", ret := "3", ret := ret + ",3"));
    if (getbit(g1, 4), if (ret = "", ret := "4", ret := ret + ",4"));
    if (getbit(g1, 5), if (ret = "", ret := "5", ret := ret + ",5"));
    if (getbit(g1, 6), if (ret = "", ret := "6", ret := ret + ",6"));
    if (getbit(g1, 7), if (ret = "", ret := "7", ret := ret + ",7"));
    if (getbit(g2, 0), if (ret = "", ret := "8", ret := ret + ",8"));
    if (getbit(g2, 1), if (ret = "", ret := "9", ret := ret + ",9"));
    if (getbit(g2, 2), if (ret = "", ret := "10", ret := ret + ",10"));
    if (getbit(g2, 3), if (ret = "", ret := "11", ret := ret + ",11"));
    if (getbit(g2, 4), if (ret = "", ret := "12", ret := ret + ",12"));
    if (getbit(g2, 5), if (ret = "", ret := "13", ret := ret + ",13"));
    if (getbit(g2, 6), if (ret = "", ret := "14", ret := ret + ",14"));
    if (getbit(g2, 7), if (ret = "", ret := "15", ret := ret + ",15"));

    if (ret = "", return("None"), return(ret));
else
    return("--");
end
DALI Status
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x90);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if x <= 0xFF
        var s := "";
        if (getbit(x, 0), s := if(s = "", "gear failure", s + ", gear failure"));
        if (getbit(x, 1), s := if(s = "", "lamp failure", s + ", lamp failure"));
        if (getbit(x, 2), s := if(s = "", "lamp on", s + ", lamp on"));
        if (getbit(x, 3), s := if(s = "", "limit error", s + ", limit error"));
        if (getbit(x, 4), s := if(s = "", "fade running", s + ", fade running"));
        if (getbit(x, 5), s := if(s = "", "reset state", s + ", reset state"));
        if (getbit(x, 6), s := if(s = "", "missing short address", s + ", missing short address"));
        if (getbit(x, 7), s := if(s = "", "power cycle", s + ", power cycle"));
        var ign := if((ignGear = 1) and (ignLamp = 1), "gear and lamp failure", if(ignGear = 1, "gear failure", if(ignLamp = 1, "lamp failure", "")));
        return(if(s = "", "OK", s) + " (0x" + tostring(x, "X2") + ")" + if(ign = "", "", "; not raised: " + ign + " reported since start"));
    end
end

return("--")
Fade
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA5);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if x <= 0xFF
        var t := getbits(x, 4, 4);
        var ret := if(t = 0, "off", t + " (" + round(sqrt(power(2, t)) * 5) / 10 + " s)");
        modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA8);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
        var e := modbusr(SH, 511, uint16);
        if (t = 0 and e <= 0xFF and e != 0, ret := "extended 0x" + tostring(e, "X2"));
        return("fade time " + ret + ", fade rate " + getbits(x, 0, 4));
    end
end

return("--")
DALI Version
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x97);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if x <= 0xFF
        return(if(x >= 8, "DALI-2 " + getbits(x, 2, 6) + "." + getbits(x, 0, 2), "DALI-1") + " (" + x + ")");
    end
end

return("--")
Bus statistics
return("since start: queries " + cntQ + ", stale answers read away " + cntStale + ", no answer " + cntNone + ", collisions " + cntColl + ", rejected levels " + cntBad)
Azioni di servizio
${xml_add_to_group}
Parametri: Group ID (0–15 grp)
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x60 + grp);
${xml_remove_from_group}
Parametri: Group ID (0–15 grp)
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x70 + grp);
${xml_reset_to_default_settings}
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x20);
${xml_set_startup_levels}
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x21);
sleep(10);
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x2c);
sleep(10);
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x2d);
Disable fading
modbusw(SH, 541, uint16, 0xA300);
sleep(100);
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x2E);
sleep(100);
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x30);
Gear 58 Dimmer Lettura e scrittura

Dispositivo di controllo DALI all'indirizzo breve 58 — dimmer TapHome mappato su DALI arc power 0–100 % tramite H:510 LAMP LEVEL (scrittura) e QUERY ACTUAL LEVEL tramite H:511 (lettura), delimitato dai propri MIN / MAX LEVEL del gear.

Registro: H:511 → H:510 UInt16 Unità: % numeric
Attributi di servizio
Indirizzo breveIndirizzo breve DALI (0–63) target di questo dispositivo — fissato al momento dell'importazione del template e utilizzato nel byte alto di ogni scrittura Modbus.
Device TypeByte device-type DALI restituito da QUERY DEVICE TYPE (0x99) — riporta DT0 (fluorescente), DT6 (driver LED), DT8 (colore / tunable white) ecc., o -- quando non c'è risposta.
Physical Min LevelLivello minimo di dimmerazione imposto dall'hardware riportato dal gear — letto da QUERY PHYSICAL MIN LEVEL (0x9A), in percentuale.
Max LevelDALI MAX LEVEL configurato — letto da QUERY MAX LEVEL (0xA1); utilizzato come limite superiore durante la scalatura di TapHome 0–100 % su DALI arc power.
Min LevelDALI MIN LEVEL configurato — letto da QUERY MIN LEVEL (0xA2); utilizzato come limite inferiore durante la scalatura di TapHome 0–100 % su DALI arc power.
Power Up LevelLuminosità ripristinata dopo il ripristino dell'alimentazione del bus DALI — letta da QUERY POWER ON LEVEL (0xA3).
System Failure LevelLuminosità adottata quando il bus DALI perde la comunicazione per più di 500 ms — letta da QUERY SYSTEM FAILURE LEVEL (0xA4).
GruppiElenco separato da virgole dei gruppi DALI (0–15) a cui appartiene il gear — decodificato da QUERY GROUPS 0-7 (0xC0) e QUERY GROUPS 8-15 (0xC1); mostra None o ad es. 0,3,7.
Support Lamp FailureSe la lampada / driver supporta il rilevamento dei guasti della lampada — Yes / No / --. Gestisce l'errore Lamp failure! nel readscript periodico.
Support Power FailureSe la lampada / driver supporta il rilevamento dei guasti di alimentazione — Yes / No / --. Gestisce l'errore Power failure! nel readscript periodico.
DALI Version
Bus statistics
Azioni di servizio
Add to GroupAggiunge questo gear a un gruppo DALI (0–15) tramite ADD TO GROUP (0x60+grp) — auto-ripetuto entro 100 ms come richiesto per i comandi di configurazione DALI.
Remove from GroupRimuove questo gear da un gruppo DALI (0–15) tramite REMOVE FROM GROUP (0x70+grp).
Reset to Default SettingsInvia DALI RESET (0x20) — ripristina ogni parametro NVM del gear (livelli max / min / power-on / system-failure, appartenenza al gruppo, scene) al valore predefinito del produttore.
Set Startup LevelsCattura l'arc power corrente e la memorizza come Power On Level e System Failure Level — sequenza STORE ACTUAL LEVEL IN DTR (0x21) → STORE DTR AS POWER ON LEVEL (0x2C) → STORE DTR AS SYSTEM FAILURE LEVEL (0x2D).
Disable fading

Gear 58

Lettura (modulo)
var x := 0; var rx := 0; var y := 0;
if Status > 0
    Status := Status - 1;
    adderror(3, "Gear not responding!");
    return(0);
end

# checkStatus: ReadLevel resets it while the gear answers; statusPoll: QUERY STATUS at least once per 60 runs
checkStatus := checkStatus - 1;
statusPoll := statusPoll - 1;
if checkStatus < 1 or statusPoll < 1
    # an unread answer left in the gateway would be taken for this query: read it away and count it
    x := modbusr(SH, 511, uint16); if (x != 0x8000, cntStale := cntStale + 1);
    modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x90);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    x := modbusr(SH, 511, uint16);
    cntQ := cntQ + 1; if (x = 0x8000, cntNone := cntNone + 1); if (x = 0x20FF, cntColl := cntColl + 1);
    # a single lost answer happens on DALI: ask once more before declaring the gear missing
    if x = 0x8000
        x := modbusr(SH, 511, uint16); if (x != 0x8000, cntStale := cntStale + 1);
        modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x90);
        sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
        x := modbusr(SH, 511, uint16);
        cntQ := cntQ + 1; if (x = 0x8000, cntNone := cntNone + 1); if (x = 0x20FF, cntColl := cntColl + 1);
    end
    if x <= 0xFF
        # a changed failure bit must be read twice the same before it is taken
        if statusSeen = 1 and getbits(x, 0, 2) != getbits(gearStatus, 0, 2)
            y := modbusr(SH, 511, uint16); if (y != 0x8000, cntStale := cntStale + 1);
            modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x90);
            sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
            y := modbusr(SH, 511, uint16);
            cntQ := cntQ + 1; if (y = 0x8000, cntNone := cntNone + 1); if (y = 0x20FF, cntColl := cntColl + 1);
            if y != x
                cntBad := cntBad + 1;
                x := gearStatus;
            end
        end
        if statusSeen = 0
            ignGear := getbit(x, 0);
            ignLamp := getbit(x, 1);
            statusSeen := 1;
        end
        # a bit that clears ends its ignore, so a later failure is raised
        if (getbit(x, 0) = 0, ignGear := 0);
        if (getbit(x, 1) = 0, ignLamp := 0);
        gearStatus := x;
        checkStatus := 60;
        statusPoll := 60;
    else
        if x = 0x8000
            Status := RANDINT(10, 60);
            adderror(3, "Gear not responding!");
            return(0);
        end
    end
end

# messages last one run only, so they are raised from the stored status on every run
if ((getbit(gearStatus, 0) = 1) and (ignGear = 0), adderror(1, "Control gear failure!"));
if ((getbit(gearStatus, 1) = 1) and (ignLamp = 0), adderror(2, "Lamp failure!"));
Inizializzazione
var x := 0; var rx := 0;
# QUERY STATUS 0x90: every reply byte proves the gear is present; 0x8000 = no answer, 0x20FF = bus collision
# an unread answer left in the gateway would be taken for this query: read it away and count it
x := modbusr(SH, 511, uint16); if (x != 0x8000, cntStale := cntStale + 1);
modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x90);
sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
x := modbusr(SH, 511, uint16);
cntQ := cntQ + 1; if (x = 0x8000, cntNone := cntNone + 1); if (x = 0x20FF, cntColl := cntColl + 1);
statusSeen := 0;
if x <= 0xFF
    # failure bits a gear reports from its first answer are its permanent state, not an event: shown, not raised
    gearStatus := x;
    ignGear := getbit(x, 0);
    ignLamp := getbit(x, 1);
    statusSeen := 1;
    Status := 0;
else
    Status := RANDINT(1, 60);
end

if Status = 0
    x := modbusr(SH, 511, uint16); if (x != 0x8000, cntStale := cntStale + 1);
    modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA2);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    x := modbusr(SH, 511, uint16);
    cntQ := cntQ + 1; if (x = 0x8000, cntNone := cntNone + 1); if (x = 0x20FF, cntColl := cntColl + 1);
    if (x <= 0xFE, minLevel := x);

    x := modbusr(SH, 511, uint16); if (x != 0x8000, cntStale := cntStale + 1);
    modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA1);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    x := modbusr(SH, 511, uint16);
    cntQ := cntQ + 1; if (x = 0x8000, cntNone := cntNone + 1); if (x = 0x20FF, cntColl := cntColl + 1);
    if (x <= 0xFE, maxLevel := x);
end
Lettura livello
var x := 0; var rx := 0; var y := 0;
if Status = 0
    if minLevel = 0
        # an unread answer left in the gateway would be taken for this query: read it away and count it
        x := modbusr(SH, 511, uint16); if (x != 0x8000, cntStale := cntStale + 1);
        modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA2);
        sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
        x := modbusr(SH, 511, uint16);
        cntQ := cntQ + 1; if (x = 0x8000, cntNone := cntNone + 1); if (x = 0x20FF, cntColl := cntColl + 1);
        if (x <= 0xFE, minLevel := x);
    end
    x := modbusr(SH, 511, uint16); if (x != 0x8000, cntStale := cntStale + 1);
    modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA0);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    x := modbusr(SH, 511, uint16);
    cntQ := cntQ + 1; if (x = 0x8000, cntNone := cntNone + 1); if (x = 0x20FF, cntColl := cntColl + 1);
    if (x != 0x8000 or rx, checkStatus := 60);
    # 0xFF = MASK, 0x20FF = collision, 0x8000 = no answer: keep the last level instead of a phantom value
    if x > 0xFE
        return(Le);
    end
    # an actual level is 0 or between the gear's min and max: anything else is not this gear's answer
    if x > 0 and x < minLevel
        cntBad := cntBad + 1;
        return(Le);
    end
    # a changed level must be read twice the same before it is taken
    if x != lastRaw
        y := modbusr(SH, 511, uint16); if (y != 0x8000, cntStale := cntStale + 1);
        modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA0);
        sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
        y := modbusr(SH, 511, uint16);
        cntQ := cntQ + 1; if (y = 0x8000, cntNone := cntNone + 1); if (y = 0x20FF, cntColl := cntColl + 1);
        if y != x
            cntBad := cntBad + 1;
            return(Le);
        end
        lastRaw := x;
    end
    return(if(x = 0, 0, linear(x, minLevel, 0.01, maxLevel, 1)));
else
    return(NaN);
end
Scrittura livello
var level := 0;
if(Le > 0, level := round(linear(Le, 0.01, minLevel, 1, maxLevel)));
modbusw(SH, 510, uint16, (ShortAddress << 8) + level );
Attributi di servizio
${xml_short_address}
ShortAddress
${xml_device_type}
var x := 0; var y := 0; var rx := 0; var s := ""; var i := 0;
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x99);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    x := modbusr(SH, 511, uint16);
    if (x < 0xFF, return("DT" + x));
    if x = 0xFF
        while i < 8
            modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA7);
            sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
            y := modbusr(SH, 511, uint16);
            if y < 0xFE
                s := if(s = "", "DT" + y, s + ", DT" + y);
                i := i + 1;
            else
                i := 8;
            end
        loop
        return(if(s = "", "MASK", s));
    end
end

return("--")
Physical Min Level
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x9A);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if (x <= 0xFE, return(round((x / 0xFE) * 100) + " %"));
end

return("--")
Max Level
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA1);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if (x <= 0xFE, return(round((x / 0xFE) * 100) + " %"));
end

return("--")
Min Level
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA2);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if (x <= 0xFE, return(round((x / 0xFE) * 100) + " %"));
end

return("--")
Power Up Level
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA3);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if (x <= 0xFE, return(round((x / 0xFE) * 100) + " %"));
end

return("--")
System Failure Level
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA4);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if (x <= 0xFE, return(round((x / 0xFE) * 100) + " %"));
end

return("--")
${xml_groups}
var x := 0; var rx := 0;
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xC0);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var g1 := modbusr(SH, 511, uint16);
    if (g1 > 0xFF, return("--")); 

    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xC1);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var g2 := modbusr(SH, 511, uint16);
    if (g2 > 0xFF, return("--")); 

    var ret := "";

    if (getbit(g1, 0), ret := ret + "0");
    if (getbit(g1, 1), if (ret = "", ret := "1", ret := ret + ",1"));
    if (getbit(g1, 2), if (ret = "", ret := "2", ret := ret + ",2"));
    if (getbit(g1, 3), if (ret = "", ret := "3", ret := ret + ",3"));
    if (getbit(g1, 4), if (ret = "", ret := "4", ret := ret + ",4"));
    if (getbit(g1, 5), if (ret = "", ret := "5", ret := ret + ",5"));
    if (getbit(g1, 6), if (ret = "", ret := "6", ret := ret + ",6"));
    if (getbit(g1, 7), if (ret = "", ret := "7", ret := ret + ",7"));
    if (getbit(g2, 0), if (ret = "", ret := "8", ret := ret + ",8"));
    if (getbit(g2, 1), if (ret = "", ret := "9", ret := ret + ",9"));
    if (getbit(g2, 2), if (ret = "", ret := "10", ret := ret + ",10"));
    if (getbit(g2, 3), if (ret = "", ret := "11", ret := ret + ",11"));
    if (getbit(g2, 4), if (ret = "", ret := "12", ret := ret + ",12"));
    if (getbit(g2, 5), if (ret = "", ret := "13", ret := ret + ",13"));
    if (getbit(g2, 6), if (ret = "", ret := "14", ret := ret + ",14"));
    if (getbit(g2, 7), if (ret = "", ret := "15", ret := ret + ",15"));

    if (ret = "", return("None"), return(ret));
else
    return("--");
end
DALI Status
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x90);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if x <= 0xFF
        var s := "";
        if (getbit(x, 0), s := if(s = "", "gear failure", s + ", gear failure"));
        if (getbit(x, 1), s := if(s = "", "lamp failure", s + ", lamp failure"));
        if (getbit(x, 2), s := if(s = "", "lamp on", s + ", lamp on"));
        if (getbit(x, 3), s := if(s = "", "limit error", s + ", limit error"));
        if (getbit(x, 4), s := if(s = "", "fade running", s + ", fade running"));
        if (getbit(x, 5), s := if(s = "", "reset state", s + ", reset state"));
        if (getbit(x, 6), s := if(s = "", "missing short address", s + ", missing short address"));
        if (getbit(x, 7), s := if(s = "", "power cycle", s + ", power cycle"));
        var ign := if((ignGear = 1) and (ignLamp = 1), "gear and lamp failure", if(ignGear = 1, "gear failure", if(ignLamp = 1, "lamp failure", "")));
        return(if(s = "", "OK", s) + " (0x" + tostring(x, "X2") + ")" + if(ign = "", "", "; not raised: " + ign + " reported since start"));
    end
end

return("--")
Fade
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA5);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if x <= 0xFF
        var t := getbits(x, 4, 4);
        var ret := if(t = 0, "off", t + " (" + round(sqrt(power(2, t)) * 5) / 10 + " s)");
        modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA8);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
        var e := modbusr(SH, 511, uint16);
        if (t = 0 and e <= 0xFF and e != 0, ret := "extended 0x" + tostring(e, "X2"));
        return("fade time " + ret + ", fade rate " + getbits(x, 0, 4));
    end
end

return("--")
DALI Version
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x97);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if x <= 0xFF
        return(if(x >= 8, "DALI-2 " + getbits(x, 2, 6) + "." + getbits(x, 0, 2), "DALI-1") + " (" + x + ")");
    end
end

return("--")
Bus statistics
return("since start: queries " + cntQ + ", stale answers read away " + cntStale + ", no answer " + cntNone + ", collisions " + cntColl + ", rejected levels " + cntBad)
Azioni di servizio
${xml_add_to_group}
Parametri: Group ID (0–15 grp)
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x60 + grp);
${xml_remove_from_group}
Parametri: Group ID (0–15 grp)
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x70 + grp);
${xml_reset_to_default_settings}
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x20);
${xml_set_startup_levels}
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x21);
sleep(10);
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x2c);
sleep(10);
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x2d);
Disable fading
modbusw(SH, 541, uint16, 0xA300);
sleep(100);
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x2E);
sleep(100);
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x30);
Gear 59 Dimmer Lettura e scrittura

Dispositivo di controllo DALI all'indirizzo breve 59 — dimmer TapHome mappato su DALI arc power 0–100 % tramite H:510 LAMP LEVEL (scrittura) e QUERY ACTUAL LEVEL tramite H:511 (lettura), delimitato dai propri MIN / MAX LEVEL del gear.

Registro: H:511 → H:510 UInt16 Unità: % numeric
Attributi di servizio
Indirizzo breveIndirizzo breve DALI (0–63) target di questo dispositivo — fissato al momento dell'importazione del template e utilizzato nel byte alto di ogni scrittura Modbus.
Device TypeByte device-type DALI restituito da QUERY DEVICE TYPE (0x99) — riporta DT0 (fluorescente), DT6 (driver LED), DT8 (colore / tunable white) ecc., o -- quando non c'è risposta.
Physical Min LevelLivello minimo di dimmerazione imposto dall'hardware riportato dal gear — letto da QUERY PHYSICAL MIN LEVEL (0x9A), in percentuale.
Max LevelDALI MAX LEVEL configurato — letto da QUERY MAX LEVEL (0xA1); utilizzato come limite superiore durante la scalatura di TapHome 0–100 % su DALI arc power.
Min LevelDALI MIN LEVEL configurato — letto da QUERY MIN LEVEL (0xA2); utilizzato come limite inferiore durante la scalatura di TapHome 0–100 % su DALI arc power.
Power Up LevelLuminosità ripristinata dopo il ripristino dell'alimentazione del bus DALI — letta da QUERY POWER ON LEVEL (0xA3).
System Failure LevelLuminosità adottata quando il bus DALI perde la comunicazione per più di 500 ms — letta da QUERY SYSTEM FAILURE LEVEL (0xA4).
GruppiElenco separato da virgole dei gruppi DALI (0–15) a cui appartiene il gear — decodificato da QUERY GROUPS 0-7 (0xC0) e QUERY GROUPS 8-15 (0xC1); mostra None o ad es. 0,3,7.
Support Lamp FailureSe la lampada / driver supporta il rilevamento dei guasti della lampada — Yes / No / --. Gestisce l'errore Lamp failure! nel readscript periodico.
Support Power FailureSe la lampada / driver supporta il rilevamento dei guasti di alimentazione — Yes / No / --. Gestisce l'errore Power failure! nel readscript periodico.
DALI Version
Bus statistics
Azioni di servizio
Add to GroupAggiunge questo gear a un gruppo DALI (0–15) tramite ADD TO GROUP (0x60+grp) — auto-ripetuto entro 100 ms come richiesto per i comandi di configurazione DALI.
Remove from GroupRimuove questo gear da un gruppo DALI (0–15) tramite REMOVE FROM GROUP (0x70+grp).
Reset to Default SettingsInvia DALI RESET (0x20) — ripristina ogni parametro NVM del gear (livelli max / min / power-on / system-failure, appartenenza al gruppo, scene) al valore predefinito del produttore.
Set Startup LevelsCattura l'arc power corrente e la memorizza come Power On Level e System Failure Level — sequenza STORE ACTUAL LEVEL IN DTR (0x21) → STORE DTR AS POWER ON LEVEL (0x2C) → STORE DTR AS SYSTEM FAILURE LEVEL (0x2D).
Disable fading

Gear 59

Lettura (modulo)
var x := 0; var rx := 0; var y := 0;
if Status > 0
    Status := Status - 1;
    adderror(3, "Gear not responding!");
    return(0);
end

# checkStatus: ReadLevel resets it while the gear answers; statusPoll: QUERY STATUS at least once per 60 runs
checkStatus := checkStatus - 1;
statusPoll := statusPoll - 1;
if checkStatus < 1 or statusPoll < 1
    # an unread answer left in the gateway would be taken for this query: read it away and count it
    x := modbusr(SH, 511, uint16); if (x != 0x8000, cntStale := cntStale + 1);
    modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x90);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    x := modbusr(SH, 511, uint16);
    cntQ := cntQ + 1; if (x = 0x8000, cntNone := cntNone + 1); if (x = 0x20FF, cntColl := cntColl + 1);
    # a single lost answer happens on DALI: ask once more before declaring the gear missing
    if x = 0x8000
        x := modbusr(SH, 511, uint16); if (x != 0x8000, cntStale := cntStale + 1);
        modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x90);
        sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
        x := modbusr(SH, 511, uint16);
        cntQ := cntQ + 1; if (x = 0x8000, cntNone := cntNone + 1); if (x = 0x20FF, cntColl := cntColl + 1);
    end
    if x <= 0xFF
        # a changed failure bit must be read twice the same before it is taken
        if statusSeen = 1 and getbits(x, 0, 2) != getbits(gearStatus, 0, 2)
            y := modbusr(SH, 511, uint16); if (y != 0x8000, cntStale := cntStale + 1);
            modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x90);
            sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
            y := modbusr(SH, 511, uint16);
            cntQ := cntQ + 1; if (y = 0x8000, cntNone := cntNone + 1); if (y = 0x20FF, cntColl := cntColl + 1);
            if y != x
                cntBad := cntBad + 1;
                x := gearStatus;
            end
        end
        if statusSeen = 0
            ignGear := getbit(x, 0);
            ignLamp := getbit(x, 1);
            statusSeen := 1;
        end
        # a bit that clears ends its ignore, so a later failure is raised
        if (getbit(x, 0) = 0, ignGear := 0);
        if (getbit(x, 1) = 0, ignLamp := 0);
        gearStatus := x;
        checkStatus := 60;
        statusPoll := 60;
    else
        if x = 0x8000
            Status := RANDINT(10, 60);
            adderror(3, "Gear not responding!");
            return(0);
        end
    end
end

# messages last one run only, so they are raised from the stored status on every run
if ((getbit(gearStatus, 0) = 1) and (ignGear = 0), adderror(1, "Control gear failure!"));
if ((getbit(gearStatus, 1) = 1) and (ignLamp = 0), adderror(2, "Lamp failure!"));
Inizializzazione
var x := 0; var rx := 0;
# QUERY STATUS 0x90: every reply byte proves the gear is present; 0x8000 = no answer, 0x20FF = bus collision
# an unread answer left in the gateway would be taken for this query: read it away and count it
x := modbusr(SH, 511, uint16); if (x != 0x8000, cntStale := cntStale + 1);
modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x90);
sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
x := modbusr(SH, 511, uint16);
cntQ := cntQ + 1; if (x = 0x8000, cntNone := cntNone + 1); if (x = 0x20FF, cntColl := cntColl + 1);
statusSeen := 0;
if x <= 0xFF
    # failure bits a gear reports from its first answer are its permanent state, not an event: shown, not raised
    gearStatus := x;
    ignGear := getbit(x, 0);
    ignLamp := getbit(x, 1);
    statusSeen := 1;
    Status := 0;
else
    Status := RANDINT(1, 60);
end

if Status = 0
    x := modbusr(SH, 511, uint16); if (x != 0x8000, cntStale := cntStale + 1);
    modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA2);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    x := modbusr(SH, 511, uint16);
    cntQ := cntQ + 1; if (x = 0x8000, cntNone := cntNone + 1); if (x = 0x20FF, cntColl := cntColl + 1);
    if (x <= 0xFE, minLevel := x);

    x := modbusr(SH, 511, uint16); if (x != 0x8000, cntStale := cntStale + 1);
    modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA1);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    x := modbusr(SH, 511, uint16);
    cntQ := cntQ + 1; if (x = 0x8000, cntNone := cntNone + 1); if (x = 0x20FF, cntColl := cntColl + 1);
    if (x <= 0xFE, maxLevel := x);
end
Lettura livello
var x := 0; var rx := 0; var y := 0;
if Status = 0
    if minLevel = 0
        # an unread answer left in the gateway would be taken for this query: read it away and count it
        x := modbusr(SH, 511, uint16); if (x != 0x8000, cntStale := cntStale + 1);
        modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA2);
        sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
        x := modbusr(SH, 511, uint16);
        cntQ := cntQ + 1; if (x = 0x8000, cntNone := cntNone + 1); if (x = 0x20FF, cntColl := cntColl + 1);
        if (x <= 0xFE, minLevel := x);
    end
    x := modbusr(SH, 511, uint16); if (x != 0x8000, cntStale := cntStale + 1);
    modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA0);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    x := modbusr(SH, 511, uint16);
    cntQ := cntQ + 1; if (x = 0x8000, cntNone := cntNone + 1); if (x = 0x20FF, cntColl := cntColl + 1);
    if (x != 0x8000 or rx, checkStatus := 60);
    # 0xFF = MASK, 0x20FF = collision, 0x8000 = no answer: keep the last level instead of a phantom value
    if x > 0xFE
        return(Le);
    end
    # an actual level is 0 or between the gear's min and max: anything else is not this gear's answer
    if x > 0 and x < minLevel
        cntBad := cntBad + 1;
        return(Le);
    end
    # a changed level must be read twice the same before it is taken
    if x != lastRaw
        y := modbusr(SH, 511, uint16); if (y != 0x8000, cntStale := cntStale + 1);
        modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA0);
        sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
        y := modbusr(SH, 511, uint16);
        cntQ := cntQ + 1; if (y = 0x8000, cntNone := cntNone + 1); if (y = 0x20FF, cntColl := cntColl + 1);
        if y != x
            cntBad := cntBad + 1;
            return(Le);
        end
        lastRaw := x;
    end
    return(if(x = 0, 0, linear(x, minLevel, 0.01, maxLevel, 1)));
else
    return(NaN);
end
Scrittura livello
var level := 0;
if(Le > 0, level := round(linear(Le, 0.01, minLevel, 1, maxLevel)));
modbusw(SH, 510, uint16, (ShortAddress << 8) + level );
Attributi di servizio
${xml_short_address}
ShortAddress
${xml_device_type}
var x := 0; var y := 0; var rx := 0; var s := ""; var i := 0;
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x99);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    x := modbusr(SH, 511, uint16);
    if (x < 0xFF, return("DT" + x));
    if x = 0xFF
        while i < 8
            modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA7);
            sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
            y := modbusr(SH, 511, uint16);
            if y < 0xFE
                s := if(s = "", "DT" + y, s + ", DT" + y);
                i := i + 1;
            else
                i := 8;
            end
        loop
        return(if(s = "", "MASK", s));
    end
end

return("--")
Physical Min Level
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x9A);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if (x <= 0xFE, return(round((x / 0xFE) * 100) + " %"));
end

return("--")
Max Level
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA1);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if (x <= 0xFE, return(round((x / 0xFE) * 100) + " %"));
end

return("--")
Min Level
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA2);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if (x <= 0xFE, return(round((x / 0xFE) * 100) + " %"));
end

return("--")
Power Up Level
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA3);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if (x <= 0xFE, return(round((x / 0xFE) * 100) + " %"));
end

return("--")
System Failure Level
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA4);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if (x <= 0xFE, return(round((x / 0xFE) * 100) + " %"));
end

return("--")
${xml_groups}
var x := 0; var rx := 0;
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xC0);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var g1 := modbusr(SH, 511, uint16);
    if (g1 > 0xFF, return("--")); 

    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xC1);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var g2 := modbusr(SH, 511, uint16);
    if (g2 > 0xFF, return("--")); 

    var ret := "";

    if (getbit(g1, 0), ret := ret + "0");
    if (getbit(g1, 1), if (ret = "", ret := "1", ret := ret + ",1"));
    if (getbit(g1, 2), if (ret = "", ret := "2", ret := ret + ",2"));
    if (getbit(g1, 3), if (ret = "", ret := "3", ret := ret + ",3"));
    if (getbit(g1, 4), if (ret = "", ret := "4", ret := ret + ",4"));
    if (getbit(g1, 5), if (ret = "", ret := "5", ret := ret + ",5"));
    if (getbit(g1, 6), if (ret = "", ret := "6", ret := ret + ",6"));
    if (getbit(g1, 7), if (ret = "", ret := "7", ret := ret + ",7"));
    if (getbit(g2, 0), if (ret = "", ret := "8", ret := ret + ",8"));
    if (getbit(g2, 1), if (ret = "", ret := "9", ret := ret + ",9"));
    if (getbit(g2, 2), if (ret = "", ret := "10", ret := ret + ",10"));
    if (getbit(g2, 3), if (ret = "", ret := "11", ret := ret + ",11"));
    if (getbit(g2, 4), if (ret = "", ret := "12", ret := ret + ",12"));
    if (getbit(g2, 5), if (ret = "", ret := "13", ret := ret + ",13"));
    if (getbit(g2, 6), if (ret = "", ret := "14", ret := ret + ",14"));
    if (getbit(g2, 7), if (ret = "", ret := "15", ret := ret + ",15"));

    if (ret = "", return("None"), return(ret));
else
    return("--");
end
DALI Status
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x90);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if x <= 0xFF
        var s := "";
        if (getbit(x, 0), s := if(s = "", "gear failure", s + ", gear failure"));
        if (getbit(x, 1), s := if(s = "", "lamp failure", s + ", lamp failure"));
        if (getbit(x, 2), s := if(s = "", "lamp on", s + ", lamp on"));
        if (getbit(x, 3), s := if(s = "", "limit error", s + ", limit error"));
        if (getbit(x, 4), s := if(s = "", "fade running", s + ", fade running"));
        if (getbit(x, 5), s := if(s = "", "reset state", s + ", reset state"));
        if (getbit(x, 6), s := if(s = "", "missing short address", s + ", missing short address"));
        if (getbit(x, 7), s := if(s = "", "power cycle", s + ", power cycle"));
        var ign := if((ignGear = 1) and (ignLamp = 1), "gear and lamp failure", if(ignGear = 1, "gear failure", if(ignLamp = 1, "lamp failure", "")));
        return(if(s = "", "OK", s) + " (0x" + tostring(x, "X2") + ")" + if(ign = "", "", "; not raised: " + ign + " reported since start"));
    end
end

return("--")
Fade
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA5);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if x <= 0xFF
        var t := getbits(x, 4, 4);
        var ret := if(t = 0, "off", t + " (" + round(sqrt(power(2, t)) * 5) / 10 + " s)");
        modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA8);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
        var e := modbusr(SH, 511, uint16);
        if (t = 0 and e <= 0xFF and e != 0, ret := "extended 0x" + tostring(e, "X2"));
        return("fade time " + ret + ", fade rate " + getbits(x, 0, 4));
    end
end

return("--")
DALI Version
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x97);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if x <= 0xFF
        return(if(x >= 8, "DALI-2 " + getbits(x, 2, 6) + "." + getbits(x, 0, 2), "DALI-1") + " (" + x + ")");
    end
end

return("--")
Bus statistics
return("since start: queries " + cntQ + ", stale answers read away " + cntStale + ", no answer " + cntNone + ", collisions " + cntColl + ", rejected levels " + cntBad)
Azioni di servizio
${xml_add_to_group}
Parametri: Group ID (0–15 grp)
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x60 + grp);
${xml_remove_from_group}
Parametri: Group ID (0–15 grp)
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x70 + grp);
${xml_reset_to_default_settings}
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x20);
${xml_set_startup_levels}
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x21);
sleep(10);
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x2c);
sleep(10);
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x2d);
Disable fading
modbusw(SH, 541, uint16, 0xA300);
sleep(100);
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x2E);
sleep(100);
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x30);
Gear 60 Dimmer Lettura e scrittura

Dispositivo di controllo DALI all'indirizzo breve 60 — dimmer TapHome mappato su DALI arc power 0–100 % tramite H:510 LAMP LEVEL (scrittura) e QUERY ACTUAL LEVEL tramite H:511 (lettura), delimitato dai propri MIN / MAX LEVEL del gear.

Registro: H:511 → H:510 UInt16 Unità: % numeric
Attributi di servizio
Indirizzo breveIndirizzo breve DALI (0–63) target di questo dispositivo — fissato al momento dell'importazione del template e utilizzato nel byte alto di ogni scrittura Modbus.
Device TypeByte device-type DALI restituito da QUERY DEVICE TYPE (0x99) — riporta DT0 (fluorescente), DT6 (driver LED), DT8 (colore / tunable white) ecc., o -- quando non c'è risposta.
Physical Min LevelLivello minimo di dimmerazione imposto dall'hardware riportato dal gear — letto da QUERY PHYSICAL MIN LEVEL (0x9A), in percentuale.
Max LevelDALI MAX LEVEL configurato — letto da QUERY MAX LEVEL (0xA1); utilizzato come limite superiore durante la scalatura di TapHome 0–100 % su DALI arc power.
Min LevelDALI MIN LEVEL configurato — letto da QUERY MIN LEVEL (0xA2); utilizzato come limite inferiore durante la scalatura di TapHome 0–100 % su DALI arc power.
Power Up LevelLuminosità ripristinata dopo il ripristino dell'alimentazione del bus DALI — letta da QUERY POWER ON LEVEL (0xA3).
System Failure LevelLuminosità adottata quando il bus DALI perde la comunicazione per più di 500 ms — letta da QUERY SYSTEM FAILURE LEVEL (0xA4).
GruppiElenco separato da virgole dei gruppi DALI (0–15) a cui appartiene il gear — decodificato da QUERY GROUPS 0-7 (0xC0) e QUERY GROUPS 8-15 (0xC1); mostra None o ad es. 0,3,7.
Support Lamp FailureSe la lampada / driver supporta il rilevamento dei guasti della lampada — Yes / No / --. Gestisce l'errore Lamp failure! nel readscript periodico.
Support Power FailureSe la lampada / driver supporta il rilevamento dei guasti di alimentazione — Yes / No / --. Gestisce l'errore Power failure! nel readscript periodico.
DALI Version
Bus statistics
Azioni di servizio
Add to GroupAggiunge questo gear a un gruppo DALI (0–15) tramite ADD TO GROUP (0x60+grp) — auto-ripetuto entro 100 ms come richiesto per i comandi di configurazione DALI.
Remove from GroupRimuove questo gear da un gruppo DALI (0–15) tramite REMOVE FROM GROUP (0x70+grp).
Reset to Default SettingsInvia DALI RESET (0x20) — ripristina ogni parametro NVM del gear (livelli max / min / power-on / system-failure, appartenenza al gruppo, scene) al valore predefinito del produttore.
Set Startup LevelsCattura l'arc power corrente e la memorizza come Power On Level e System Failure Level — sequenza STORE ACTUAL LEVEL IN DTR (0x21) → STORE DTR AS POWER ON LEVEL (0x2C) → STORE DTR AS SYSTEM FAILURE LEVEL (0x2D).
Disable fading

Gear 60

Lettura (modulo)
var x := 0; var rx := 0; var y := 0;
if Status > 0
    Status := Status - 1;
    adderror(3, "Gear not responding!");
    return(0);
end

# checkStatus: ReadLevel resets it while the gear answers; statusPoll: QUERY STATUS at least once per 60 runs
checkStatus := checkStatus - 1;
statusPoll := statusPoll - 1;
if checkStatus < 1 or statusPoll < 1
    # an unread answer left in the gateway would be taken for this query: read it away and count it
    x := modbusr(SH, 511, uint16); if (x != 0x8000, cntStale := cntStale + 1);
    modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x90);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    x := modbusr(SH, 511, uint16);
    cntQ := cntQ + 1; if (x = 0x8000, cntNone := cntNone + 1); if (x = 0x20FF, cntColl := cntColl + 1);
    # a single lost answer happens on DALI: ask once more before declaring the gear missing
    if x = 0x8000
        x := modbusr(SH, 511, uint16); if (x != 0x8000, cntStale := cntStale + 1);
        modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x90);
        sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
        x := modbusr(SH, 511, uint16);
        cntQ := cntQ + 1; if (x = 0x8000, cntNone := cntNone + 1); if (x = 0x20FF, cntColl := cntColl + 1);
    end
    if x <= 0xFF
        # a changed failure bit must be read twice the same before it is taken
        if statusSeen = 1 and getbits(x, 0, 2) != getbits(gearStatus, 0, 2)
            y := modbusr(SH, 511, uint16); if (y != 0x8000, cntStale := cntStale + 1);
            modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x90);
            sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
            y := modbusr(SH, 511, uint16);
            cntQ := cntQ + 1; if (y = 0x8000, cntNone := cntNone + 1); if (y = 0x20FF, cntColl := cntColl + 1);
            if y != x
                cntBad := cntBad + 1;
                x := gearStatus;
            end
        end
        if statusSeen = 0
            ignGear := getbit(x, 0);
            ignLamp := getbit(x, 1);
            statusSeen := 1;
        end
        # a bit that clears ends its ignore, so a later failure is raised
        if (getbit(x, 0) = 0, ignGear := 0);
        if (getbit(x, 1) = 0, ignLamp := 0);
        gearStatus := x;
        checkStatus := 60;
        statusPoll := 60;
    else
        if x = 0x8000
            Status := RANDINT(10, 60);
            adderror(3, "Gear not responding!");
            return(0);
        end
    end
end

# messages last one run only, so they are raised from the stored status on every run
if ((getbit(gearStatus, 0) = 1) and (ignGear = 0), adderror(1, "Control gear failure!"));
if ((getbit(gearStatus, 1) = 1) and (ignLamp = 0), adderror(2, "Lamp failure!"));
Inizializzazione
var x := 0; var rx := 0;
# QUERY STATUS 0x90: every reply byte proves the gear is present; 0x8000 = no answer, 0x20FF = bus collision
# an unread answer left in the gateway would be taken for this query: read it away and count it
x := modbusr(SH, 511, uint16); if (x != 0x8000, cntStale := cntStale + 1);
modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x90);
sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
x := modbusr(SH, 511, uint16);
cntQ := cntQ + 1; if (x = 0x8000, cntNone := cntNone + 1); if (x = 0x20FF, cntColl := cntColl + 1);
statusSeen := 0;
if x <= 0xFF
    # failure bits a gear reports from its first answer are its permanent state, not an event: shown, not raised
    gearStatus := x;
    ignGear := getbit(x, 0);
    ignLamp := getbit(x, 1);
    statusSeen := 1;
    Status := 0;
else
    Status := RANDINT(1, 60);
end

if Status = 0
    x := modbusr(SH, 511, uint16); if (x != 0x8000, cntStale := cntStale + 1);
    modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA2);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    x := modbusr(SH, 511, uint16);
    cntQ := cntQ + 1; if (x = 0x8000, cntNone := cntNone + 1); if (x = 0x20FF, cntColl := cntColl + 1);
    if (x <= 0xFE, minLevel := x);

    x := modbusr(SH, 511, uint16); if (x != 0x8000, cntStale := cntStale + 1);
    modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA1);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    x := modbusr(SH, 511, uint16);
    cntQ := cntQ + 1; if (x = 0x8000, cntNone := cntNone + 1); if (x = 0x20FF, cntColl := cntColl + 1);
    if (x <= 0xFE, maxLevel := x);
end
Lettura livello
var x := 0; var rx := 0; var y := 0;
if Status = 0
    if minLevel = 0
        # an unread answer left in the gateway would be taken for this query: read it away and count it
        x := modbusr(SH, 511, uint16); if (x != 0x8000, cntStale := cntStale + 1);
        modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA2);
        sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
        x := modbusr(SH, 511, uint16);
        cntQ := cntQ + 1; if (x = 0x8000, cntNone := cntNone + 1); if (x = 0x20FF, cntColl := cntColl + 1);
        if (x <= 0xFE, minLevel := x);
    end
    x := modbusr(SH, 511, uint16); if (x != 0x8000, cntStale := cntStale + 1);
    modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA0);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    x := modbusr(SH, 511, uint16);
    cntQ := cntQ + 1; if (x = 0x8000, cntNone := cntNone + 1); if (x = 0x20FF, cntColl := cntColl + 1);
    if (x != 0x8000 or rx, checkStatus := 60);
    # 0xFF = MASK, 0x20FF = collision, 0x8000 = no answer: keep the last level instead of a phantom value
    if x > 0xFE
        return(Le);
    end
    # an actual level is 0 or between the gear's min and max: anything else is not this gear's answer
    if x > 0 and x < minLevel
        cntBad := cntBad + 1;
        return(Le);
    end
    # a changed level must be read twice the same before it is taken
    if x != lastRaw
        y := modbusr(SH, 511, uint16); if (y != 0x8000, cntStale := cntStale + 1);
        modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA0);
        sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
        y := modbusr(SH, 511, uint16);
        cntQ := cntQ + 1; if (y = 0x8000, cntNone := cntNone + 1); if (y = 0x20FF, cntColl := cntColl + 1);
        if y != x
            cntBad := cntBad + 1;
            return(Le);
        end
        lastRaw := x;
    end
    return(if(x = 0, 0, linear(x, minLevel, 0.01, maxLevel, 1)));
else
    return(NaN);
end
Scrittura livello
var level := 0;
if(Le > 0, level := round(linear(Le, 0.01, minLevel, 1, maxLevel)));
modbusw(SH, 510, uint16, (ShortAddress << 8) + level );
Attributi di servizio
${xml_short_address}
ShortAddress
${xml_device_type}
var x := 0; var y := 0; var rx := 0; var s := ""; var i := 0;
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x99);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    x := modbusr(SH, 511, uint16);
    if (x < 0xFF, return("DT" + x));
    if x = 0xFF
        while i < 8
            modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA7);
            sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
            y := modbusr(SH, 511, uint16);
            if y < 0xFE
                s := if(s = "", "DT" + y, s + ", DT" + y);
                i := i + 1;
            else
                i := 8;
            end
        loop
        return(if(s = "", "MASK", s));
    end
end

return("--")
Physical Min Level
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x9A);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if (x <= 0xFE, return(round((x / 0xFE) * 100) + " %"));
end

return("--")
Max Level
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA1);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if (x <= 0xFE, return(round((x / 0xFE) * 100) + " %"));
end

return("--")
Min Level
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA2);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if (x <= 0xFE, return(round((x / 0xFE) * 100) + " %"));
end

return("--")
Power Up Level
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA3);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if (x <= 0xFE, return(round((x / 0xFE) * 100) + " %"));
end

return("--")
System Failure Level
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA4);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if (x <= 0xFE, return(round((x / 0xFE) * 100) + " %"));
end

return("--")
${xml_groups}
var x := 0; var rx := 0;
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xC0);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var g1 := modbusr(SH, 511, uint16);
    if (g1 > 0xFF, return("--")); 

    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xC1);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var g2 := modbusr(SH, 511, uint16);
    if (g2 > 0xFF, return("--")); 

    var ret := "";

    if (getbit(g1, 0), ret := ret + "0");
    if (getbit(g1, 1), if (ret = "", ret := "1", ret := ret + ",1"));
    if (getbit(g1, 2), if (ret = "", ret := "2", ret := ret + ",2"));
    if (getbit(g1, 3), if (ret = "", ret := "3", ret := ret + ",3"));
    if (getbit(g1, 4), if (ret = "", ret := "4", ret := ret + ",4"));
    if (getbit(g1, 5), if (ret = "", ret := "5", ret := ret + ",5"));
    if (getbit(g1, 6), if (ret = "", ret := "6", ret := ret + ",6"));
    if (getbit(g1, 7), if (ret = "", ret := "7", ret := ret + ",7"));
    if (getbit(g2, 0), if (ret = "", ret := "8", ret := ret + ",8"));
    if (getbit(g2, 1), if (ret = "", ret := "9", ret := ret + ",9"));
    if (getbit(g2, 2), if (ret = "", ret := "10", ret := ret + ",10"));
    if (getbit(g2, 3), if (ret = "", ret := "11", ret := ret + ",11"));
    if (getbit(g2, 4), if (ret = "", ret := "12", ret := ret + ",12"));
    if (getbit(g2, 5), if (ret = "", ret := "13", ret := ret + ",13"));
    if (getbit(g2, 6), if (ret = "", ret := "14", ret := ret + ",14"));
    if (getbit(g2, 7), if (ret = "", ret := "15", ret := ret + ",15"));

    if (ret = "", return("None"), return(ret));
else
    return("--");
end
DALI Status
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x90);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if x <= 0xFF
        var s := "";
        if (getbit(x, 0), s := if(s = "", "gear failure", s + ", gear failure"));
        if (getbit(x, 1), s := if(s = "", "lamp failure", s + ", lamp failure"));
        if (getbit(x, 2), s := if(s = "", "lamp on", s + ", lamp on"));
        if (getbit(x, 3), s := if(s = "", "limit error", s + ", limit error"));
        if (getbit(x, 4), s := if(s = "", "fade running", s + ", fade running"));
        if (getbit(x, 5), s := if(s = "", "reset state", s + ", reset state"));
        if (getbit(x, 6), s := if(s = "", "missing short address", s + ", missing short address"));
        if (getbit(x, 7), s := if(s = "", "power cycle", s + ", power cycle"));
        var ign := if((ignGear = 1) and (ignLamp = 1), "gear and lamp failure", if(ignGear = 1, "gear failure", if(ignLamp = 1, "lamp failure", "")));
        return(if(s = "", "OK", s) + " (0x" + tostring(x, "X2") + ")" + if(ign = "", "", "; not raised: " + ign + " reported since start"));
    end
end

return("--")
Fade
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA5);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if x <= 0xFF
        var t := getbits(x, 4, 4);
        var ret := if(t = 0, "off", t + " (" + round(sqrt(power(2, t)) * 5) / 10 + " s)");
        modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA8);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
        var e := modbusr(SH, 511, uint16);
        if (t = 0 and e <= 0xFF and e != 0, ret := "extended 0x" + tostring(e, "X2"));
        return("fade time " + ret + ", fade rate " + getbits(x, 0, 4));
    end
end

return("--")
DALI Version
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x97);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if x <= 0xFF
        return(if(x >= 8, "DALI-2 " + getbits(x, 2, 6) + "." + getbits(x, 0, 2), "DALI-1") + " (" + x + ")");
    end
end

return("--")
Bus statistics
return("since start: queries " + cntQ + ", stale answers read away " + cntStale + ", no answer " + cntNone + ", collisions " + cntColl + ", rejected levels " + cntBad)
Azioni di servizio
${xml_add_to_group}
Parametri: Group ID (0–15 grp)
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x60 + grp);
${xml_remove_from_group}
Parametri: Group ID (0–15 grp)
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x70 + grp);
${xml_reset_to_default_settings}
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x20);
${xml_set_startup_levels}
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x21);
sleep(10);
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x2c);
sleep(10);
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x2d);
Disable fading
modbusw(SH, 541, uint16, 0xA300);
sleep(100);
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x2E);
sleep(100);
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x30);
Gear 61 Dimmer Lettura e scrittura

Dispositivo di controllo DALI all'indirizzo breve 61 — dimmer TapHome mappato su DALI arc power 0–100 % tramite H:510 LAMP LEVEL (scrittura) e QUERY ACTUAL LEVEL tramite H:511 (lettura), delimitato dai propri MIN / MAX LEVEL del gear.

Registro: H:511 → H:510 UInt16 Unità: % numeric
Attributi di servizio
Indirizzo breveIndirizzo breve DALI (0–63) target di questo dispositivo — fissato al momento dell'importazione del template e utilizzato nel byte alto di ogni scrittura Modbus.
Device TypeByte device-type DALI restituito da QUERY DEVICE TYPE (0x99) — riporta DT0 (fluorescente), DT6 (driver LED), DT8 (colore / tunable white) ecc., o -- quando non c'è risposta.
Physical Min LevelLivello minimo di dimmerazione imposto dall'hardware riportato dal gear — letto da QUERY PHYSICAL MIN LEVEL (0x9A), in percentuale.
Max LevelDALI MAX LEVEL configurato — letto da QUERY MAX LEVEL (0xA1); utilizzato come limite superiore durante la scalatura di TapHome 0–100 % su DALI arc power.
Min LevelDALI MIN LEVEL configurato — letto da QUERY MIN LEVEL (0xA2); utilizzato come limite inferiore durante la scalatura di TapHome 0–100 % su DALI arc power.
Power Up LevelLuminosità ripristinata dopo il ripristino dell'alimentazione del bus DALI — letta da QUERY POWER ON LEVEL (0xA3).
System Failure LevelLuminosità adottata quando il bus DALI perde la comunicazione per più di 500 ms — letta da QUERY SYSTEM FAILURE LEVEL (0xA4).
GruppiElenco separato da virgole dei gruppi DALI (0–15) a cui appartiene il gear — decodificato da QUERY GROUPS 0-7 (0xC0) e QUERY GROUPS 8-15 (0xC1); mostra None o ad es. 0,3,7.
Support Lamp FailureSe la lampada / driver supporta il rilevamento dei guasti della lampada — Yes / No / --. Gestisce l'errore Lamp failure! nel readscript periodico.
Support Power FailureSe la lampada / driver supporta il rilevamento dei guasti di alimentazione — Yes / No / --. Gestisce l'errore Power failure! nel readscript periodico.
DALI Version
Bus statistics
Azioni di servizio
Add to GroupAggiunge questo gear a un gruppo DALI (0–15) tramite ADD TO GROUP (0x60+grp) — auto-ripetuto entro 100 ms come richiesto per i comandi di configurazione DALI.
Remove from GroupRimuove questo gear da un gruppo DALI (0–15) tramite REMOVE FROM GROUP (0x70+grp).
Reset to Default SettingsInvia DALI RESET (0x20) — ripristina ogni parametro NVM del gear (livelli max / min / power-on / system-failure, appartenenza al gruppo, scene) al valore predefinito del produttore.
Set Startup LevelsCattura l'arc power corrente e la memorizza come Power On Level e System Failure Level — sequenza STORE ACTUAL LEVEL IN DTR (0x21) → STORE DTR AS POWER ON LEVEL (0x2C) → STORE DTR AS SYSTEM FAILURE LEVEL (0x2D).
Disable fading

Gear 61

Lettura (modulo)
var x := 0; var rx := 0; var y := 0;
if Status > 0
    Status := Status - 1;
    adderror(3, "Gear not responding!");
    return(0);
end

# checkStatus: ReadLevel resets it while the gear answers; statusPoll: QUERY STATUS at least once per 60 runs
checkStatus := checkStatus - 1;
statusPoll := statusPoll - 1;
if checkStatus < 1 or statusPoll < 1
    # an unread answer left in the gateway would be taken for this query: read it away and count it
    x := modbusr(SH, 511, uint16); if (x != 0x8000, cntStale := cntStale + 1);
    modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x90);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    x := modbusr(SH, 511, uint16);
    cntQ := cntQ + 1; if (x = 0x8000, cntNone := cntNone + 1); if (x = 0x20FF, cntColl := cntColl + 1);
    # a single lost answer happens on DALI: ask once more before declaring the gear missing
    if x = 0x8000
        x := modbusr(SH, 511, uint16); if (x != 0x8000, cntStale := cntStale + 1);
        modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x90);
        sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
        x := modbusr(SH, 511, uint16);
        cntQ := cntQ + 1; if (x = 0x8000, cntNone := cntNone + 1); if (x = 0x20FF, cntColl := cntColl + 1);
    end
    if x <= 0xFF
        # a changed failure bit must be read twice the same before it is taken
        if statusSeen = 1 and getbits(x, 0, 2) != getbits(gearStatus, 0, 2)
            y := modbusr(SH, 511, uint16); if (y != 0x8000, cntStale := cntStale + 1);
            modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x90);
            sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
            y := modbusr(SH, 511, uint16);
            cntQ := cntQ + 1; if (y = 0x8000, cntNone := cntNone + 1); if (y = 0x20FF, cntColl := cntColl + 1);
            if y != x
                cntBad := cntBad + 1;
                x := gearStatus;
            end
        end
        if statusSeen = 0
            ignGear := getbit(x, 0);
            ignLamp := getbit(x, 1);
            statusSeen := 1;
        end
        # a bit that clears ends its ignore, so a later failure is raised
        if (getbit(x, 0) = 0, ignGear := 0);
        if (getbit(x, 1) = 0, ignLamp := 0);
        gearStatus := x;
        checkStatus := 60;
        statusPoll := 60;
    else
        if x = 0x8000
            Status := RANDINT(10, 60);
            adderror(3, "Gear not responding!");
            return(0);
        end
    end
end

# messages last one run only, so they are raised from the stored status on every run
if ((getbit(gearStatus, 0) = 1) and (ignGear = 0), adderror(1, "Control gear failure!"));
if ((getbit(gearStatus, 1) = 1) and (ignLamp = 0), adderror(2, "Lamp failure!"));
Inizializzazione
var x := 0; var rx := 0;
# QUERY STATUS 0x90: every reply byte proves the gear is present; 0x8000 = no answer, 0x20FF = bus collision
# an unread answer left in the gateway would be taken for this query: read it away and count it
x := modbusr(SH, 511, uint16); if (x != 0x8000, cntStale := cntStale + 1);
modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x90);
sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
x := modbusr(SH, 511, uint16);
cntQ := cntQ + 1; if (x = 0x8000, cntNone := cntNone + 1); if (x = 0x20FF, cntColl := cntColl + 1);
statusSeen := 0;
if x <= 0xFF
    # failure bits a gear reports from its first answer are its permanent state, not an event: shown, not raised
    gearStatus := x;
    ignGear := getbit(x, 0);
    ignLamp := getbit(x, 1);
    statusSeen := 1;
    Status := 0;
else
    Status := RANDINT(1, 60);
end

if Status = 0
    x := modbusr(SH, 511, uint16); if (x != 0x8000, cntStale := cntStale + 1);
    modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA2);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    x := modbusr(SH, 511, uint16);
    cntQ := cntQ + 1; if (x = 0x8000, cntNone := cntNone + 1); if (x = 0x20FF, cntColl := cntColl + 1);
    if (x <= 0xFE, minLevel := x);

    x := modbusr(SH, 511, uint16); if (x != 0x8000, cntStale := cntStale + 1);
    modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA1);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    x := modbusr(SH, 511, uint16);
    cntQ := cntQ + 1; if (x = 0x8000, cntNone := cntNone + 1); if (x = 0x20FF, cntColl := cntColl + 1);
    if (x <= 0xFE, maxLevel := x);
end
Lettura livello
var x := 0; var rx := 0; var y := 0;
if Status = 0
    if minLevel = 0
        # an unread answer left in the gateway would be taken for this query: read it away and count it
        x := modbusr(SH, 511, uint16); if (x != 0x8000, cntStale := cntStale + 1);
        modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA2);
        sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
        x := modbusr(SH, 511, uint16);
        cntQ := cntQ + 1; if (x = 0x8000, cntNone := cntNone + 1); if (x = 0x20FF, cntColl := cntColl + 1);
        if (x <= 0xFE, minLevel := x);
    end
    x := modbusr(SH, 511, uint16); if (x != 0x8000, cntStale := cntStale + 1);
    modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA0);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    x := modbusr(SH, 511, uint16);
    cntQ := cntQ + 1; if (x = 0x8000, cntNone := cntNone + 1); if (x = 0x20FF, cntColl := cntColl + 1);
    if (x != 0x8000 or rx, checkStatus := 60);
    # 0xFF = MASK, 0x20FF = collision, 0x8000 = no answer: keep the last level instead of a phantom value
    if x > 0xFE
        return(Le);
    end
    # an actual level is 0 or between the gear's min and max: anything else is not this gear's answer
    if x > 0 and x < minLevel
        cntBad := cntBad + 1;
        return(Le);
    end
    # a changed level must be read twice the same before it is taken
    if x != lastRaw
        y := modbusr(SH, 511, uint16); if (y != 0x8000, cntStale := cntStale + 1);
        modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA0);
        sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
        y := modbusr(SH, 511, uint16);
        cntQ := cntQ + 1; if (y = 0x8000, cntNone := cntNone + 1); if (y = 0x20FF, cntColl := cntColl + 1);
        if y != x
            cntBad := cntBad + 1;
            return(Le);
        end
        lastRaw := x;
    end
    return(if(x = 0, 0, linear(x, minLevel, 0.01, maxLevel, 1)));
else
    return(NaN);
end
Scrittura livello
var level := 0;
if(Le > 0, level := round(linear(Le, 0.01, minLevel, 1, maxLevel)));
modbusw(SH, 510, uint16, (ShortAddress << 8) + level );
Attributi di servizio
${xml_short_address}
ShortAddress
${xml_device_type}
var x := 0; var y := 0; var rx := 0; var s := ""; var i := 0;
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x99);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    x := modbusr(SH, 511, uint16);
    if (x < 0xFF, return("DT" + x));
    if x = 0xFF
        while i < 8
            modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA7);
            sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
            y := modbusr(SH, 511, uint16);
            if y < 0xFE
                s := if(s = "", "DT" + y, s + ", DT" + y);
                i := i + 1;
            else
                i := 8;
            end
        loop
        return(if(s = "", "MASK", s));
    end
end

return("--")
Physical Min Level
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x9A);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if (x <= 0xFE, return(round((x / 0xFE) * 100) + " %"));
end

return("--")
Max Level
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA1);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if (x <= 0xFE, return(round((x / 0xFE) * 100) + " %"));
end

return("--")
Min Level
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA2);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if (x <= 0xFE, return(round((x / 0xFE) * 100) + " %"));
end

return("--")
Power Up Level
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA3);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if (x <= 0xFE, return(round((x / 0xFE) * 100) + " %"));
end

return("--")
System Failure Level
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA4);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if (x <= 0xFE, return(round((x / 0xFE) * 100) + " %"));
end

return("--")
${xml_groups}
var x := 0; var rx := 0;
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xC0);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var g1 := modbusr(SH, 511, uint16);
    if (g1 > 0xFF, return("--")); 

    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xC1);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var g2 := modbusr(SH, 511, uint16);
    if (g2 > 0xFF, return("--")); 

    var ret := "";

    if (getbit(g1, 0), ret := ret + "0");
    if (getbit(g1, 1), if (ret = "", ret := "1", ret := ret + ",1"));
    if (getbit(g1, 2), if (ret = "", ret := "2", ret := ret + ",2"));
    if (getbit(g1, 3), if (ret = "", ret := "3", ret := ret + ",3"));
    if (getbit(g1, 4), if (ret = "", ret := "4", ret := ret + ",4"));
    if (getbit(g1, 5), if (ret = "", ret := "5", ret := ret + ",5"));
    if (getbit(g1, 6), if (ret = "", ret := "6", ret := ret + ",6"));
    if (getbit(g1, 7), if (ret = "", ret := "7", ret := ret + ",7"));
    if (getbit(g2, 0), if (ret = "", ret := "8", ret := ret + ",8"));
    if (getbit(g2, 1), if (ret = "", ret := "9", ret := ret + ",9"));
    if (getbit(g2, 2), if (ret = "", ret := "10", ret := ret + ",10"));
    if (getbit(g2, 3), if (ret = "", ret := "11", ret := ret + ",11"));
    if (getbit(g2, 4), if (ret = "", ret := "12", ret := ret + ",12"));
    if (getbit(g2, 5), if (ret = "", ret := "13", ret := ret + ",13"));
    if (getbit(g2, 6), if (ret = "", ret := "14", ret := ret + ",14"));
    if (getbit(g2, 7), if (ret = "", ret := "15", ret := ret + ",15"));

    if (ret = "", return("None"), return(ret));
else
    return("--");
end
DALI Status
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x90);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if x <= 0xFF
        var s := "";
        if (getbit(x, 0), s := if(s = "", "gear failure", s + ", gear failure"));
        if (getbit(x, 1), s := if(s = "", "lamp failure", s + ", lamp failure"));
        if (getbit(x, 2), s := if(s = "", "lamp on", s + ", lamp on"));
        if (getbit(x, 3), s := if(s = "", "limit error", s + ", limit error"));
        if (getbit(x, 4), s := if(s = "", "fade running", s + ", fade running"));
        if (getbit(x, 5), s := if(s = "", "reset state", s + ", reset state"));
        if (getbit(x, 6), s := if(s = "", "missing short address", s + ", missing short address"));
        if (getbit(x, 7), s := if(s = "", "power cycle", s + ", power cycle"));
        var ign := if((ignGear = 1) and (ignLamp = 1), "gear and lamp failure", if(ignGear = 1, "gear failure", if(ignLamp = 1, "lamp failure", "")));
        return(if(s = "", "OK", s) + " (0x" + tostring(x, "X2") + ")" + if(ign = "", "", "; not raised: " + ign + " reported since start"));
    end
end

return("--")
Fade
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA5);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if x <= 0xFF
        var t := getbits(x, 4, 4);
        var ret := if(t = 0, "off", t + " (" + round(sqrt(power(2, t)) * 5) / 10 + " s)");
        modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA8);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
        var e := modbusr(SH, 511, uint16);
        if (t = 0 and e <= 0xFF and e != 0, ret := "extended 0x" + tostring(e, "X2"));
        return("fade time " + ret + ", fade rate " + getbits(x, 0, 4));
    end
end

return("--")
DALI Version
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x97);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if x <= 0xFF
        return(if(x >= 8, "DALI-2 " + getbits(x, 2, 6) + "." + getbits(x, 0, 2), "DALI-1") + " (" + x + ")");
    end
end

return("--")
Bus statistics
return("since start: queries " + cntQ + ", stale answers read away " + cntStale + ", no answer " + cntNone + ", collisions " + cntColl + ", rejected levels " + cntBad)
Azioni di servizio
${xml_add_to_group}
Parametri: Group ID (0–15 grp)
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x60 + grp);
${xml_remove_from_group}
Parametri: Group ID (0–15 grp)
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x70 + grp);
${xml_reset_to_default_settings}
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x20);
${xml_set_startup_levels}
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x21);
sleep(10);
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x2c);
sleep(10);
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x2d);
Disable fading
modbusw(SH, 541, uint16, 0xA300);
sleep(100);
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x2E);
sleep(100);
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x30);
Gear 62 Dimmer Lettura e scrittura

Dispositivo di controllo DALI all'indirizzo breve 62 — dimmer TapHome mappato su DALI arc power 0–100 % tramite H:510 LAMP LEVEL (scrittura) e QUERY ACTUAL LEVEL tramite H:511 (lettura), delimitato dai propri MIN / MAX LEVEL del gear.

Registro: H:511 → H:510 UInt16 Unità: % numeric
Attributi di servizio
Indirizzo breveIndirizzo breve DALI (0–63) target di questo dispositivo — fissato al momento dell'importazione del template e utilizzato nel byte alto di ogni scrittura Modbus.
Device TypeByte device-type DALI restituito da QUERY DEVICE TYPE (0x99) — riporta DT0 (fluorescente), DT6 (driver LED), DT8 (colore / tunable white) ecc., o -- quando non c'è risposta.
Physical Min LevelLivello minimo di dimmerazione imposto dall'hardware riportato dal gear — letto da QUERY PHYSICAL MIN LEVEL (0x9A), in percentuale.
Max LevelDALI MAX LEVEL configurato — letto da QUERY MAX LEVEL (0xA1); utilizzato come limite superiore durante la scalatura di TapHome 0–100 % su DALI arc power.
Min LevelDALI MIN LEVEL configurato — letto da QUERY MIN LEVEL (0xA2); utilizzato come limite inferiore durante la scalatura di TapHome 0–100 % su DALI arc power.
Power Up LevelLuminosità ripristinata dopo il ripristino dell'alimentazione del bus DALI — letta da QUERY POWER ON LEVEL (0xA3).
System Failure LevelLuminosità adottata quando il bus DALI perde la comunicazione per più di 500 ms — letta da QUERY SYSTEM FAILURE LEVEL (0xA4).
GruppiElenco separato da virgole dei gruppi DALI (0–15) a cui appartiene il gear — decodificato da QUERY GROUPS 0-7 (0xC0) e QUERY GROUPS 8-15 (0xC1); mostra None o ad es. 0,3,7.
Support Lamp FailureSe la lampada / driver supporta il rilevamento dei guasti della lampada — Yes / No / --. Gestisce l'errore Lamp failure! nel readscript periodico.
Support Power FailureSe la lampada / driver supporta il rilevamento dei guasti di alimentazione — Yes / No / --. Gestisce l'errore Power failure! nel readscript periodico.
DALI Version
Bus statistics
Azioni di servizio
Add to GroupAggiunge questo gear a un gruppo DALI (0–15) tramite ADD TO GROUP (0x60+grp) — auto-ripetuto entro 100 ms come richiesto per i comandi di configurazione DALI.
Remove from GroupRimuove questo gear da un gruppo DALI (0–15) tramite REMOVE FROM GROUP (0x70+grp).
Reset to Default SettingsInvia DALI RESET (0x20) — ripristina ogni parametro NVM del gear (livelli max / min / power-on / system-failure, appartenenza al gruppo, scene) al valore predefinito del produttore.
Set Startup LevelsCattura l'arc power corrente e la memorizza come Power On Level e System Failure Level — sequenza STORE ACTUAL LEVEL IN DTR (0x21) → STORE DTR AS POWER ON LEVEL (0x2C) → STORE DTR AS SYSTEM FAILURE LEVEL (0x2D).
Disable fading

Gear 62

Lettura (modulo)
var x := 0; var rx := 0; var y := 0;
if Status > 0
    Status := Status - 1;
    adderror(3, "Gear not responding!");
    return(0);
end

# checkStatus: ReadLevel resets it while the gear answers; statusPoll: QUERY STATUS at least once per 60 runs
checkStatus := checkStatus - 1;
statusPoll := statusPoll - 1;
if checkStatus < 1 or statusPoll < 1
    # an unread answer left in the gateway would be taken for this query: read it away and count it
    x := modbusr(SH, 511, uint16); if (x != 0x8000, cntStale := cntStale + 1);
    modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x90);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    x := modbusr(SH, 511, uint16);
    cntQ := cntQ + 1; if (x = 0x8000, cntNone := cntNone + 1); if (x = 0x20FF, cntColl := cntColl + 1);
    # a single lost answer happens on DALI: ask once more before declaring the gear missing
    if x = 0x8000
        x := modbusr(SH, 511, uint16); if (x != 0x8000, cntStale := cntStale + 1);
        modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x90);
        sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
        x := modbusr(SH, 511, uint16);
        cntQ := cntQ + 1; if (x = 0x8000, cntNone := cntNone + 1); if (x = 0x20FF, cntColl := cntColl + 1);
    end
    if x <= 0xFF
        # a changed failure bit must be read twice the same before it is taken
        if statusSeen = 1 and getbits(x, 0, 2) != getbits(gearStatus, 0, 2)
            y := modbusr(SH, 511, uint16); if (y != 0x8000, cntStale := cntStale + 1);
            modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x90);
            sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
            y := modbusr(SH, 511, uint16);
            cntQ := cntQ + 1; if (y = 0x8000, cntNone := cntNone + 1); if (y = 0x20FF, cntColl := cntColl + 1);
            if y != x
                cntBad := cntBad + 1;
                x := gearStatus;
            end
        end
        if statusSeen = 0
            ignGear := getbit(x, 0);
            ignLamp := getbit(x, 1);
            statusSeen := 1;
        end
        # a bit that clears ends its ignore, so a later failure is raised
        if (getbit(x, 0) = 0, ignGear := 0);
        if (getbit(x, 1) = 0, ignLamp := 0);
        gearStatus := x;
        checkStatus := 60;
        statusPoll := 60;
    else
        if x = 0x8000
            Status := RANDINT(10, 60);
            adderror(3, "Gear not responding!");
            return(0);
        end
    end
end

# messages last one run only, so they are raised from the stored status on every run
if ((getbit(gearStatus, 0) = 1) and (ignGear = 0), adderror(1, "Control gear failure!"));
if ((getbit(gearStatus, 1) = 1) and (ignLamp = 0), adderror(2, "Lamp failure!"));
Inizializzazione
var x := 0; var rx := 0;
# QUERY STATUS 0x90: every reply byte proves the gear is present; 0x8000 = no answer, 0x20FF = bus collision
# an unread answer left in the gateway would be taken for this query: read it away and count it
x := modbusr(SH, 511, uint16); if (x != 0x8000, cntStale := cntStale + 1);
modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x90);
sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
x := modbusr(SH, 511, uint16);
cntQ := cntQ + 1; if (x = 0x8000, cntNone := cntNone + 1); if (x = 0x20FF, cntColl := cntColl + 1);
statusSeen := 0;
if x <= 0xFF
    # failure bits a gear reports from its first answer are its permanent state, not an event: shown, not raised
    gearStatus := x;
    ignGear := getbit(x, 0);
    ignLamp := getbit(x, 1);
    statusSeen := 1;
    Status := 0;
else
    Status := RANDINT(1, 60);
end

if Status = 0
    x := modbusr(SH, 511, uint16); if (x != 0x8000, cntStale := cntStale + 1);
    modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA2);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    x := modbusr(SH, 511, uint16);
    cntQ := cntQ + 1; if (x = 0x8000, cntNone := cntNone + 1); if (x = 0x20FF, cntColl := cntColl + 1);
    if (x <= 0xFE, minLevel := x);

    x := modbusr(SH, 511, uint16); if (x != 0x8000, cntStale := cntStale + 1);
    modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA1);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    x := modbusr(SH, 511, uint16);
    cntQ := cntQ + 1; if (x = 0x8000, cntNone := cntNone + 1); if (x = 0x20FF, cntColl := cntColl + 1);
    if (x <= 0xFE, maxLevel := x);
end
Lettura livello
var x := 0; var rx := 0; var y := 0;
if Status = 0
    if minLevel = 0
        # an unread answer left in the gateway would be taken for this query: read it away and count it
        x := modbusr(SH, 511, uint16); if (x != 0x8000, cntStale := cntStale + 1);
        modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA2);
        sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
        x := modbusr(SH, 511, uint16);
        cntQ := cntQ + 1; if (x = 0x8000, cntNone := cntNone + 1); if (x = 0x20FF, cntColl := cntColl + 1);
        if (x <= 0xFE, minLevel := x);
    end
    x := modbusr(SH, 511, uint16); if (x != 0x8000, cntStale := cntStale + 1);
    modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA0);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    x := modbusr(SH, 511, uint16);
    cntQ := cntQ + 1; if (x = 0x8000, cntNone := cntNone + 1); if (x = 0x20FF, cntColl := cntColl + 1);
    if (x != 0x8000 or rx, checkStatus := 60);
    # 0xFF = MASK, 0x20FF = collision, 0x8000 = no answer: keep the last level instead of a phantom value
    if x > 0xFE
        return(Le);
    end
    # an actual level is 0 or between the gear's min and max: anything else is not this gear's answer
    if x > 0 and x < minLevel
        cntBad := cntBad + 1;
        return(Le);
    end
    # a changed level must be read twice the same before it is taken
    if x != lastRaw
        y := modbusr(SH, 511, uint16); if (y != 0x8000, cntStale := cntStale + 1);
        modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA0);
        sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
        y := modbusr(SH, 511, uint16);
        cntQ := cntQ + 1; if (y = 0x8000, cntNone := cntNone + 1); if (y = 0x20FF, cntColl := cntColl + 1);
        if y != x
            cntBad := cntBad + 1;
            return(Le);
        end
        lastRaw := x;
    end
    return(if(x = 0, 0, linear(x, minLevel, 0.01, maxLevel, 1)));
else
    return(NaN);
end
Scrittura livello
var level := 0;
if(Le > 0, level := round(linear(Le, 0.01, minLevel, 1, maxLevel)));
modbusw(SH, 510, uint16, (ShortAddress << 8) + level );
Attributi di servizio
${xml_short_address}
ShortAddress
${xml_device_type}
var x := 0; var y := 0; var rx := 0; var s := ""; var i := 0;
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x99);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    x := modbusr(SH, 511, uint16);
    if (x < 0xFF, return("DT" + x));
    if x = 0xFF
        while i < 8
            modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA7);
            sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
            y := modbusr(SH, 511, uint16);
            if y < 0xFE
                s := if(s = "", "DT" + y, s + ", DT" + y);
                i := i + 1;
            else
                i := 8;
            end
        loop
        return(if(s = "", "MASK", s));
    end
end

return("--")
Physical Min Level
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x9A);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if (x <= 0xFE, return(round((x / 0xFE) * 100) + " %"));
end

return("--")
Max Level
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA1);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if (x <= 0xFE, return(round((x / 0xFE) * 100) + " %"));
end

return("--")
Min Level
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA2);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if (x <= 0xFE, return(round((x / 0xFE) * 100) + " %"));
end

return("--")
Power Up Level
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA3);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if (x <= 0xFE, return(round((x / 0xFE) * 100) + " %"));
end

return("--")
System Failure Level
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA4);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if (x <= 0xFE, return(round((x / 0xFE) * 100) + " %"));
end

return("--")
${xml_groups}
var x := 0; var rx := 0;
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xC0);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var g1 := modbusr(SH, 511, uint16);
    if (g1 > 0xFF, return("--")); 

    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xC1);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var g2 := modbusr(SH, 511, uint16);
    if (g2 > 0xFF, return("--")); 

    var ret := "";

    if (getbit(g1, 0), ret := ret + "0");
    if (getbit(g1, 1), if (ret = "", ret := "1", ret := ret + ",1"));
    if (getbit(g1, 2), if (ret = "", ret := "2", ret := ret + ",2"));
    if (getbit(g1, 3), if (ret = "", ret := "3", ret := ret + ",3"));
    if (getbit(g1, 4), if (ret = "", ret := "4", ret := ret + ",4"));
    if (getbit(g1, 5), if (ret = "", ret := "5", ret := ret + ",5"));
    if (getbit(g1, 6), if (ret = "", ret := "6", ret := ret + ",6"));
    if (getbit(g1, 7), if (ret = "", ret := "7", ret := ret + ",7"));
    if (getbit(g2, 0), if (ret = "", ret := "8", ret := ret + ",8"));
    if (getbit(g2, 1), if (ret = "", ret := "9", ret := ret + ",9"));
    if (getbit(g2, 2), if (ret = "", ret := "10", ret := ret + ",10"));
    if (getbit(g2, 3), if (ret = "", ret := "11", ret := ret + ",11"));
    if (getbit(g2, 4), if (ret = "", ret := "12", ret := ret + ",12"));
    if (getbit(g2, 5), if (ret = "", ret := "13", ret := ret + ",13"));
    if (getbit(g2, 6), if (ret = "", ret := "14", ret := ret + ",14"));
    if (getbit(g2, 7), if (ret = "", ret := "15", ret := ret + ",15"));

    if (ret = "", return("None"), return(ret));
else
    return("--");
end
DALI Status
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x90);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if x <= 0xFF
        var s := "";
        if (getbit(x, 0), s := if(s = "", "gear failure", s + ", gear failure"));
        if (getbit(x, 1), s := if(s = "", "lamp failure", s + ", lamp failure"));
        if (getbit(x, 2), s := if(s = "", "lamp on", s + ", lamp on"));
        if (getbit(x, 3), s := if(s = "", "limit error", s + ", limit error"));
        if (getbit(x, 4), s := if(s = "", "fade running", s + ", fade running"));
        if (getbit(x, 5), s := if(s = "", "reset state", s + ", reset state"));
        if (getbit(x, 6), s := if(s = "", "missing short address", s + ", missing short address"));
        if (getbit(x, 7), s := if(s = "", "power cycle", s + ", power cycle"));
        var ign := if((ignGear = 1) and (ignLamp = 1), "gear and lamp failure", if(ignGear = 1, "gear failure", if(ignLamp = 1, "lamp failure", "")));
        return(if(s = "", "OK", s) + " (0x" + tostring(x, "X2") + ")" + if(ign = "", "", "; not raised: " + ign + " reported since start"));
    end
end

return("--")
Fade
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA5);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if x <= 0xFF
        var t := getbits(x, 4, 4);
        var ret := if(t = 0, "off", t + " (" + round(sqrt(power(2, t)) * 5) / 10 + " s)");
        modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA8);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
        var e := modbusr(SH, 511, uint16);
        if (t = 0 and e <= 0xFF and e != 0, ret := "extended 0x" + tostring(e, "X2"));
        return("fade time " + ret + ", fade rate " + getbits(x, 0, 4));
    end
end

return("--")
DALI Version
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x97);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if x <= 0xFF
        return(if(x >= 8, "DALI-2 " + getbits(x, 2, 6) + "." + getbits(x, 0, 2), "DALI-1") + " (" + x + ")");
    end
end

return("--")
Bus statistics
return("since start: queries " + cntQ + ", stale answers read away " + cntStale + ", no answer " + cntNone + ", collisions " + cntColl + ", rejected levels " + cntBad)
Azioni di servizio
${xml_add_to_group}
Parametri: Group ID (0–15 grp)
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x60 + grp);
${xml_remove_from_group}
Parametri: Group ID (0–15 grp)
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x70 + grp);
${xml_reset_to_default_settings}
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x20);
${xml_set_startup_levels}
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x21);
sleep(10);
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x2c);
sleep(10);
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x2d);
Disable fading
modbusw(SH, 541, uint16, 0xA300);
sleep(100);
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x2E);
sleep(100);
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x30);
Gear 63 Dimmer Lettura e scrittura

Dispositivo di controllo DALI all'indirizzo breve 63 — dimmer TapHome mappato su DALI arc power 0–100 % tramite H:510 LAMP LEVEL (scrittura) e QUERY ACTUAL LEVEL tramite H:511 (lettura), delimitato dai propri MIN / MAX LEVEL del gear.

Registro: H:511 → H:510 UInt16 Unità: % numeric
Attributi di servizio
Indirizzo breveIndirizzo breve DALI (0–63) target di questo dispositivo — fissato al momento dell'importazione del template e utilizzato nel byte alto di ogni scrittura Modbus.
Device TypeByte device-type DALI restituito da QUERY DEVICE TYPE (0x99) — riporta DT0 (fluorescente), DT6 (driver LED), DT8 (colore / tunable white) ecc., o -- quando non c'è risposta.
Physical Min LevelLivello minimo di dimmerazione imposto dall'hardware riportato dal gear — letto da QUERY PHYSICAL MIN LEVEL (0x9A), in percentuale.
Max LevelDALI MAX LEVEL configurato — letto da QUERY MAX LEVEL (0xA1); utilizzato come limite superiore durante la scalatura di TapHome 0–100 % su DALI arc power.
Min LevelDALI MIN LEVEL configurato — letto da QUERY MIN LEVEL (0xA2); utilizzato come limite inferiore durante la scalatura di TapHome 0–100 % su DALI arc power.
Power Up LevelLuminosità ripristinata dopo il ripristino dell'alimentazione del bus DALI — letta da QUERY POWER ON LEVEL (0xA3).
System Failure LevelLuminosità adottata quando il bus DALI perde la comunicazione per più di 500 ms — letta da QUERY SYSTEM FAILURE LEVEL (0xA4).
GruppiElenco separato da virgole dei gruppi DALI (0–15) a cui appartiene il gear — decodificato da QUERY GROUPS 0-7 (0xC0) e QUERY GROUPS 8-15 (0xC1); mostra None o ad es. 0,3,7.
Support Lamp FailureSe la lampada / driver supporta il rilevamento dei guasti della lampada — Yes / No / --. Gestisce l'errore Lamp failure! nel readscript periodico.
Support Power FailureSe la lampada / driver supporta il rilevamento dei guasti di alimentazione — Yes / No / --. Gestisce l'errore Power failure! nel readscript periodico.
DALI Version
Bus statistics
Azioni di servizio
Add to GroupAggiunge questo gear a un gruppo DALI (0–15) tramite ADD TO GROUP (0x60+grp) — auto-ripetuto entro 100 ms come richiesto per i comandi di configurazione DALI.
Remove from GroupRimuove questo gear da un gruppo DALI (0–15) tramite REMOVE FROM GROUP (0x70+grp).
Reset to Default SettingsInvia DALI RESET (0x20) — ripristina ogni parametro NVM del gear (livelli max / min / power-on / system-failure, appartenenza al gruppo, scene) al valore predefinito del produttore.
Set Startup LevelsCattura l'arc power corrente e la memorizza come Power On Level e System Failure Level — sequenza STORE ACTUAL LEVEL IN DTR (0x21) → STORE DTR AS POWER ON LEVEL (0x2C) → STORE DTR AS SYSTEM FAILURE LEVEL (0x2D).
Disable fading

Gear 63

Lettura (modulo)
var x := 0; var rx := 0; var y := 0;
if Status > 0
    Status := Status - 1;
    adderror(3, "Gear not responding!");
    return(0);
end

# checkStatus: ReadLevel resets it while the gear answers; statusPoll: QUERY STATUS at least once per 60 runs
checkStatus := checkStatus - 1;
statusPoll := statusPoll - 1;
if checkStatus < 1 or statusPoll < 1
    # an unread answer left in the gateway would be taken for this query: read it away and count it
    x := modbusr(SH, 511, uint16); if (x != 0x8000, cntStale := cntStale + 1);
    modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x90);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    x := modbusr(SH, 511, uint16);
    cntQ := cntQ + 1; if (x = 0x8000, cntNone := cntNone + 1); if (x = 0x20FF, cntColl := cntColl + 1);
    # a single lost answer happens on DALI: ask once more before declaring the gear missing
    if x = 0x8000
        x := modbusr(SH, 511, uint16); if (x != 0x8000, cntStale := cntStale + 1);
        modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x90);
        sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
        x := modbusr(SH, 511, uint16);
        cntQ := cntQ + 1; if (x = 0x8000, cntNone := cntNone + 1); if (x = 0x20FF, cntColl := cntColl + 1);
    end
    if x <= 0xFF
        # a changed failure bit must be read twice the same before it is taken
        if statusSeen = 1 and getbits(x, 0, 2) != getbits(gearStatus, 0, 2)
            y := modbusr(SH, 511, uint16); if (y != 0x8000, cntStale := cntStale + 1);
            modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x90);
            sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
            y := modbusr(SH, 511, uint16);
            cntQ := cntQ + 1; if (y = 0x8000, cntNone := cntNone + 1); if (y = 0x20FF, cntColl := cntColl + 1);
            if y != x
                cntBad := cntBad + 1;
                x := gearStatus;
            end
        end
        if statusSeen = 0
            ignGear := getbit(x, 0);
            ignLamp := getbit(x, 1);
            statusSeen := 1;
        end
        # a bit that clears ends its ignore, so a later failure is raised
        if (getbit(x, 0) = 0, ignGear := 0);
        if (getbit(x, 1) = 0, ignLamp := 0);
        gearStatus := x;
        checkStatus := 60;
        statusPoll := 60;
    else
        if x = 0x8000
            Status := RANDINT(10, 60);
            adderror(3, "Gear not responding!");
            return(0);
        end
    end
end

# messages last one run only, so they are raised from the stored status on every run
if ((getbit(gearStatus, 0) = 1) and (ignGear = 0), adderror(1, "Control gear failure!"));
if ((getbit(gearStatus, 1) = 1) and (ignLamp = 0), adderror(2, "Lamp failure!"));
Inizializzazione
var x := 0; var rx := 0;
# QUERY STATUS 0x90: every reply byte proves the gear is present; 0x8000 = no answer, 0x20FF = bus collision
# an unread answer left in the gateway would be taken for this query: read it away and count it
x := modbusr(SH, 511, uint16); if (x != 0x8000, cntStale := cntStale + 1);
modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x90);
sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
x := modbusr(SH, 511, uint16);
cntQ := cntQ + 1; if (x = 0x8000, cntNone := cntNone + 1); if (x = 0x20FF, cntColl := cntColl + 1);
statusSeen := 0;
if x <= 0xFF
    # failure bits a gear reports from its first answer are its permanent state, not an event: shown, not raised
    gearStatus := x;
    ignGear := getbit(x, 0);
    ignLamp := getbit(x, 1);
    statusSeen := 1;
    Status := 0;
else
    Status := RANDINT(1, 60);
end

if Status = 0
    x := modbusr(SH, 511, uint16); if (x != 0x8000, cntStale := cntStale + 1);
    modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA2);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    x := modbusr(SH, 511, uint16);
    cntQ := cntQ + 1; if (x = 0x8000, cntNone := cntNone + 1); if (x = 0x20FF, cntColl := cntColl + 1);
    if (x <= 0xFE, minLevel := x);

    x := modbusr(SH, 511, uint16); if (x != 0x8000, cntStale := cntStale + 1);
    modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA1);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    x := modbusr(SH, 511, uint16);
    cntQ := cntQ + 1; if (x = 0x8000, cntNone := cntNone + 1); if (x = 0x20FF, cntColl := cntColl + 1);
    if (x <= 0xFE, maxLevel := x);
end
Lettura livello
var x := 0; var rx := 0; var y := 0;
if Status = 0
    if minLevel = 0
        # an unread answer left in the gateway would be taken for this query: read it away and count it
        x := modbusr(SH, 511, uint16); if (x != 0x8000, cntStale := cntStale + 1);
        modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA2);
        sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
        x := modbusr(SH, 511, uint16);
        cntQ := cntQ + 1; if (x = 0x8000, cntNone := cntNone + 1); if (x = 0x20FF, cntColl := cntColl + 1);
        if (x <= 0xFE, minLevel := x);
    end
    x := modbusr(SH, 511, uint16); if (x != 0x8000, cntStale := cntStale + 1);
    modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA0);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    x := modbusr(SH, 511, uint16);
    cntQ := cntQ + 1; if (x = 0x8000, cntNone := cntNone + 1); if (x = 0x20FF, cntColl := cntColl + 1);
    if (x != 0x8000 or rx, checkStatus := 60);
    # 0xFF = MASK, 0x20FF = collision, 0x8000 = no answer: keep the last level instead of a phantom value
    if x > 0xFE
        return(Le);
    end
    # an actual level is 0 or between the gear's min and max: anything else is not this gear's answer
    if x > 0 and x < minLevel
        cntBad := cntBad + 1;
        return(Le);
    end
    # a changed level must be read twice the same before it is taken
    if x != lastRaw
        y := modbusr(SH, 511, uint16); if (y != 0x8000, cntStale := cntStale + 1);
        modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA0);
        sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
        y := modbusr(SH, 511, uint16);
        cntQ := cntQ + 1; if (y = 0x8000, cntNone := cntNone + 1); if (y = 0x20FF, cntColl := cntColl + 1);
        if y != x
            cntBad := cntBad + 1;
            return(Le);
        end
        lastRaw := x;
    end
    return(if(x = 0, 0, linear(x, minLevel, 0.01, maxLevel, 1)));
else
    return(NaN);
end
Scrittura livello
var level := 0;
if(Le > 0, level := round(linear(Le, 0.01, minLevel, 1, maxLevel)));
modbusw(SH, 510, uint16, (ShortAddress << 8) + level );
Attributi di servizio
${xml_short_address}
ShortAddress
${xml_device_type}
var x := 0; var y := 0; var rx := 0; var s := ""; var i := 0;
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x99);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    x := modbusr(SH, 511, uint16);
    if (x < 0xFF, return("DT" + x));
    if x = 0xFF
        while i < 8
            modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA7);
            sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
            y := modbusr(SH, 511, uint16);
            if y < 0xFE
                s := if(s = "", "DT" + y, s + ", DT" + y);
                i := i + 1;
            else
                i := 8;
            end
        loop
        return(if(s = "", "MASK", s));
    end
end

return("--")
Physical Min Level
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x9A);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if (x <= 0xFE, return(round((x / 0xFE) * 100) + " %"));
end

return("--")
Max Level
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA1);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if (x <= 0xFE, return(round((x / 0xFE) * 100) + " %"));
end

return("--")
Min Level
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA2);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if (x <= 0xFE, return(round((x / 0xFE) * 100) + " %"));
end

return("--")
Power Up Level
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA3);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if (x <= 0xFE, return(round((x / 0xFE) * 100) + " %"));
end

return("--")
System Failure Level
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA4);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if (x <= 0xFE, return(round((x / 0xFE) * 100) + " %"));
end

return("--")
${xml_groups}
var x := 0; var rx := 0;
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xC0);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var g1 := modbusr(SH, 511, uint16);
    if (g1 > 0xFF, return("--")); 

    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xC1);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var g2 := modbusr(SH, 511, uint16);
    if (g2 > 0xFF, return("--")); 

    var ret := "";

    if (getbit(g1, 0), ret := ret + "0");
    if (getbit(g1, 1), if (ret = "", ret := "1", ret := ret + ",1"));
    if (getbit(g1, 2), if (ret = "", ret := "2", ret := ret + ",2"));
    if (getbit(g1, 3), if (ret = "", ret := "3", ret := ret + ",3"));
    if (getbit(g1, 4), if (ret = "", ret := "4", ret := ret + ",4"));
    if (getbit(g1, 5), if (ret = "", ret := "5", ret := ret + ",5"));
    if (getbit(g1, 6), if (ret = "", ret := "6", ret := ret + ",6"));
    if (getbit(g1, 7), if (ret = "", ret := "7", ret := ret + ",7"));
    if (getbit(g2, 0), if (ret = "", ret := "8", ret := ret + ",8"));
    if (getbit(g2, 1), if (ret = "", ret := "9", ret := ret + ",9"));
    if (getbit(g2, 2), if (ret = "", ret := "10", ret := ret + ",10"));
    if (getbit(g2, 3), if (ret = "", ret := "11", ret := ret + ",11"));
    if (getbit(g2, 4), if (ret = "", ret := "12", ret := ret + ",12"));
    if (getbit(g2, 5), if (ret = "", ret := "13", ret := ret + ",13"));
    if (getbit(g2, 6), if (ret = "", ret := "14", ret := ret + ",14"));
    if (getbit(g2, 7), if (ret = "", ret := "15", ret := ret + ",15"));

    if (ret = "", return("None"), return(ret));
else
    return("--");
end
DALI Status
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x90);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if x <= 0xFF
        var s := "";
        if (getbit(x, 0), s := if(s = "", "gear failure", s + ", gear failure"));
        if (getbit(x, 1), s := if(s = "", "lamp failure", s + ", lamp failure"));
        if (getbit(x, 2), s := if(s = "", "lamp on", s + ", lamp on"));
        if (getbit(x, 3), s := if(s = "", "limit error", s + ", limit error"));
        if (getbit(x, 4), s := if(s = "", "fade running", s + ", fade running"));
        if (getbit(x, 5), s := if(s = "", "reset state", s + ", reset state"));
        if (getbit(x, 6), s := if(s = "", "missing short address", s + ", missing short address"));
        if (getbit(x, 7), s := if(s = "", "power cycle", s + ", power cycle"));
        var ign := if((ignGear = 1) and (ignLamp = 1), "gear and lamp failure", if(ignGear = 1, "gear failure", if(ignLamp = 1, "lamp failure", "")));
        return(if(s = "", "OK", s) + " (0x" + tostring(x, "X2") + ")" + if(ign = "", "", "; not raised: " + ign + " reported since start"));
    end
end

return("--")
Fade
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA5);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if x <= 0xFF
        var t := getbits(x, 4, 4);
        var ret := if(t = 0, "off", t + " (" + round(sqrt(power(2, t)) * 5) / 10 + " s)");
        modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0xA8);
    sleep(5); rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
        var e := modbusr(SH, 511, uint16);
        if (t = 0 and e <= 0xFF and e != 0, ret := "extended 0x" + tostring(e, "X2"));
        return("fade time " + ret + ", fade rate " + getbits(x, 0, 4));
    end
end

return("--")
DALI Version
if Status = 0
    modbusr(SH, 511, uint16); modbusw(SH, 511, uint16, (ShortAddress << 8) + 0x97);
    sleep(5); var rx := getbits(modbusr(SH, 550, uint16), 0, 2); if(rx, 0, sleep(50));
    var x := modbusr(SH, 511, uint16);
    if x <= 0xFF
        return(if(x >= 8, "DALI-2 " + getbits(x, 2, 6) + "." + getbits(x, 0, 2), "DALI-1") + " (" + x + ")");
    end
end

return("--")
Bus statistics
return("since start: queries " + cntQ + ", stale answers read away " + cntStale + ", no answer " + cntNone + ", collisions " + cntColl + ", rejected levels " + cntBad)
Azioni di servizio
${xml_add_to_group}
Parametri: Group ID (0–15 grp)
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x60 + grp);
${xml_remove_from_group}
Parametri: Group ID (0–15 grp)
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x70 + grp);
${xml_reset_to_default_settings}
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x20);
${xml_set_startup_levels}
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x21);
sleep(10);
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x2c);
sleep(10);
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x2d);
Disable fading
modbusw(SH, 541, uint16, 0xA300);
sleep(100);
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x2E);
sleep(100);
modbusw(SH, 512, uint16, (ShortAddress << 8) + 0x30);
Group 0 Dimmer Lettura e scrittura

Gruppo broadcast DALI 0 (0–15) — dimmer TapHome write-only che broadcasta un singolo valore arc-power a ogni gear in questo gruppo tramite H:520 GROUP LEVEL. Il bus non riecheggia i livelli di gruppo, quindi TapHome mantiene l'ultimo valore scritto.

UInt16 Unità: % numeric
Azioni di servizio
Add All Lamps to GroupBroadcasta ADD TO GROUP tramite H:532 ALL COMMAND + REPEAT — ogni gear sul bus si unisce a questo gruppo indipendentemente dal suo indirizzo breve corrente.
Remove All Lamps from GroupBroadcasta REMOVE FROM GROUP tramite H:532 ALL COMMAND + REPEAT — ogni gear sul bus lascia questo gruppo.

Group 0

Scrittura livello
var GroupAddress := 0;
modbusw(SH, 520, uint16, (GroupAddress << 8) + (Le * 0xFE));
Azioni di servizio
${xml_add_to_group_all_lamps}
var GroupAddress := 0;
modbusw(SH, 532, uint16, 0x60 + GroupAddress)
${xml_remove_from_group_all_lamps}
var GroupAddress := 0;
modbusw(SH, 532, uint16, 0x70 + GroupAddress)
Group 1 Dimmer Lettura e scrittura

Gruppo broadcast DALI 1 (0–15) — dimmer TapHome write-only che broadcasta un singolo valore arc-power a ogni gear in questo gruppo tramite H:520 GROUP LEVEL. Il bus non riecheggia i livelli di gruppo, quindi TapHome mantiene l'ultimo valore scritto.

UInt16 Unità: % numeric
Azioni di servizio
Add All Lamps to GroupBroadcasta ADD TO GROUP tramite H:532 ALL COMMAND + REPEAT — ogni gear sul bus si unisce a questo gruppo indipendentemente dal suo indirizzo breve corrente.
Remove All Lamps from GroupBroadcasta REMOVE FROM GROUP tramite H:532 ALL COMMAND + REPEAT — ogni gear sul bus lascia questo gruppo.

Group 1

Scrittura livello
var GroupAddress := 1;
modbusw(SH, 520, uint16, (GroupAddress << 8) + (Le * 0xFE));
Azioni di servizio
${xml_add_to_group_all_lamps}
var GroupAddress := 1;
modbusw(SH, 532, uint16, 0x60 + GroupAddress)
${xml_remove_from_group_all_lamps}
var GroupAddress := 1;
modbusw(SH, 532, uint16, 0x70 + GroupAddress)
Group 2 Dimmer Lettura e scrittura

Gruppo broadcast DALI 2 (0–15) — dimmer TapHome write-only che broadcasta un singolo valore arc-power a ogni gear in questo gruppo tramite H:520 GROUP LEVEL. Il bus non riecheggia i livelli di gruppo, quindi TapHome mantiene l'ultimo valore scritto.

UInt16 Unità: % numeric
Azioni di servizio
Add All Lamps to GroupBroadcasta ADD TO GROUP tramite H:532 ALL COMMAND + REPEAT — ogni gear sul bus si unisce a questo gruppo indipendentemente dal suo indirizzo breve corrente.
Remove All Lamps from GroupBroadcasta REMOVE FROM GROUP tramite H:532 ALL COMMAND + REPEAT — ogni gear sul bus lascia questo gruppo.

Group 2

Scrittura livello
var GroupAddress := 2;
modbusw(SH, 520, uint16, (GroupAddress << 8) + (Le * 0xFE));
Azioni di servizio
${xml_add_to_group_all_lamps}
var GroupAddress := 2;
modbusw(SH, 532, uint16, 0x60 + GroupAddress)
${xml_remove_from_group_all_lamps}
var GroupAddress := 2;
modbusw(SH, 532, uint16, 0x70 + GroupAddress)
Group 3 Dimmer Lettura e scrittura

Gruppo broadcast DALI 3 (0–15) — dimmer TapHome write-only che broadcasta un singolo valore arc-power a ogni gear in questo gruppo tramite H:520 GROUP LEVEL. Il bus non riecheggia i livelli di gruppo, quindi TapHome mantiene l'ultimo valore scritto.

UInt16 Unità: % numeric
Azioni di servizio
Add All Lamps to GroupBroadcasta ADD TO GROUP tramite H:532 ALL COMMAND + REPEAT — ogni gear sul bus si unisce a questo gruppo indipendentemente dal suo indirizzo breve corrente.
Remove All Lamps from GroupBroadcasta REMOVE FROM GROUP tramite H:532 ALL COMMAND + REPEAT — ogni gear sul bus lascia questo gruppo.

Group 3

Scrittura livello
var GroupAddress := 3;
modbusw(SH, 520, uint16, (GroupAddress << 8) + (Le * 0xFE));
Azioni di servizio
${xml_add_to_group_all_lamps}
var GroupAddress := 3;
modbusw(SH, 532, uint16, 0x60 + GroupAddress)
${xml_remove_from_group_all_lamps}
var GroupAddress := 3;
modbusw(SH, 532, uint16, 0x70 + GroupAddress)
Group 4 Dimmer Lettura e scrittura

Gruppo broadcast DALI 4 (0–15) — dimmer TapHome write-only che broadcasta un singolo valore arc-power a ogni gear in questo gruppo tramite H:520 GROUP LEVEL. Il bus non riecheggia i livelli di gruppo, quindi TapHome mantiene l'ultimo valore scritto.

UInt16 Unità: % numeric
Azioni di servizio
Add All Lamps to GroupBroadcasta ADD TO GROUP tramite H:532 ALL COMMAND + REPEAT — ogni gear sul bus si unisce a questo gruppo indipendentemente dal suo indirizzo breve corrente.
Remove All Lamps from GroupBroadcasta REMOVE FROM GROUP tramite H:532 ALL COMMAND + REPEAT — ogni gear sul bus lascia questo gruppo.

Group 4

Scrittura livello
var GroupAddress := 4;
modbusw(SH, 520, uint16, (GroupAddress << 8) + (Le * 0xFE));
Azioni di servizio
${xml_add_to_group_all_lamps}
var GroupAddress := 4;
modbusw(SH, 532, uint16, 0x60 + GroupAddress)
${xml_remove_from_group_all_lamps}
var GroupAddress := 4;
modbusw(SH, 532, uint16, 0x70 + GroupAddress)
Group 5 Dimmer Lettura e scrittura

Gruppo broadcast DALI 5 (0–15) — dimmer TapHome write-only che broadcasta un singolo valore arc-power a ogni gear in questo gruppo tramite H:520 GROUP LEVEL. Il bus non riecheggia i livelli di gruppo, quindi TapHome mantiene l'ultimo valore scritto.

UInt16 Unità: % numeric
Azioni di servizio
Add All Lamps to GroupBroadcasta ADD TO GROUP tramite H:532 ALL COMMAND + REPEAT — ogni gear sul bus si unisce a questo gruppo indipendentemente dal suo indirizzo breve corrente.
Remove All Lamps from GroupBroadcasta REMOVE FROM GROUP tramite H:532 ALL COMMAND + REPEAT — ogni gear sul bus lascia questo gruppo.

Group 5

Scrittura livello
var GroupAddress := 5;
modbusw(SH, 520, uint16, (GroupAddress << 8) + (Le * 0xFE));
Azioni di servizio
${xml_add_to_group_all_lamps}
var GroupAddress := 5;
modbusw(SH, 532, uint16, 0x60 + GroupAddress)
${xml_remove_from_group_all_lamps}
var GroupAddress := 5;
modbusw(SH, 532, uint16, 0x70 + GroupAddress)
Group 6 Dimmer Lettura e scrittura

Gruppo broadcast DALI 6 (0–15) — dimmer TapHome write-only che broadcasta un singolo valore arc-power a ogni gear in questo gruppo tramite H:520 GROUP LEVEL. Il bus non riecheggia i livelli di gruppo, quindi TapHome mantiene l'ultimo valore scritto.

UInt16 Unità: % numeric
Azioni di servizio
Add All Lamps to GroupBroadcasta ADD TO GROUP tramite H:532 ALL COMMAND + REPEAT — ogni gear sul bus si unisce a questo gruppo indipendentemente dal suo indirizzo breve corrente.
Remove All Lamps from GroupBroadcasta REMOVE FROM GROUP tramite H:532 ALL COMMAND + REPEAT — ogni gear sul bus lascia questo gruppo.

Group 6

Scrittura livello
var GroupAddress := 6;
modbusw(SH, 520, uint16, (GroupAddress << 8) + (Le * 0xFE));
Azioni di servizio
${xml_add_to_group_all_lamps}
var GroupAddress := 6;
modbusw(SH, 532, uint16, 0x60 + GroupAddress)
${xml_remove_from_group_all_lamps}
var GroupAddress := 6;
modbusw(SH, 532, uint16, 0x70 + GroupAddress)
Group 7 Dimmer Lettura e scrittura

Gruppo broadcast DALI 7 (0–15) — dimmer TapHome write-only che broadcasta un singolo valore arc-power a ogni gear in questo gruppo tramite H:520 GROUP LEVEL. Il bus non riecheggia i livelli di gruppo, quindi TapHome mantiene l'ultimo valore scritto.

UInt16 Unità: % numeric
Azioni di servizio
Add All Lamps to GroupBroadcasta ADD TO GROUP tramite H:532 ALL COMMAND + REPEAT — ogni gear sul bus si unisce a questo gruppo indipendentemente dal suo indirizzo breve corrente.
Remove All Lamps from GroupBroadcasta REMOVE FROM GROUP tramite H:532 ALL COMMAND + REPEAT — ogni gear sul bus lascia questo gruppo.

Group 7

Scrittura livello
var GroupAddress := 7;
modbusw(SH, 520, uint16, (GroupAddress << 8) + (Le * 0xFE));
Azioni di servizio
${xml_add_to_group_all_lamps}
var GroupAddress := 7;
modbusw(SH, 532, uint16, 0x60 + GroupAddress)
${xml_remove_from_group_all_lamps}
var GroupAddress := 7;
modbusw(SH, 532, uint16, 0x70 + GroupAddress)
Group 8 Dimmer Lettura e scrittura

Gruppo broadcast DALI 8 (0–15) — dimmer TapHome write-only che broadcasta un singolo valore arc-power a ogni gear in questo gruppo tramite H:520 GROUP LEVEL. Il bus non riecheggia i livelli di gruppo, quindi TapHome mantiene l'ultimo valore scritto.

UInt16 Unità: % numeric
Azioni di servizio
Add All Lamps to GroupBroadcasta ADD TO GROUP tramite H:532 ALL COMMAND + REPEAT — ogni gear sul bus si unisce a questo gruppo indipendentemente dal suo indirizzo breve corrente.
Remove All Lamps from GroupBroadcasta REMOVE FROM GROUP tramite H:532 ALL COMMAND + REPEAT — ogni gear sul bus lascia questo gruppo.

Group 8

Scrittura livello
var GroupAddress := 8;
modbusw(SH, 520, uint16, (GroupAddress << 8) + (Le * 0xFE));
Azioni di servizio
${xml_add_to_group_all_lamps}
var GroupAddress := 8;
modbusw(SH, 532, uint16, 0x60 + GroupAddress)
${xml_remove_from_group_all_lamps}
var GroupAddress := 8;
modbusw(SH, 532, uint16, 0x70 + GroupAddress)
Group 9 Dimmer Lettura e scrittura

Gruppo broadcast DALI 9 (0–15) — dimmer TapHome write-only che broadcasta un singolo valore arc-power a ogni gear in questo gruppo tramite H:520 GROUP LEVEL. Il bus non riecheggia i livelli di gruppo, quindi TapHome mantiene l'ultimo valore scritto.

UInt16 Unità: % numeric
Azioni di servizio
Add All Lamps to GroupBroadcasta ADD TO GROUP tramite H:532 ALL COMMAND + REPEAT — ogni gear sul bus si unisce a questo gruppo indipendentemente dal suo indirizzo breve corrente.
Remove All Lamps from GroupBroadcasta REMOVE FROM GROUP tramite H:532 ALL COMMAND + REPEAT — ogni gear sul bus lascia questo gruppo.

Group 9

Scrittura livello
var GroupAddress := 9;
modbusw(SH, 520, uint16, (GroupAddress << 8) + (Le * 0xFE));
Azioni di servizio
${xml_add_to_group_all_lamps}
var GroupAddress := 9;
modbusw(SH, 532, uint16, 0x60 + GroupAddress)
${xml_remove_from_group_all_lamps}
var GroupAddress := 9;
modbusw(SH, 532, uint16, 0x70 + GroupAddress)
Group 10 Dimmer Lettura e scrittura

Gruppo broadcast DALI 10 (0–15) — dimmer TapHome write-only che broadcasta un singolo valore arc-power a ogni gear in questo gruppo tramite H:520 GROUP LEVEL. Il bus non riecheggia i livelli di gruppo, quindi TapHome mantiene l'ultimo valore scritto.

UInt16 Unità: % numeric
Azioni di servizio
Add All Lamps to GroupBroadcasta ADD TO GROUP tramite H:532 ALL COMMAND + REPEAT — ogni gear sul bus si unisce a questo gruppo indipendentemente dal suo indirizzo breve corrente.
Remove All Lamps from GroupBroadcasta REMOVE FROM GROUP tramite H:532 ALL COMMAND + REPEAT — ogni gear sul bus lascia questo gruppo.

Group 10

Scrittura livello
var GroupAddress := 10;
modbusw(SH, 520, uint16, (GroupAddress << 8) + (Le * 0xFE));
Azioni di servizio
${xml_add_to_group_all_lamps}
var GroupAddress := 10;
modbusw(SH, 532, uint16, 0x60 + GroupAddress)
${xml_remove_from_group_all_lamps}
var GroupAddress := 10;
modbusw(SH, 532, uint16, 0x70 + GroupAddress)
Group 11 Dimmer Lettura e scrittura

Gruppo broadcast DALI 11 (0–15) — dimmer TapHome write-only che broadcasta un singolo valore arc-power a ogni gear in questo gruppo tramite H:520 GROUP LEVEL. Il bus non riecheggia i livelli di gruppo, quindi TapHome mantiene l'ultimo valore scritto.

UInt16 Unità: % numeric
Azioni di servizio
Add All Lamps to GroupBroadcasta ADD TO GROUP tramite H:532 ALL COMMAND + REPEAT — ogni gear sul bus si unisce a questo gruppo indipendentemente dal suo indirizzo breve corrente.
Remove All Lamps from GroupBroadcasta REMOVE FROM GROUP tramite H:532 ALL COMMAND + REPEAT — ogni gear sul bus lascia questo gruppo.

Group 11

Scrittura livello
var GroupAddress := 11;
modbusw(SH, 520, uint16, (GroupAddress << 8) + (Le * 0xFE));
Azioni di servizio
${xml_add_to_group_all_lamps}
var GroupAddress := 11;
modbusw(SH, 532, uint16, 0x60 + GroupAddress)
${xml_remove_from_group_all_lamps}
var GroupAddress := 11;
modbusw(SH, 532, uint16, 0x70 + GroupAddress)
Group 12 Dimmer Lettura e scrittura

Gruppo broadcast DALI 12 (0–15) — dimmer TapHome write-only che broadcasta un singolo valore arc-power a ogni gear in questo gruppo tramite H:520 GROUP LEVEL. Il bus non riecheggia i livelli di gruppo, quindi TapHome mantiene l'ultimo valore scritto.

UInt16 Unità: % numeric
Azioni di servizio
Add All Lamps to GroupBroadcasta ADD TO GROUP tramite H:532 ALL COMMAND + REPEAT — ogni gear sul bus si unisce a questo gruppo indipendentemente dal suo indirizzo breve corrente.
Remove All Lamps from GroupBroadcasta REMOVE FROM GROUP tramite H:532 ALL COMMAND + REPEAT — ogni gear sul bus lascia questo gruppo.

Group 12

Scrittura livello
var GroupAddress := 12;
modbusw(SH, 520, uint16, (GroupAddress << 8) + (Le * 0xFE));
Azioni di servizio
${xml_add_to_group_all_lamps}
var GroupAddress := 12;
modbusw(SH, 532, uint16, 0x60 + GroupAddress)
${xml_remove_from_group_all_lamps}
var GroupAddress := 12;
modbusw(SH, 532, uint16, 0x70 + GroupAddress)
Group 13 Dimmer Lettura e scrittura

Gruppo broadcast DALI 13 (0–15) — dimmer TapHome write-only che broadcasta un singolo valore arc-power a ogni gear in questo gruppo tramite H:520 GROUP LEVEL. Il bus non riecheggia i livelli di gruppo, quindi TapHome mantiene l'ultimo valore scritto.

UInt16 Unità: % numeric
Azioni di servizio
Add All Lamps to GroupBroadcasta ADD TO GROUP tramite H:532 ALL COMMAND + REPEAT — ogni gear sul bus si unisce a questo gruppo indipendentemente dal suo indirizzo breve corrente.
Remove All Lamps from GroupBroadcasta REMOVE FROM GROUP tramite H:532 ALL COMMAND + REPEAT — ogni gear sul bus lascia questo gruppo.

Group 13

Scrittura livello
var GroupAddress := 13;
modbusw(SH, 520, uint16, (GroupAddress << 8) + (Le * 0xFE));
Azioni di servizio
${xml_add_to_group_all_lamps}
var GroupAddress := 13;
modbusw(SH, 532, uint16, 0x60 + GroupAddress)
${xml_remove_from_group_all_lamps}
var GroupAddress := 13;
modbusw(SH, 532, uint16, 0x70 + GroupAddress)
Group 14 Dimmer Lettura e scrittura

Gruppo broadcast DALI 14 (0–15) — dimmer TapHome write-only che broadcasta un singolo valore arc-power a ogni gear in questo gruppo tramite H:520 GROUP LEVEL. Il bus non riecheggia i livelli di gruppo, quindi TapHome mantiene l'ultimo valore scritto.

UInt16 Unità: % numeric
Azioni di servizio
Add All Lamps to GroupBroadcasta ADD TO GROUP tramite H:532 ALL COMMAND + REPEAT — ogni gear sul bus si unisce a questo gruppo indipendentemente dal suo indirizzo breve corrente.
Remove All Lamps from GroupBroadcasta REMOVE FROM GROUP tramite H:532 ALL COMMAND + REPEAT — ogni gear sul bus lascia questo gruppo.

Group 14

Scrittura livello
var GroupAddress := 14;
modbusw(SH, 520, uint16, (GroupAddress << 8) + (Le * 0xFE));
Azioni di servizio
${xml_add_to_group_all_lamps}
var GroupAddress := 14;
modbusw(SH, 532, uint16, 0x60 + GroupAddress)
${xml_remove_from_group_all_lamps}
var GroupAddress := 14;
modbusw(SH, 532, uint16, 0x70 + GroupAddress)
Group 15 Dimmer Lettura e scrittura

Gruppo broadcast DALI 15 (0–15) — dimmer TapHome write-only che broadcasta un singolo valore arc-power a ogni gear in questo gruppo tramite H:520 GROUP LEVEL. Il bus non riecheggia i livelli di gruppo, quindi TapHome mantiene l'ultimo valore scritto.

UInt16 Unità: % numeric
Azioni di servizio
Add All Lamps to GroupBroadcasta ADD TO GROUP tramite H:532 ALL COMMAND + REPEAT — ogni gear sul bus si unisce a questo gruppo indipendentemente dal suo indirizzo breve corrente.
Remove All Lamps from GroupBroadcasta REMOVE FROM GROUP tramite H:532 ALL COMMAND + REPEAT — ogni gear sul bus lascia questo gruppo.

Group 15

Scrittura livello
var GroupAddress := 15;
modbusw(SH, 520, uint16, (GroupAddress << 8) + (Le * 0xFE));
Azioni di servizio
${xml_add_to_group_all_lamps}
var GroupAddress := 15;
modbusw(SH, 532, uint16, 0x60 + GroupAddress)
${xml_remove_from_group_all_lamps}
var GroupAddress := 15;
modbusw(SH, 532, uint16, 0x70 + GroupAddress)
Connessione: Modbus RTU • 9600 baud• 8N1 • Slave ID: $[SlaveId]
Possibili miglioramenti (23)
  • H:531 ALL COMMAND (broadcast DALI command) — Single-shot broadcast DALI command (no repeat). Template uses H:532 (ALL COMMAND + REPEAT) for group membership but never exposes plain ALL OFF / ALL ON / ALL ARC POWER as a service action — turn-on/off-all are not present (sibling daliconfig template has them via H:530)
  • H:530 ALL LEVEL (broadcast arc power) — Sets brightness for every gear in one Modbus write. Convenient 'turn off all lamps' / 'turn on all lamps' shortcut — implemented in the sibling daliconfig template, missing in this operational template
  • H:521 GROUP COMMAND (per-group DALI command) — Per-group DALI command (single-shot). Could expose group-level OFF / RECALL MIN / RECALL MAX / GO TO SCENE as service actions on each Group device, but template only writes H:520 GROUP LEVEL
  • H:522 GROUP COMMAND + REPEAT — Per-group DALI configuration command (auto-repeated within 100 ms). Required for STORE DTR AS GROUP SCENE etc. — not exposed as a service action
  • H:541 DIRECT 16-BIT FRAME — Raw DALI 1.0 frame send. Used by sibling daliconfig template for the DALI 2.0 random-addressing algorithm; not needed for runtime brightness control
  • I:10020-I:10027 DALI 24-BIT FRAME — DALI 2.0 24-bit frames — required for DT8 colour control (XY, colour temperature, RGBW), DALI 2.0 control gear queries, and DALI-2 input devices (push-buttons, presence detectors). Template exposes only DALI 1.0 brightness layer per gear
  • I:10030-I:10047 DALI 25-BIT eDALI FRAME — Lunatone-proprietary 25-bit eDALI frames (auto and user redundant-bit variants). Not used by any DALI 1.0 gear
  • I:10050-I:10067 DALI 28-BIT / 32-BIT FRAME — Extended DALI 2.0 frames (memory bank access, DALI-2 application controllers). Template scope is single-channel arc power per gear
  • H:500 (DSI VALUE) DSI 8-bit value send — Send a raw 8-bit DSI/DALI value with no addressing (bus-level diagnostics). Bypassed by every TapHome script
  • C:0 / H:551 DALI Bus Error — 1 = DALI bus fault / short circuit / missing PSU. Useful diagnostic — could be added as a module-level service attribute. Currently bus errors only surface indirectly through 'Gear not responding!' errors emitted by per-gear readscripts
  • H:100 DALI PRIORITY SLOT — 0..4 → 12-16 ms forward-frame timing. Default 2 (configuration). Bus-tuning parameter; template runs at default
  • H:6000 DIP SWITCH / SOFTWARE RESET — Read returns the 4 DIP switch values; write 1 reboots the gateway. Sibling daliconfig template exposes Reset Gateway / Set Slave ID; this runtime template intentionally does not (commissioning concern)
  • H:65222 / H:65224 / H:65225 BAUD_RATE / PARITY / STOP_BITS (FLASH) — FLASH-stored serial parameters. Template hard-codes 9600 8N1 in connection_details, so these are out of scope
  • I:0 / I:50-I:53 / scenes DALI 1.0 scenes (recall / store / query) — DALI 1.0 standard supports 16 stored scenes per gear/group recallable via GO TO SCENE (0x10..0x1F) and storable via STORE DTR AS SCENE (0x40..0x4F). Template exposes per-gear ADD/REMOVE FROM GROUP and RESET, but no scene recall/store/remove/query actions
  • H:512 (RECALL MAX/MIN/GOTO LAST/UP/DOWN/STEP) DALI 1.0 high-level commands per gear — RECALL MAX LEVEL (0x05), RECALL MIN LEVEL (0x06), UP (0x01), DOWN (0x02), STEP UP (0x03), STEP DOWN (0x04), GO TO LAST ACTIVE LEVEL (0x0A) — useful as service actions for visual feedback / smooth dimming. Not exposed; brightness goes only through linear scaling
  • H:512 (STORE DTR AS MAX/MIN/POWER ON/SYSTEM FAILURE LEVEL) Per-gear configuration write commands — STORE DTR AS MAX LEVEL (0x2A), STORE DTR AS MIN LEVEL (0x2B), STORE DTR AS POWER ON LEVEL (0x2C), STORE DTR AS SYSTEM FAILURE LEVEL (0x2D), STORE DTR AS FADE TIME / FADE RATE — template has 'Set Startup Levels' (combines 0x21, 0x2C, 0x2D) but does NOT expose individual writes for max/min/fade-time/fade-rate
  • H:511 (QUERY FADE TIME / FADE RATE / RANDOM ADDRESS / EXT VERSION) Additional DALI queries — QUERY FADE TIME / FADE RATE (0xA5), QUERY VERSION NUMBER (0x97), QUERY RANDOM ADDRESS H/M/L (0x98/0xC2/0xC3), QUERY CONTENT DTR/DTR1/DTR2 — not exposed in service attributes, only the 10 attributes listed per gear are populated
  • H:511 (QUERY CONTROL GEAR / RESET STATE / LIMIT ERROR / LAMP POWER ON / MISSING SHORT ADDRESS) DALI gear health / topology queries — QUERY CONTROL GEAR (0x90), QUERY RESET STATE (0x95), QUERY LIMIT ERROR (0x94), QUERY LAMP POWER ON (0x93), QUERY MISSING SHORT ADDRESS (0x96, broadcast) — diagnostic queries. Could be useful as module-level diagnostics; template exposes only QUERY STATUS / LAMP FAILURE / POWER FAILURE / DEVICE TYPE / MIN-MAX-PHYSICAL MIN-POWER UP-SYSTEM FAILURE LEVEL / GROUPS
  • H:511 (READ MEMORY LOCATION 0xC5) DALI memory bank read — READ MEMORY LOCATION (0xC5) is required to read DALI 2.0 memory banks (Bank 0 device GTIN, FW version, serial number; Bank 1 for emergency lighting). Not used
  • ASCII protocol commands Parallel ASCII text protocol — RESI gateway also exposes a CR-terminated text protocol (#LARC, #GARC, #AARC, #LGS, #LCMD, #LCMDA, #DALI CMDxx etc.). Template uses Modbus exclusively — ASCII would only matter for diagnostics/terminal access
  • DT6 fade time / fade rate / DAPC sequence Smooth dimming primitives — DAPC (Direct Arc Power Control) sequence allows fast continuous level updates for smooth dimming. Each gear has stored fade time / fade rate that affect transitions. Template writes raw arc power without configuring fade behaviour
  • DT8 colour control (XY, colour temperature, RGBW) DALI DT8 tunable white / RGB / RGBW — DT8 colour control gears (tunable white CCT, XY colour, RGBW) require DALI 2.0 24-bit frames sent via H:541 / I:10020. Template exposes plain ModbusDimmer per gear — for DT8 lamps use a dedicated DT8 template
  • DT1 emergency lighting DALI DT1 self-contained emergency lights — Emergency-luminaire device type with periodic self-tests (function/duration test) and battery state queries. Out of scope — template is general-purpose dimming

Parametri di importazione

Inserisci questi valori quando importi l'XML.

Richiesto nell'appPredefinito
Slave ID255
Indirizzo IP192.168.1.0

Fonti

I documenti del produttore sono © dei rispettivi proprietari. Sono forniti così come pubblicati dal produttore, solo a titolo informativo.

Hai trovato un problema con questo template?

Dicci cosa non funziona, cosa manca o come dovrebbe comportarsi il template. Il tuo feedback ci aiuta a mantenere il catalogo accurato.

Modello · portale TapHome Resi DALI Apri questo template nel Customer Portal per applicarlo a una delle tue case, o crea una proposta di modifica e inviala al catalogo. Modbus RTU Vedi nel portale TapHome