Python zapytanie do kasy Novitus z protokołem TANGO

Python zapytanie do kasy Novitus z protokołem TANGO
LT
  • Rejestracja:2 miesiące
  • Ostatnio:2 miesiące
  • Postów:1
0

Dzień dobry

Chcę się podłączyć do kasy firmy Novitus z obsługą protokołu TANGO i co jakiś czas wysłać nowe towary i pobrać raport sprzedaży. Kasa z programami ze strony Novitus działa poprawnie. Pobrałem dokumentację protokołu ale nigdy nie robiłem tak złożonej komunikacji i składania pakietów.. Trochę mi pomogła AI, kasa coś tam niby odpowiada ale wywala się na PAKIECIE STARTOWYM.

tu jest jak ma niby działać komunikacja

Przesłanie z komputera pojedynczego pakietu danych

-> ENQ
<- ACK
-> PAKIET STARTOWY
<- ACK
-> PAKIET DANYCH
<- ACK
-> EOT
<- EOT

Przesłanie do komputera pojedynczego pakietu danych
-> ENQ
<- ACK
-> PAKIET STARTOWY
<- ACK
-> EOT
<- ENQ
-> ACK
<-PAKIET DANYCH
-> ACK
<- EOT
-> EOT

tu opis Pakiet startowy

Lp.;Offset;Długość;Zawartość;Opis
1;0;1;STX;02H
2;1;1;‘S’;Znacznik pakietu startowego
3;2;1;Typ zadania;‘A’ (41H) do ‘Z’ (5AH) lub ‘a’ (61H) do ‘s’ (73H) - znak ASCII określający typ następującego(ych) pakietu(ów) danych (poza ‘F’, i ‘O’)
4;3;1;Typ transmisji;‘0’ (30H) = pobranie danych przez komputer, ‘1’ (31H) = wysłanie danych przez komputer, ‘2’ (32H) = pobranie danych raportowych z wyzerowaniem
5;4;18;Początek;Numer początkowy dla pobierania raportów i niektórych danych
6;22;18;Koniec;Numer końcowy dla pobierania raportów i niektórych danych
7;40;1;ETX;03H
8;41;4;Suma kontrolna

Tu program który nabazgrałem z AI

Kopiuj
import socket
import time

KASA_IP = "192.168.1.XXX"
KASA_PORT = 5001
TOUT = 3  # Zwiększony czas oczekiwania

ENQ = b"\x05"
ACK = b"\x06"
NAK = b"\x15"
EOT = b"\x04"
STX = b"\x02"
ETX = b"\x03"

# Funkcja do obliczania sumy kontrolnej (CRC)
def oblicz_sume_kontrolna(pakiet):
    crc = 0
    for i, znak in enumerate(pakiet):
        crc ^= znak << (i % 9)
    return format(crc, '04X')  # Zwraca wynik jako 4-cyfrową liczbę heksadecymalną

# Funkcja do wysyłania pakietu startowego
def wyslij_pakiet_startowy(s):
    # Składając pakiet na podstawie specyfikacji
    numer_poczatkowy = b"000000000000000000"  # Zmienny początek (np. numery raportów)
    numer_koncowy = b"000000000000000000"    # Zmienny koniec (np. numery raportów)
    
    pakiet_startowy = STX + b'S' + b'A' + b'0' + numer_poczatkowy + numer_koncowy + ETX
    
    print(pakiet_startowy)
    
    suma = oblicz_sume_kontrolna(pakiet_startowy)
    
    # Dodajemy sumę kontrolną (cztery bajty)
    pakiet_startowy += bytes.fromhex(suma)  
    
    print(pakiet_startowy)
    
    s.sendall(pakiet_startowy)
    
    print(f"Wysłano pakiet startowy: {pakiet_startowy.hex()}")
    
def wyslij_pakiet_danych(s, dane):
    pakiet_danych = STX + dane + ETX
    suma = oblicz_sume_kontrolna(pakiet_danych)
    
    # Dodajemy sumę kontrolną (cztery bajty)
    pakiet_danych += bytes.fromhex(suma)
    
    s.sendall(pakiet_danych)
    print(f"Wysłano pakiet danych: {pakiet_danych.hex()}")

def komunikacja_z_kasą():
    with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
        s.settimeout(TOUT)  # Timeout na odpowiedzi
        
        try:
            s.connect((KASA_IP, KASA_PORT))
            print("Połączono z kasą.")
            
            # Wysłanie ENQ do rozpoczęcia transmisji
            s.sendall(ENQ)
            print("Wysłano ENQ, oczekiwanie na odpowiedź...")
            odpowiedz = s.recv(1)
            print(f"Odebrano odpowiedź po ENQ: {odpowiedz.hex()}")
            
            if odpowiedz == ACK:
                print("Odebrano ACK - kasa gotowa do transmisji.")
                
                # Wysyłanie pakietu startowego
                wyslij_pakiet_startowy(s)

                # Oczekiwanie na ACK po wysłaniu pakietu startowego
                odpowiedz = s.recv(1)
                print(odpowiedz)
                print(f"Odebrano odpowiedź po pakiecie startowym: {odpowiedz.hex()}")
                
                if odpowiedz == ACK:
                    print("Odebrano ACK po pakiecie startowym.")
                    
                    # Wysyłanie pakietu danych (przykład danych: "12345678")
                    dane = b"12345678"  # Przykładowe dane do wysłania
                    wyslij_pakiet_danych(s, dane)

                    # Oczekiwanie na ACK po wysłaniu pakietu danych
                    odpowiedz = s.recv(1)
                    print(f"Odebrano odpowiedź po pakiecie danych: {odpowiedz.hex()}")
                    if odpowiedz == ACK:
                        print("Odebrano ACK po pakiecie danych.")
                    
                    # Wysłanie EOT
                    s.sendall(EOT)
                    print("Wysłano EOT, koniec transmisji.")
                    
                    # Oczekiwanie na EOT
                    odpowiedz = s.recv(1)
                    print(f"Odebrano odpowiedź po EOT: {odpowiedz.hex()}")
                    if odpowiedz == EOT:
                        print("Odebrano EOT - zakończenie transmisji.")
                
                else:
                    print("Błąd komunikacji - nie otrzymano ACK po wysłaniu pakietu startowego.")
            
            else:
                print(f"Odebrano nieoczekiwaną odpowiedź po ENQ: {odpowiedz.hex()}")
        
        except socket.timeout:
            print("Timeout - kasa nie odpowiada.")
        except Exception as e:
            print(f"Błąd: {e}")

if __name__ == "__main__":
    komunikacja_z_kasą()

A tu co mi kasa odpowiada

Połączono z kasą.
Wysłano ENQ, oczekiwanie na odpowiedź...
Odebrano odpowiedź po ENQ: 06
Odebrano ACK - kasa gotowa do transmisji.
b'\x02SA0000000000000000000000000000000000000\x03'
b'\x02SA0000000000000000000000000000000000000\x03\x00\x10'
Wysłano pakiet startowy: 02534130303030303030303030303030303030303030303030303030303030303030303030303030030010
b'\x15'
Odebrano odpowiedź po pakiecie startowym: 15
Błąd komunikacji - nie otrzymano ACK po wysłaniu pakietu startowego.

Dziękuje za pomoc. Pozdrawiam

edytowany 2x, ostatnio: LaToZ
AD
Tego nie da się czytać. Weź to sformatuj. I na tak ogólne pytanie będzie ciężko o sensowną odpowiedź.
RG
  • Rejestracja:około 5 lat
  • Ostatnio:około 5 godzin
  • Lokalizacja:Sardine, Italy
  • Postów:187
0

Zgodnie z komunikatem to czy jesteś pewien o wysłaniu ACK?

Zarejestruj się i dołącz do największej społeczności programistów w Polsce.

Otrzymaj wsparcie, dziel się wiedzą i rozwijaj swoje umiejętności z najlepszymi.