Am fost nevoit sa vin cu o solutie pentru a actualiza ora pe niste ceasuri de pontaj folosite cu ADP.
Primul pas a fost sa aflu cine fabrica ceasurile: Control Module Inc; modelul era SaveTime 20xx, care arata ca Genus 1. Apoi m-am intrebat daca suporta NTP; nu, nu suporta. Am gasit link-ul catre documentatia tehnica si am inceput sa invat protocolul pe care il intelege ceasul.
Cateva caractere speciale folosite:
_______________________________________________________
| |
| POLL | 'P' | 0x50 | Poll command character |
|--------|-----|------|-------------------------------|
| SELECT | 'S' | 0x53 | Select command character |
|--------|-----|------|-------------------------------|
| ACK | ACK | 0x06 | Positive data acknowledgement |
|--------|-----|------|-------------------------------|
| NAK | NAK | 0x15 | Negative data acknowledgement |
|--------|-----|------|-------------------------------|
| SOH | SOH | 0x01 | Start of data stream header |
|--------|-----|------|-------------------------------|
| STX | STX | 0x02 | Start of data stream text |
|--------|-----|------|-------------------------------|
| ETX | ETX | 0x03 | Last character of all strings |
|--------|-----|------|-------------------------------|
| EOT | EOT | 0x04 | Start of each command string |
|_____________________________________________________|
Exista doi octeti reprezentand adrese: ADD1 si ADD2. ADD1 este adresa controllerului si este irelevanta, deoarece comunicatia va fi initiata de noi (server oarecare) spre terminal (ceasul de pontaj); ADD1 va fi mereu zero. ADD2 este adresa terminalului si este, de asemenea, irelevanta – pentru ca ADD2 este adresa dispozitivului pe bus-ul serial, iar noi il contactam prin TCP/IP; ADD2 va fi tot zero.
Caracterul de control este numit LRC (Longitudinal Redundancy Check), este penultimul caracter in comenzile ce transfera date si se calculeaza astfel: se aplica XOR tuturor caracterelor, de la stanga la dreapta, pana la caracterul ce preceda LRC. Aplicam OR intre rezultatul obtinut si 0x40 (40h sau 40 in baza 16). Ceea ce ne rezulta este LRC.
Tipul de terminal este un caracter ASCII si identifica, cum ii zice numele, tipul de terminal caruia ne adresam. In documentatie este un exemplu in care se foloseste ‘J’. Software-ul de la ADP foloseste tot ‘J’.
Exista doua tipuri de comenzi: Poll si Select. Poll este folosita cand vrei sa citesti datele de la terminal: trimiti o comanda Poll catre terminal si terminalul raspunde transmitand toate datele pe care le are in memorie (datele insemnand pontajul inregistrat de la momentul ultimului poll). Comanda Select se foloseste pentru a atentiona terminalul ca urmeaza sa i se comunice ceva – un nou program, ajustarea ceasului sau schimbarea starii.
Formatul comenzii Poll este:
<EOT> (ADD1) (ADD2) P <ETX>
Daca terminalul nu are date de transmis, raspunsul va fi:
<ETX>
Daca terminalul are date de transmis, conversatia va arata asa:
SERVER:<EOT> 1 0 P <ETX>
TERMINAL #0: <SOH> 1 0 <STX> \ J 0 <GS> HELLO <RS> (lrc) <ETX>
SERVER: <ACK> <ETX>
TERMINAL #0: <ETX>
Conversatia s-ar traduce (liber) prin: serverul cere raportul de la terminalul 0, terminalul trimite raportul (“HELLO”), serverul confirma ca a primit raportul si terminalul confirma ca a primit confirmarea serverului (adica poate sa stearga datele pe care tocmai le-a transmis).
Formatul comenzii Select este:
<EOT> (ADD1) (ADD2) S <ETX>
Formatul comenzii ce transmite date este acelasi si pentru Poll si pentru Select:
<SOH>(ADD1)(ADD2)<STX>\(TYPE)(ADD2)(DATA)(LRC)<ETX>
Cautam comanda pentru a transmite ora catre terminal si o integram in formatul general al comenzii de transmis date si obtinem:
<SOH>(ADD1)(ADD2)<STX>\(TYPE)(ADD2)TØØyymmddhhmmss(LRC)<ETX>
Daca ceasul are activat DSC (Daylight Saving Control), atunci comanda de trimitere a orei trebuie sa includa si ziua saptamanii (dow): 1-Duminica, 2-Luni, …, 7-Sambata. Adica:
<SOH>(ADD1)(ADD2)<STX>\(TYPE)(ADD2)TØØyymmddhhmmss(dow)(LRC)<ETX>
In final, pentru a trimite ora catre un terminal, transmisia va fi:
SERVER: <EOT> (ADD1) (ADD2) S <ETX>
TERMINAL: <ACK><ETX>
SERVER: <SOH>(ADD1)(ADD2)<STX>\(TYPE)(ADD2)TØØyymmddhhmmss(dow)(LRC)<ETX>
TERMINAL: <ACK><ETX>
SERVER: <ETX>
Pentru un script Perl care parcurge o lista de ceasuri si le actualizeaza ora in functie de fusul orar pe care se afla fiecare, inclusiv DST, lasa-mi un mesaj.
For English, press 1 – or drop me an e-mail.
No Comments