Forum

Bitte beachte auch unsere Knowledgebase und das Handbuch!

Benachrichtigungen
Alles löschen

[Gelöst] Kundendisplay

6 Beiträge
2 Benutzer
0 Reactions
43 Ansichten
(@stefaan)
Beiträge: 54
Trusted Member
Themenstarter
 

Hallo!

Ich hätte über den Sommer die Motivation, die Ansteuerung des Kassendisplays bei unserer Kassa (ChromisPOS) aus ChromisPOS loszulösen, da nicht alle gewünschten Anzeigoptionen möglich sind. Die Idee ist, ein kleines Stück Software zu schreiben, die über eine Pipe oder übers Netzwerk ein XML/JSON-Dokument annimmt und richtig formatiert anzeigt.

Das könnte auch für QRK eine Option sein, da würde es reichen, bei jedem Vorgang (Produkt hinzufügen/ändern, Zahlung) einen String irgendwo hineinzukübeln und die ganze Ansteuerung des Displays wäre ausgelagert.

Gibt es Anregungen dazu?
Meine Idee:

  • Plattformunabhängig (bei mir ist Linux im Einsatz, könnte mir Python vorstellen)
  • Am einfachsten wohl über TCP oder sogar HTTP
  • Habe ein Epson DM-D110-Display für Tests
  • Noch unklar: Soll die Formatierung in meinem Programm erfolgen oder 1:1 einen vorformatierten String aufs Display klatschen. Formatierung in meinem Programm wäre wahrscheinlich flexibler, wenn man die Anzeigelogik auslagern will. Dann wären problemlos unterschiedliche Displays möglich, wenn man einfach den aktuellen Verkaufsvorgang (x Produkte und Gesamtsumme etc) strukturiert als JSON/XML annimmt.
  • Für die ferne Zukunft: Anzeige auf einem 2. Display (regulärer 2. Bildschirm per HDMI/USB).

Stefan

 
Veröffentlicht : 18. Juni 2024 11:30
chris
(@chris)
Beiträge: 1143
Noble Member Admin
 

Veröffentlicht von: @stefaan

Hallo!

Ich hätte über den Sommer die Motivation, die Ansteuerung des Kassendisplays bei unserer Kassa (ChromisPOS) aus ChromisPOS loszulösen, da nicht alle gewünschten Anzeigoptionen möglich sind. Die Idee ist, ein kleines Stück Software zu schreiben, die über eine Pipe oder übers Netzwerk ein XML/JSON-Dokument annimmt und richtig formatiert anzeigt.

Das könnte auch für QRK eine Option sein, da würde es reichen, bei jedem Vorgang (Produkt hinzufügen/ändern, Zahlung) einen String irgendwo hineinzukübeln und die ganze Ansteuerung des Displays wäre ausgelagert.

Gibt es Anregungen dazu?
Meine Idee:

  • Plattformunabhängig (bei mir ist Linux im Einsatz, könnte mir Python vorstellen)
  • Am einfachsten wohl über TCP oder sogar HTTP
  • Habe ein Epson DM-D110-Display für Tests
  • Noch unklar: Soll die Formatierung in meinem Programm erfolgen oder 1:1 einen vorformatierten String aufs Display klatschen. Formatierung in meinem Programm wäre wahrscheinlich flexibler, wenn man die Anzeigelogik auslagern will. Dann wären problemlos unterschiedliche Displays möglich, wenn man einfach den aktuellen Verkaufsvorgang (x Produkte und Gesamtsumme etc) strukturiert als JSON/XML annimmt.
  • Für die ferne Zukunft: Anzeige auf einem 2. Display (regulärer 2. Bildschirm per HDMI/USB).

Stefan

Ja ich hatte so eine Kundenanzeige fast fertig. Lief schon im Test.
Wurde aber mangels Interesse eingestellt.Auch die Kosten waren etwas zu hoch.Es war ein Raspberry Zero dafür vorgesehen mit 7zoll Display.

Von QRK wurde per Datagram/udp ins netz geschickt. Es habe alle Monitore darauf reagiert.

void QRK::sendDatagram(QString what, QString data)
{
    //    qDebug() << "Function Name: " << Q_FUNC_INFO << what << " data: " <<
    //    data;
    QByteArray datagram;
    QDataStream out(&datagram, QIODevice::WriteOnly);
    out << what << data;

    udpSocket.writeDatagram(datagram, QHostAddress::Broadcast, 5824);
}

Das ist noch als code vorhanden 😉 und wird teilweise noch ausgesendet.

nc -lukp 5824

 

 
Veröffentlicht : 18. Juni 2024 12:09
chris
(@chris)
Beiträge: 1143
Noble Member Admin
 

Veröffentlicht von: @stefaan

Hallo!

  • Habe ein Epson DM-D110-Display für Tests

Es sollte ein 7-Zoll-LCD sein, das Werbebilder vom Betreiber anzeigen kann und über eine Kamera verfügt, um Gutscheincodes zu scannen. Der angestrebte Preis lag unter 100 Euro.

Ein Epson Kundendisplay ist allein schon teuer; ein ESP32 mit Display könnte deutlich kostengünstiger sein.

 

 
Veröffentlicht : 18. Juni 2024 13:55
(@stefaan)
Beiträge: 54
Trusted Member
Themenstarter
 

Wunderbar, da kommen ja schon brauchbare Daten raus! Danke!
Einzelpreis in der Liste wäre noch ein Hit und eine Verfeinerung beim Zahlungsprozess (Zahlungsart(en) und Retourgeld).
Ich melde mich einfach nochmals, wenn ich im Sommer ein paar ruhige Momente dafür finde.
Mit Multicast ist die Lösung ganz universell, da könnte man später einmal direkt über QRK der Kundschaft die (noch nicht vorhandene) Wallbox freischalten 😀 . Einfach ein Produkt "Ladestation" eintippen, irgendwo lauscht ein Script mit und schaltet den Ladevorgang frei.

Bei den Features vom Kundendisplay bin ich bei dir, da ist sicher Entwicklungspotential da. Mal schauen bzw wäre interessant, ob potentielle User eh noch alte POS-Displays herumliegen haben oder selber was basteln wollen.
Das Epson-Display war gebraucht gekauft, da waren es €40 oder so. Neu hätte ich es auch nicht gekauft.

Stefan

 
Veröffentlicht : 18. Juni 2024 17:56
chris
(@chris)
Beiträge: 1143
Noble Member Admin
 

Ich muss Nachschauen was alles noch im Code vorhanden ist, Ich glaube ich habe die Sachen nur auskommentiert. Bin mir jetzt gar nicht sicher. Hat mich dann nicht weiter interessiert,

 
Veröffentlicht : 18. Juni 2024 20:35
chris
(@chris)
Beiträge: 1143
Noble Member Admin
 

@stefaan 

Hallo
Mehr ist eigentlich nicht da. Steht auch nur im QRK Kassenmode zu Verfügung
Hier ein kurzes Python3 snippet um zu sehen wie das ausgewertet werden könnte

import socket
import json

def receive_udp_data(host, port):
    udp_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
    udp_socket.bind((host, port))
    print(f"Listening on {host}:{port}...")
    
    while True:
        try:
            data, addr = udp_socket.recvfrom(1024)
            if data:


                try:
                    # Debugging:
                    print(f"Received raw data: {data}")

                    # Extrahieren der Länge des "what"-Teils (ersten 4 Bytes)
                    what_length = int.from_bytes(data[:4], byteorder='big')
                    print(f"Length of 'what': {what_length}")
                    # Extrahieren des "what"-Teils
                    what = data[4:4 + what_length].decode('utf-8').replace('\0', '').strip()
                    print(f"'what': @{what}@")

                    # Startindex des JSON-Teils berechnen
                    start_idx = 4 + what_length  # Beginne 4 Bytes + Länge des 'what'-Teils

                    # Länge des JSON-Teils lesen (nächste 4 Bytes nach start_idx)
                    json_length = int.from_bytes(data[start_idx:start_idx + 4], byteorder='big')
                    print(f"Length of 'json': {json_length}")

                    # JSON-String extrahieren und dekodieren
                    json_str = data[4 + what_length + 4:start_idx + 4 + json_length].decode('latin1').replace('\0', '').strip()

                    # orders = json.loads(json_data)
                    print(f"'data': {json_str}")
                    print("=======================================================")

                    try:
                        if what == "orders":
                          json_data = json.loads(json_str)
                          process_orders(json_data)
                        elif what == "topay":
                            print(f"To pay: {json_str}")
                        elif what == "finished":
                            print("Payment finished")

                        print("=======================================================")

                    except json.JSONDecodeError as e:
                        print(f"Error decoding JSON data: {str(e)}")

                except UnicodeDecodeError as e:
                    print(f"Error decoding received data as Latin-1: {str(e)}")

        except KeyboardInterrupt:
            print("\nUDP Receiver stopped.")
            break

        except Exception as e:
            print(f"Error receiving UDP data: {str(e)}")

    udp_socket.close()

def process_orders(data):
    if isinstance(data, dict) and 'Orders' in data:
        orders = data['Orders']
        for order in orders:
            try:
                count = order.get("count")
                product = order.get("product")
                sum_amount = order.get("sum")
                print(f"Order received: {count}x {product}, Total: {sum_amount}")

            except Exception as e:
                print(f"Error processing order: {str(e)}")

        print(f"Order received: Summe:  {data.get("sum", 0)}")

    else:
        print("Received data does not contain a valid 'Orders' key.")

if __name__ == "__main__":
    HOST = '0.0.0.0'
    PORT = 5824

    receive_udp_data(HOST, PORT)
 
Veröffentlicht : 24. Juni 2024 10:42
Teilen: