Elektronisches Preisschild Sammelbestellung - Ansteuerung

Der chaotische Hauptfaden

Moderatoren: Heaterman, Finger, Sven, TDI, Marsupilami72, duese

Benutzeravatar
Marsupilami72
Beiträge: 2874
Registriert: Mo 4. Nov 2013, 23:48
Wohnort: mittendrin

Re: Elektronisches Preisschild Sammelbestellung - Ansteuerung

Beitrag von Marsupilami72 »

Wir werden das in absehbarer Zeit in einem größeren Gebäude im Harz ausgiebig testen ;)
Stefan
Beiträge: 381
Registriert: So 11. Aug 2013, 15:14
Wohnort: Köln

Re: Elektronisches Preisschild Sammelbestellung - Ansteuerung

Beitrag von Stefan »

Den CC2531 gibt es auch bereits fertig mit SMA-Konnektor. Das Routing der Masseführung zum SMA-Konnektor ist mies, aber denoch ist die Reichweite mit externer 2,4 GHz Antenne deutlich höher (grob 1-2 Räume weiter, Stahlbetondecken machen ohne weitere Router kein Spaß). Wenn das Teil in einem ZigBee 3.0 Netzwerk mit Routern funktionieren würde, wäre dies wohl ein großer Mehrwert.
Benutzeravatar
Hightech
Beiträge: 11466
Registriert: So 11. Aug 2013, 18:37

Re: Elektronisches Preisschild Sammelbestellung - Ansteuerung

Beitrag von Hightech »

Arrrr, der Meister wird zufrieden sein!
D573C7FD-2636-404E-BA67-F64D047D20EA.jpeg
Benutzeravatar
Finger
Administrator
Beiträge: 7465
Registriert: Di 12. Jun 2012, 20:16
Kontaktdaten:

Re: Elektronisches Preisschild Sammelbestellung - Ansteuerung

Beitrag von Finger »

Bild
Benutzeravatar
Finger
Administrator
Beiträge: 7465
Registriert: Di 12. Jun 2012, 20:16
Kontaktdaten:

Re: Elektronisches Preisschild Sammelbestellung - Ansteuerung

Beitrag von Finger »

BTW: Was bedeuten die Barcodes am Rand?
Benutzeravatar
Marsupilami72
Beiträge: 2874
Registriert: Mo 4. Nov 2013, 23:48
Wohnort: mittendrin

Re: Elektronisches Preisschild Sammelbestellung - Ansteuerung

Beitrag von Marsupilami72 »

Das sind die MAC-Adressen der Schilder
Benutzeravatar
Hightech
Beiträge: 11466
Registriert: So 11. Aug 2013, 18:37

Re: Elektronisches Preisschild Sammelbestellung - Ansteuerung

Beitrag von Hightech »

Wir brauchen jetzt noch eine ordentliche Antenne für den Stick.
Einen 50Ohm Dipol, oder gibbet da was feineres?
andreas6
Beiträge: 4157
Registriert: So 11. Aug 2013, 15:09

Re: Elektronisches Preisschild Sammelbestellung - Ansteuerung

Beitrag von andreas6 »

Gewöhnliche Wlan-Antennen sollten es tun. Es reichen die für "nur" 2,4 GHz.

MfG. Andreas
Benutzeravatar
Hightech
Beiträge: 11466
Registriert: So 11. Aug 2013, 18:37

Re: Elektronisches Preisschild Sammelbestellung - Ansteuerung

Beitrag von Hightech »

Bisschen Gewinn an der Antenne wäre ja gut.
Benutzeravatar
phettsack
Beiträge: 1202
Registriert: Mo 12. Aug 2013, 18:17

Re: Elektronisches Preisschild Sammelbestellung - Ansteuerung

Beitrag von phettsack »

Je länger die Antenne wird, desto flacher wird die Abstrahlcharakteristik. Der Stummel ist ungefähr kugelförmig, mit einer längeren Antenne wird es dann mehr zu einer flachen Scheibe.
An meinem normalen Zigbee2Mqtt-Stick habe ich eine 5dB-Antenne von einem alten WLAN-Router, da sind allerdings noch 2 Birnen als Repeater dabei.
Benutzeravatar
Mechatronk
Beiträge: 448
Registriert: So 28. Feb 2021, 23:47

Re: Elektronisches Preisschild Sammelbestellung - Ansteuerung

Beitrag von Mechatronk »

Was, außer der Bundesnetzagentur, spricht gegen einen Verstärker vor der Antenne?
Stefan
Beiträge: 381
Registriert: So 11. Aug 2013, 15:14
Wohnort: Köln

Re: Elektronisches Preisschild Sammelbestellung - Ansteuerung

Beitrag von Stefan »

Hightech hat geschrieben: Fr 14. Okt 2022, 10:11 Bisschen Gewinn an der Antenne wäre ja gut.
Achtung: Gewinn gegenüber Kugelstrahler. Davon sollte es nicht zuviel sein (2-5 dBi).
Mechatronk hat geschrieben: Fr 14. Okt 2022, 13:22 Was, außer der Bundesnetzagentur, spricht gegen einen Verstärker vor der Antenne?
Wenn, dann in Sende- und Empfangsrichtung. 20 dBm EIRP sind bei uns "erlaubt" (EIRP_dBm = Ausgangsleistung_Verstärker_dBm + Antennengewinn_dBi).
Benutzeravatar
Mechatronk
Beiträge: 448
Registriert: So 28. Feb 2021, 23:47

Re: Elektronisches Preisschild Sammelbestellung - Ansteuerung

Beitrag von Mechatronk »

Benutzeravatar
phettsack
Beiträge: 1202
Registriert: Mo 12. Aug 2013, 18:17

Re: Elektronisches Preisschild Sammelbestellung - Ansteuerung

Beitrag von phettsack »

Mechatronk hat geschrieben: Fr 14. Okt 2022, 14:39 https://www.ebay.de/itm/114337978055 sollte es tun, oder ?
Mal fabulieren: Hmm, also ein einem Ende stöpselt man den CC2531 mit möglichst kurzem Verbindungskabel an, am anderen Ende eine Antenne. Der CC2531 sendet und das Ding verstärkt es. Soweit klar, aber was ist mit eingehenden Signalen von den Schildern? Oder fängt der einfach ALLES im 2,4GHz auf und drückt es nachgebrannt in Richtung CC2531 der sich dann aussuchen soll was er braucht?
Benutzeravatar
Hightech
Beiträge: 11466
Registriert: So 11. Aug 2013, 18:37

Re: Elektronisches Preisschild Sammelbestellung - Ansteuerung

Beitrag von Hightech »

Ich hab an der aktuellen Station.py geschraubt und einen "Discovery-Modus" eingebaut:

führt man die station.py --d aus, läuft sie im Discovery-mode
dann erzeugt sie für jedes Schild was sich an der Station anmeldet eine mac.png Datei mit einem Musterinhalt und eingebettet einen Text zuzüglich des Aktualisierungs- Datum und Zeit.

Dafür braucht man eine muster.png im richtigen Format und die FreeMonoItaly.ttf

Wenn ich herraus gefunden habe wie das mit git geht mach ich einen branch oder wie das heisst.

Bis dahin schicke ich die Dateien per PN raus.
duese
Beiträge: 6093
Registriert: So 11. Aug 2013, 17:56

Re: Elektronisches Preisschild Sammelbestellung - Ansteuerung

Beitrag von duese »

Schick es doch dem Originalautor. Vielleicht nimmt er es gleich in den Master Branch.
Benutzeravatar
Hightech
Beiträge: 11466
Registriert: So 11. Aug 2013, 18:37

Re: Elektronisches Preisschild Sammelbestellung - Ansteuerung

Beitrag von Hightech »

Hab ich schon 😁
Benutzeravatar
Hightech
Beiträge: 11466
Registriert: So 11. Aug 2013, 18:37

Re: Elektronisches Preisschild Sammelbestellung - Ansteuerung

Beitrag von Hightech »

Bei der neuen Firmware ist ein Firmware OTA möglich, also per Funk.
Dazu legt man einfach die entsprechende bin Datei in den Ordner der station.py
Die Software muss natürlich neuer sein als die Installierte.
Dann zieht sich das Display die neue Firmware.
Benutzeravatar
MatthiasK
Beiträge: 3014
Registriert: Mo 19. Aug 2013, 22:12

Re: Elektronisches Preisschild Sammelbestellung - Ansteuerung

Beitrag von MatthiasK »

Das ist ein nettes Feature. Aber erst mal muss ich verstehen, was ich da machen muss.
Benutzeravatar
Hightech
Beiträge: 11466
Registriert: So 11. Aug 2013, 18:37

Re: Elektronisches Preisschild Sammelbestellung - Ansteuerung

Beitrag von Hightech »

Also diese Grafikzeugs ist ja ätzend.

Ich will doch einfach nur Text mit Python Pillow so generieren, das es als harte Pixelschrift heraus kommt.

So sieht die Schriftart aus:
Bild

So sieht die dann in der png Datei nach der Ausgabe aus:
Total verwaschen und das Display rechnet dass dann wieder in 1-Bit BMP um
Bild

Wie macht man es so, das es nachher richtig heraus kommt?

So:
Bild

und nicht so:
Bild
Benutzeravatar
Marsupilami72
Beiträge: 2874
Registriert: Mo 4. Nov 2013, 23:48
Wohnort: mittendrin

Re: Elektronisches Preisschild Sammelbestellung - Ansteuerung

Beitrag von Marsupilami72 »

Da ist offensichtlich Antialiasing aktiviert - hast Du mal den Quelltext?
Benutzeravatar
Hightech
Beiträge: 11466
Registriert: So 11. Aug 2013, 18:37

Re: Elektronisches Preisschild Sammelbestellung - Ansteuerung

Beitrag von Hightech »

Das ist mit Python Pillow erstellt.
Zuerst eine RGB 128x296 Fläche in weiß und dann der Text drauf.

Das passiert aber auch bei gimp.
Benutzeravatar
ESDKittel
Beiträge: 3146
Registriert: Fr 23. Aug 2013, 13:18

Re: Elektronisches Preisschild Sammelbestellung - Ansteuerung

Beitrag von ESDKittel »

Hightech hat geschrieben: So 16. Okt 2022, 17:11 Das passiert aber auch bei gimp.
Stell bei GIMP in den Werkzeugeinstellungen für "Text einfügen" mal die Kantenglättung aus.
Dann legt GIMP das ohne Zwischenfarben an.
Benutzeravatar
Hightech
Beiträge: 11466
Registriert: So 11. Aug 2013, 18:37

Re: Elektronisches Preisschild Sammelbestellung - Ansteuerung

Beitrag von Hightech »

ESDKittel hat geschrieben: So 16. Okt 2022, 17:52
Hightech hat geschrieben: So 16. Okt 2022, 17:11 Das passiert aber auch bei gimp.
Stell bei GIMP in den Werkzeugeinstellungen für "Text einfügen" mal die Kantenglättung aus.
Dann legt GIMP das ohne Zwischenfarben an.
Das hat geklappt :)
Nun muss das noch bei python Pillow klappen.
Benutzeravatar
Hightech
Beiträge: 11466
Registriert: So 11. Aug 2013, 18:37

Re: Elektronisches Preisschild Sammelbestellung - Ansteuerung

Beitrag von Hightech »

Das Thema Schrift und Antialiasing.
Wenn man das Bild zum Upload komplett im Gimp oder Windows Malprogramm erstellt müsste es ohne Probleme klappen, wenn man keine Graustufen/Helligkeitsstufen im Bild hat die gedithert werden müssen.

Verwendet man aber TrueType Fonts in Python wird es hässlich.

Es klappt, wenn man die ttf in bfd und dann in .pil umwandelt.
Man muss sich zuerst eine Schriftart herauspicken und dann in bdf wandeln mit der Ziel-Schriftgröße

otf2bdf /usr/share/fonts/truetype/ttf-bitstream-vera/VeraSe.ttf -p 15 -o test15.bfd

diese wird dann in das Python Format gewandelt und steht dann für Python Pillow als Bitmap Schriftart zur Verfügung
./converts.py test15.bfd

Mit diesem Script hab ich das Schild geschrieben, es muss eine Grafik erstellt werden mit 296x128 Pixeln,
in die schreibt man dann den Text.
Zum Schluss dann noch in die Vertikale drehen.

Bild


muster.py

Code: Alles auswählen

#!/usr/bin/python3
import os
from PIL import Image, ImageDraw, ImageFont
import time

if 1>=1:
    muster=Image.new("RGB",(296,128),color=(255,255,255))

    named_tuple = time.localtime() # get struct_time
    time_string = time.strftime("%m/%d/%Y, %H:%M:%S", named_tuple)

    im = ImageDraw.Draw(muster)

    font = ImageFont.load("./fonts/test24.pil")
    im.text((10,20),"Christian Finger" ,fill=(0, 0, 0),font=font)
    font = ImageFont.load("./fonts/test.pil")
    im.text((25,60),"Weltherrschaft" ,fill=(255, 0, 0),font=font)
    im.rectangle((22,94,250,120),fill=(255,0,0))
    im.rectangle((24,95,251,121),outline=(0,0,0,),width=2)
    font = ImageFont.load("./fonts/test15.pil")

    im.text((30,95),"spätestens bis 2025" ,fill=(255,255,255),font=font)
    muster=muster.rotate(angle=90,expand="true")
    #muster.show()
    muster.save('00000282ddc83b15.png'

converts.py

Code: Alles auswählen

#!/usr/bin/python3
#
# The Python Imaging Library
# $Id$
#
# PIL raster font compiler
#
# history:
# 1997-08-25 fl   created
# 2002-03-10 fl   use "from PIL import"
#

from __future__ import print_function

import glob
import sys

# drivers
from PIL import BdfFontFile
from PIL import PcfFontFile

VERSION = "0.4"

if len(sys.argv) <= 1:
    print("PILFONT", VERSION, "-- PIL font compiler.")
    print()
    print("Usage: pilfont fontfiles...")
    print()
    print("Convert given font files to the PIL raster font format.")
    print("This version of pilfont supports X BDF and PCF fonts.")
    sys.exit(1)

files = []
for f in sys.argv[1:]:
    files = files + glob.glob(f)

for f in files:

    print(f + "...", end=' ')

    try:

        fp = open(f, "rb")

        try:
            p = PcfFontFile.PcfFontFile(fp)
        except SyntaxError:
            fp.seek(0)
            p = BdfFontFile.BdfFontFile(fp)

        p.save(f)

    except (SyntaxError, IOError):
        print("failed")

    else:
        print("OK")
Benutzeravatar
Hightech
Beiträge: 11466
Registriert: So 11. Aug 2013, 18:37

Re: Elektronisches Preisschild Sammelbestellung - Ansteuerung

Beitrag von Hightech »

Ich hab mal einen Schildgenerator gebastelt.
Der benötigt allerdings die .pil Schriftarten.
Müsste auch mit ttf gehen, dann muss man umstricken zb:
font = ImageFont.truetype("arial.ttf", 15)
Und sieht nicht so hübsch aus.
https://pillow.readthedocs.io/en/stable ... eFont.html

https://youtu.be/IxK-QpQpxgw
https://youtu.be/LDGm2OOVngA


Code: Alles auswählen

#!/usr/bin/python3
import os
from PIL import Image, ImageDraw, ImageFont
import time

Display_Size_x=296
Display_Size_y=128
Name=""
Titel=""
unter=""

while 1:
    print("-------------Eingabe Schild-------------------")
    mac=""
    while ( ((len(mac) <12)) or ((len(mac)>12)) ):
        mac=input (" MAC :")
        mac=mac.lower()
    Name=input (" Name : ")
    Titel=input(" Titel: ")
    unter=input(" Unterschrift: ")
    fileIn="0000"+mac+".png"
    print(" MAC: "+fileIn)
    print(" Name : "+Name)
    print(" Titel: "+Titel)
    print(" Unterschrift: "+unter)

    muster=Image.new("RGB",(296,128),color=(255,255,255))

    named_tuple = time.localtime() # get struct_time
    time_string = time.strftime("%m/%d/%Y, %H:%M:%S", named_tuple)

    im = ImageDraw.Draw(muster)

    font = ImageFont.load("./fonts/test24.pil")
    length_name=font.getbbox(Name)
    im.text((((Display_Size_x/2)-length_name[2]/2),5),Name ,fill=(0, 0, 0),font=font)

    font = ImageFont.load("./fonts/test.pil")
    length_name=font.getbbox(Titel)
    im.text((((Display_Size_x/2)-length_name[2]/2),45),Titel ,fill=(0, 0, 0),font=font)

    font = ImageFont.load("./fonts/test15.pil")
    box=font.getbbox(unter)

    tboy1=90
    tboy2=box[3]+tboy1
    tbox1=((Display_Size_x-box[2])/2)
    tbox2=((Display_Size_x-box[2])/2)+box[2]

    im.rectangle((tbox1-6,tboy1-2,tbox2+6,tboy2+2),fill=(255,0,0),outline=(0,0,0),width=2)
    im.text((tbox1,tboy1),unter,fill=(255,255,255),font=font)
    muster.show()
    ready=input(" OK? y/n :")
    if ready=="y":
        print(" Excellent")
        muster=muster.rotate(angle=90,expand="true")
        muster.save(fileIn)
    else:
        print( " Schade")
Benutzeravatar
Hightech
Beiträge: 11466
Registriert: So 11. Aug 2013, 18:37

Re: Elektronisches Preisschild Sammelbestellung - Ansteuerung

Beitrag von Hightech »

Hier noch die station.py mit Discovery-modus.

Aufrufen mit discovery.py --d

Im Discovery Modus Legt die Station eine MAC-ID.png an, wenn noch keine Datei vorhanden ist, die man dann nach belieben bearbeiten kann.
Auf dem Display wird bei Erfolg dann Discovery und die MAC id angezeigt.


Code: Alles auswählen

#!/usr/bin/python3
import timaccop 
import bmp2grays 
from Cryptodome.Cipher import AES
from collections import namedtuple
import struct
import os
import sys
import shutil
import logging
from PIL import Image, ImageDraw, ImageFont
import binascii
import time
from io import BytesIO

parameter=sys.argv
discover=False

if "--d" in parameter:
    discover=True
    print ("DISCOVER-MODE")

masterkey = bytearray.fromhex("D306D9348E29E5E358BF2934812002C1")

PORT = "/dev/ttyACM0"
EXTENDED_ADDRESS = [ 0x00, 0x12, 0x4B, 0x00, 0x14, 0xD9, 0x49, 0x35 ]
PANID = [ 0x47, 0x44 ]
CHANNEL = 11
IMAGE_WORKDIR = "/tmp/"

PKT_ASSOC_REQ			= (0xF0)
PKT_ASSOC_RESP			= (0xF1)
PKT_CHECKIN				= (0xF2)
PKT_CHECKOUT			= (0xF3)
PKT_CHUNK_REQ			= (0xF4)
PKT_CHUNK_RESP			= (0xF5)

VERSION_SIGNIFICANT_MASK				= (0x0000ffffffffffff)

HW_TYPE_42_INCH_SAMSUNG					= (1)
HW_TYPE_42_INCH_SAMSUNG_ROM_VER_OFST	= (0xEFF8)
HW_TYPE_74_INCH_DISPDATA				= (2)
HW_TYPE_74_INCH_DISPDATA_FRAME_MODE		= (3)
HW_TYPE_74_INCH_DISPDATA_ROM_VER_OFST	= (0x008b)
HW_TYPE_ZBD_EPOP50						= (4)
HW_TYPE_ZBD_EPOP50_ROM_VER_OFST			= (0x008b)
HW_TYPE_ZBD_EPOP900						= (5)
HW_TYPE_ZBD_EPOP900_ROM_VER_OFST		= (0x008b)
HW_TYPE_29_INCH_DISPDATA				= (6)
HW_TYPE_29_INCH_DISPDATA_FRAME_MODE		= (7)
HW_TYPE_29_INCH_DISPDATA_ROM_VER_OFST	= (0x008b)
HW_TYPE_29_INCH_ZBS_026					= (8)
HW_TYPE_29_INCH_ZBS_026_FRAME_MODE		= (9)
HW_TYPE_29_INCH_ZBS_025					= (10)
HW_TYPE_29_INCH_ZBS_025_FRAME_MODE		= (11)
HW_TYPE_29_INCH_ZBS_ROM_VER_OFST		= (0x008b)


TagInfo = namedtuple('TagInfo', """
protoVer,
swVer,
hwType,
batteryMv,
rfu1,
screenPixWidth,
screenPixHeight,
screenMmWidth,
screenMmHeight,
compressionsSupported,
maxWaitMsec,
screenType,
rfu
""")

AssocInfo = namedtuple('AssocInfo', """
checkinDelay,
retryDelay,
failedCheckinsTillBlank,
failedCheckinsTillDissoc,
newKey,
rfu
""")

CheckinInfo = namedtuple('CheckinInfo', """
swVer,
hwType,
batteryMv,
lastPacketLQI,
lastPacketRSSI,
temperature,
rfu,
""")

PendingInfo = namedtuple('PendingInfo', """
imgUpdateVer,
imgUpdateSize,
osUpdateVer,
osUpdateSize,
nextCheckinDelay,
rfu
""")

ChunkReqInfo = namedtuple('ChunkReqInfo', """
versionRequested,
offset,
len,
osUpdatePlz,
rfu,
""")

ChunkInfo = namedtuple('ChunkInfo', """
offset,
osUpdatePlz,
rfu,
""")

logging.basicConfig(format='%(asctime)s %(message)s')
logger = logging.getLogger(__name__)

dsn = 0

def print(*args):
    msg = ""
    for arg in args:
        msg += str(arg) + " "
    logger.warning(msg)

def decrypt(hdr, enc, tag, nonce):
    cipher = AES.new(masterkey, AES.MODE_CCM, nonce, mac_len=4)
    cipher.update(hdr)
    plaintext = cipher.decrypt(enc)
    #print("rcvd_packet:", plaintext.hex())
    #print("rcvhdr:", hdr.hex())
    try:
        cipher.verify(tag)
        return plaintext
    except:
        return None

def send_data(dst, data):
    global dsn
    dsn += 1
    if dsn > 255:
        dsn = 0
    hdr = bytearray.fromhex("41cc")
    hdr.append(dsn)
    hdr.extend(PANID)
    hdr.extend(reversed(dst))
    hdr.extend(EXTENDED_ADDRESS)
    #print("hdr:", hdr.hex())

    cntr = int(time.time())
    cntrb = struct.pack('<L', cntr)

    nonce = bytearray(cntrb)
    nonce.extend(EXTENDED_ADDRESS)
    nonce.append(0)
    #print("nonce:", nonce.hex())

    cipher = AES.new(masterkey, AES.MODE_CCM, nonce, mac_len=4)
    cipher.update(hdr)
    ciphertext, tag = cipher.encrypt_and_digest(data)

    out = ciphertext+tag+cntrb
    timaccop.mac_data_req(dst, PANID, 12, dsn, out)

def process_assoc(pkt, data):
    ti = TagInfo._make(struct.unpack('<BQHHBHHHHHHB11s',data))
    print(ti)

    ai = AssocInfo(
	    checkinDelay=900000, #check each 900sec 
	    retryDelay=1000, #retry delay 1000ms
	    failedCheckinsTillBlank=2,
	    failedCheckinsTillDissoc=2,# Better enable this by default
	    newKey=masterkey,
	    rfu=bytearray(8*[0])
    )
    print(ai)
    ai_pkt = bytearray([ PKT_ASSOC_RESP ]) + bytearray(struct.pack('<LLHH16s8s', *ai))

    send_data(pkt['src_add'], ai_pkt)


    
    
    
def prepare_image(client):
    is_bmp = 0
    filename = bytes(client).hex() + ".png"       
    #print("Reading image file:" + bytes(client).hex() + ".bmp/.png")    
    if os.path.isfile(filename):
        print("Using .png file ",filename)
    elif os.path.isfile(bytes(client).hex() + ".bmp"):
        is_bmp = 1
        filename = bytes(client).hex() + ".bmp"
        print("Using .bmp file ",filename)
    else:
        
        if discover==True:
            print("DISCOVER "+filename)
            generate_discover_image(filename)
            src=r'discover.png'
            dst=filename
            shutil.copyfile(src, dst)
        else:
           print ("No Image found "+filename)
           return 0,0
        
    
    modification_time = os.path.getmtime(filename)
    creation_time = os.path.getctime(filename)
    imgVer = int(modification_time)<<32|int(creation_time) # This uses the mofidication time of the image to look for the newest one

    file_conv = IMAGE_WORKDIR + bytes(client).hex().upper() + "_" + str(imgVer) + ".bmp" # also use the MAC in case 1 images are created within 1 second

    if not os.path.isfile(file_conv):
        if is_bmp == 0:
            Image.open(bytes(client).hex() + ".png").convert("RGB").save(IMAGE_WORKDIR + "tempConvert.bmp")
            bmp2grays.convertImage(1, "1bppR", IMAGE_WORKDIR + "tempConvert.bmp", file_conv)
        else:
            bmp2grays.convertImage(1, "1bppR", bytes(client).hex() + ".bmp", file_conv)

    imgLen = os.path.getsize(file_conv)

    return (imgVer, imgLen)

def get_firmware_offset(hwType):
    if hwType == HW_TYPE_42_INCH_SAMSUNG:
        return HW_TYPE_42_INCH_SAMSUNG_ROM_VER_OFST
    if hwType == HW_TYPE_74_INCH_DISPDATA:
        return HW_TYPE_74_INCH_DISPDATA_ROM_VER_OFST   
    if hwType == HW_TYPE_74_INCH_DISPDATA_FRAME_MODE:
        return HW_TYPE_74_INCH_DISPDATA_ROM_VER_OFST
    if hwType == HW_TYPE_29_INCH_DISPDATA:
        return HW_TYPE_29_INCH_DISPDATA_ROM_VER_OFST
    if hwType == HW_TYPE_29_INCH_DISPDATA_FRAME_MODE:
        return HW_TYPE_29_INCH_DISPDATA_ROM_VER_OFST
    if hwType == HW_TYPE_ZBD_EPOP50:
        return HW_TYPE_ZBD_EPOP50_ROM_VER_OFST
    if hwType == HW_TYPE_ZBD_EPOP900:
        return HW_TYPE_ZBD_EPOP900_ROM_VER_OFST
    if hwType == HW_TYPE_29_INCH_ZBS_026 or hwType == HW_TYPE_29_INCH_ZBS_026_FRAME_MODE or hwType == HW_TYPE_29_INCH_ZBS_025 or hwType == HW_TYPE_29_INCH_ZBS_025_FRAME_MODE:
        return HW_TYPE_29_INCH_ZBS_ROM_VER_OFST

def prepare_firmware(hwType):
    filename = 'UPDT{0:0{1}X}.BIN'.format(hwType,4)
    
    #print("Reading firmware file:", filename)

    if not os.path.isfile(filename):
        #print("No Firmware file available")
        return (0,0)

    f = open(filename,mode='rb')
    f.seek(get_firmware_offset(hwType))
    firmwareVersionData = f.read(8)
    f.close()

    osVer = int.from_bytes(firmwareVersionData, "little") & VERSION_SIGNIFICANT_MASK | hwType << 48
    osLen = os.path.getsize(filename)

    return (osVer, osLen)

def get_image_data(imgVer, offset, length):
    filename = IMAGE_WORKDIR + imgVer + ".bmp"
    #print("Reading image file:", filename)

    f = open(filename,mode='rb')
    f.seek(offset)
    image_data = f.read(length)
    f.close()

    return image_data

def get_fw_data(hwType, offset, length):
    filename = 'UPDT{0:0{1}X}.BIN'.format(hwType,4)
    print("Reading firmware file:", filename)

    f = open(filename,mode='rb')
    f.seek(offset)
    fw_data = f.read(length)
    f.close()

    return fw_data

def process_checkin(pkt, data):
    ci = CheckinInfo._make(struct.unpack('<QHHBBB6s',data))
    
    print(ci)

    imgVer = 0
    imgLen = 0

    try:
        imgVer, imgLen = prepare_image(pkt['src_add'])
    except Exception as e :
        print("Unable to prepare image data for client", pkt['src_add'])
        print(e)

    osVer = 0
    osLen = 0

    try:
        osVer, osLen = prepare_firmware(ci.hwType)
    except Exception as e :
        print("Unable to prepare firmware data for client", pkt['src_add'])
        print(e)

    pi = PendingInfo(
        imgUpdateVer = imgVer,
        imgUpdateSize = imgLen,
        osUpdateVer = osVer,
        osUpdateSize = osLen,
        nextCheckinDelay = 0,
        rfu=bytearray(4*[0])
    )
    print(pi)

    pi_pkt = bytearray([ PKT_CHECKOUT ]) + bytearray(struct.pack('<QLQLL4s', *pi))

    send_data(pkt['src_add'], pi_pkt)

def process_download(pkt, data):
    cri = ChunkReqInfo._make(struct.unpack('<QLBB6s',data))
    #print(cri)

    ci = ChunkInfo(
        offset = cri.offset,
        osUpdatePlz = cri.osUpdatePlz,
        rfu = 0,
    )
    #print(ci)

    try:
        if ci.osUpdatePlz:
            fdata = get_fw_data(cri.versionRequested>>48, cri.offset, cri.len)
        else:
            fdata = get_image_data(bytes(pkt['src_add']).hex().upper() + "_" + str(cri.versionRequested), cri.offset, cri.len)
    except Exception as e :
        print("Unable to get data for version", cri.versionRequested)
        print(e)
        return

    outpkt = bytearray([ PKT_CHUNK_RESP ]) + bytearray(struct.pack('<LBB', *ci)) + bytearray(fdata)

    #print("sending chunk", len(outpkt), outpkt[:10].hex() ,"...")

    send_data(pkt['src_add'], outpkt)

def generate_pkt_header(pkt): #hacky- timaccop cannot provide header data
    bcast = True
    if pkt['dst_add'] == b'\xff\xff': #broadcast assoc
        hdr = bytearray.fromhex("01c8")
    else:
        hdr = bytearray.fromhex("41cc")
        bcast = False
    hdr.append(pkt['dsn'])
    hdr.extend(pkt['dst_pan_id'])
    hdr.extend(pkt['dst_add'])
    if bcast:
        hdr.extend(pkt['src_pan_id'])
    hdr.extend(reversed(pkt['src_add']))
    return hdr    

def generate_discover_image(filename):  
    named_tuple = time.localtime() # get struct_time
    time_string = time.strftime("%m/%d/%Y, %H:%M:%S", named_tuple)
    muster=Image.new("RGB",(296,128),color=(255,255,255))
    im = ImageDraw.Draw(muster)
    font = ImageFont.load_default()
    output="DISCOVER"
    im.text((80, 0),output ,align='center',index=1,fill=(255, 0, 0),font=font)
    output=filename
    im.text((80, 40),output ,align='center',index=1,fill=(255, 0, 0),font=font)
    
    muster=muster.rotate(-90,expand=True)
    font = ImageFont.load_default()
    im.text((1, 1),time_string,index=1,fill=(0, 0, 0),font=font)
    muster.save('discover.png')


def process_pkt(pkt):
    hdr = generate_pkt_header(pkt)
    
    if len(pkt['data']) < 10:
        print("Received a too short paket")
        print("data", pkt['data'].hex())
        return

    nonce = bytearray(pkt['data'][-4:])
    nonce.extend(reversed(pkt['src_add']))
    nonce.extend(b'\x00')

    tag = pkt['data'][-8:-4]

    ciphertext = pkt['data'][:-8]

    plaintext = decrypt(hdr, ciphertext, tag, nonce)
    if not plaintext:
        print("data", pkt['data'].hex())
        print("hdr", hdr.hex())
        print("ciph", ciphertext.hex())
        print("nonce", nonce.hex())
        print("tag", tag.hex())
        print("packet is NOT authentic")
        return

    typ = plaintext[0]

    if typ == PKT_ASSOC_REQ:
        print("Got assoc request")
        process_assoc(pkt, plaintext[1:])
    elif typ == PKT_CHECKIN:
        print("Got checkin request")
        process_checkin(pkt, plaintext[1:])
    elif typ == PKT_CHUNK_REQ:
        #print("Got chunk request")
        process_download(pkt, plaintext[1:])
    else:
        print("Unknown request", typ)

timaccop.init(PORT, PANID, CHANNEL, EXTENDED_ADDRESS, process_pkt)
print("Station started")

timaccop.run()

Benutzeravatar
phettsack
Beiträge: 1202
Registriert: Mo 12. Aug 2013, 18:17

Re: Elektronisches Preisschild Sammelbestellung - Ansteuerung

Beitrag von phettsack »

Genialer cliffhanger ;)
Er legte die Batterie ein und was dann geschah!
urmel
Beiträge: 1035
Registriert: Di 22. Apr 2014, 13:47
Wohnort: Karlsruhe & Wittlingen

Re: Elektronisches Preisschild Sammelbestellung - Ansteuerung

Beitrag von urmel »

Fontrendering für low- oder medium-DPI geräte ohne graustufen ist die pest
also heute
früher was das Standarddisziplin. Heute fehlen teils die Funktionen dafür in den Libraries bzw die Renderer sind eigentlich nur noch auf high-DPI und Subpixel-AA getrimmt (oder aber man muss dann lowlevel mit freetype rumzicken um die drölf schichten der Grafikbibliotheken zu umgehen). Deswegen sieht Text heute auch immer blurry aus wenn man nicht viel zeit ins feintuning steckt. Dazu kommt dass die meisten Rederer auch kaum noch ordentlich ohne ebenjenes Subpixelgemurkse arbeiten und so dann zB Stämme von klein-m oder groß-T mal einen, mal zwei pixel breit werden.
IMHO ist der aktuell am wenigsten ekelhafte Weg, gleich Bitmapfonts zu nutzen. Ist zwar auch eklig aber besser als das meiste andere.
urmel
Beiträge: 1035
Registriert: Di 22. Apr 2014, 13:47
Wohnort: Karlsruhe & Wittlingen

Re: Elektronisches Preisschild Sammelbestellung - Ansteuerung

Beitrag von urmel »

Hightech hat geschrieben: Mo 17. Okt 2022, 09:01 Bild
Man sieht hier eignetlich sehr gut die Artefakte die ich meinte:
Oben im Namenstext geht es noch
Weltherrschaft ist auch fett genug.
Der Text in der roten Box: alles; die null in2025, das i in bis, die klötzchen an den kleinen e, das n, mal ein, mal zwei pixel stammbreite
Bitmapfonts nutzen und glücklich sein oder mit viel Hass tief ins Fontrendering eingreifen und feststellen dass die meisten aktuellel (open source) fonts sowieso keine hinting-infos mehr haben bzw die ggf vorhandenen geflissentlich ignoriert werden
(sorry fürs Genöle, aber das ist mein alltäglich Leid, das sieht auf Labeldruckern dann nämlich ähnlich grubbelig aus, aber ich schweife ab)
sirell
Beiträge: 606
Registriert: Mi 8. Apr 2015, 13:38
Wohnort: DE/Herzogenaurach

Re: Elektronisches Preisschild Sammelbestellung - Ansteuerung

Beitrag von sirell »

Naja, bei einem Klebelabel aus dem Epson/Zebra/Brother wäre mir das völlig egal.
Bei einer dauerhaften Beschriftung vielleicht weniger und ansonsten kann unsere
Druckerei auch Seriendrucke für Topqualität (Werbebeschriftung mit Individualisierung zb) oder Spezialkleber.

Aber generell stimme ich dir zu. Gerade einfaches Text2$bildformat in guter Qualität ist erstaunlich schwierig.
Ich hatte ähnlichen Spaß mit den Kartendruckern (Mitgliedsausweise, Thermotransfer) und gdlib/ImageMagick usw.

Ich würde ja gerne mitbasteln, aber ich warte noch auf mein Paket :(
urmel
Beiträge: 1035
Registriert: Di 22. Apr 2014, 13:47
Wohnort: Karlsruhe & Wittlingen

Re: Elektronisches Preisschild Sammelbestellung - Ansteuerung

Beitrag von urmel »

sirell hat geschrieben: Di 18. Okt 2022, 12:28 Naja, bei einem Klebelabel aus dem Epson/Zebra/Brother wäre mir das völlig egal.
Für so Kram wie Versandlabel und co: Ja.

Aber Typenschilder per Thermotransfer...
In 600DPI drucken löst das Problem. Aber eigentlich gibt es halt keinen Grund warum 300DPI mit entsprechend günstigerer Druckhardware nicht reichen würden, wären da nicht jene Probleme
Und naja $alles wenn man was auf LCD oder OLED ausgeben will bei embedded
es sieht dann halt einfach immer gruselig aus
xanakind
Beiträge: 12601
Registriert: So 11. Aug 2013, 21:55

Re: Elektronisches Preisschild Sammelbestellung - Ansteuerung

Beitrag von xanakind »

Kann mir mal jemand bitte die Funktion des $-Zeichen vor manchen Wörtern erklären.
In letzter Zeit habe ich das hier schon einige male gesehen, verstehe es aber nicht :?:
duese
Beiträge: 6093
Registriert: So 11. Aug 2013, 17:56

Re: Elektronisches Preisschild Sammelbestellung - Ansteuerung

Beitrag von duese »

In manchen Programmiersprachen wird mit dem Zeichen eine Variable gekennzeichnet. Es drückt also aus, dass man einen beliebigen Vertreter der Spezies meint. Z. B.:
$AUTO = irgendein Auto im Gegensatz zu mein Auto.
xanakind
Beiträge: 12601
Registriert: So 11. Aug 2013, 21:55

Re: Elektronisches Preisschild Sammelbestellung - Ansteuerung

Beitrag von xanakind »

Ah! Danke für die Info, war mir bisher tatsächlich nicht bekannt.Wieder was gelernt :)
Benutzeravatar
phettsack
Beiträge: 1202
Registriert: Mo 12. Aug 2013, 18:17

Re: Elektronisches Preisschild Sammelbestellung - Ansteuerung

Beitrag von phettsack »

Zur station.py:

Oben im Programm ist ein masterkey drin, sollte man den ändern oder es tunlichst unterlassen da dran rumzufummeln?

Edit:

Juchu! Meine sind heute angekommen, vielen vielen Dank dafür!

Nun habe ich mir einen CC2531 geflasht, diese 3V-Brücke habe ich nicht gebraucht, im Gegenteil, wenn die aktiviert war hagelte es verify-Errors beim Flashen mit Brücke. Jetzt ist es anscheinend sauber geflasht.
Aber, es passiert nichts.
Ich habs an einem Raspberry angestöpselt, es wurde auch als /dev/ttyACM0 eingebunden.
discovery.py --d

gestartet. "Station started" meldet es mir. Also ein Schild genommen, Deckel ab, Batterien raus, Batterien rein und es ganz dicht an die Antenne gelegt. Aber es passiert so nüscht. Gar nüscht. Weder auf dem Schild noch in der Konsole.
Dann habe ich im discovery.py mal alle auskommentierten print-Befehle einkommentiert in der Hoffnung das irgendwas kommt. Aber nichts kommt. Nächstes Schild, gleicher Effekt. Nichts.
Jetzt weiß ich nicht weiter an welchem Ende ich suchen könnte.
Kann man dem timaccop.run() noch irgendeine Debug-Option mitgeben, im Moment weiß ich eben nicht ob der CC2531 irgendwas macht.

Edit2:

Jetzt habe ich den Stick an einen PC (war vorher Raspberry) angeschlossen und es geht.
Am Raspberry hatte ich den Kanal auf 20 umgestellt, kann es daran gelegen haben?

Edit3:
Jaaaa, wenn man sich nur einmal mit dem Zeug beschäftigen würde was man so macht!
Im ZBS-Flasher liegt ein "firmware_ch11_low_power" Ordner. Naaa, was der wohl macht Herr Phettsack??
Kanal 11 ist also hardverdrahtet in der Firmware.
Kerko
Beiträge: 336
Registriert: Mo 12. Aug 2013, 22:18

Re: Elektronisches Preisschild Sammelbestellung - Ansteuerung

Beitrag von Kerko »

Meine sind auch angekommen. Vielen Dank Hightech.

Mein CC2531 habe ich geflasht, station.py meldet auch Station started aber die Displays pairen sich nicht. Weis Jemand, wie man sehen kann, was der CC2531 Stick macht? Und was hat es mit der LED auf sich? Beim Einstecken leuchtet die grün und geht dann aus, sobald die Station gestartet ist.
Benutzeravatar
Hightech
Beiträge: 11466
Registriert: So 11. Aug 2013, 18:37

Re: Elektronisches Preisschild Sammelbestellung - Ansteuerung

Beitrag von Hightech »

Die "Pairen" sich nur, wenn eine passende macID.png Datei vorliegt, einfach mal die Ausgabe der Station.py beobachten.

Man kann auch das Display debuggen, wenn man an dem Pin UartTx des Display mitschneidet.
caprivi
Beiträge: 585
Registriert: Mi 9. Mär 2016, 14:44
Wohnort: Am ehemaligen Schorbaer Berg.

Re: Elektronisches Preisschild Sammelbestellung - Ansteuerung

Beitrag von caprivi »

Mhm. Ich steige schon im Discovery-Script in Zeile 2 aus :?

Code: Alles auswählen

ModuleNotFoundError: No module named 'timaccop'
Also sag ich

Code: Alles auswählen

python3 -m pip3 install timaccop
und bekomm gesagt

Code: Alles auswählen

Defaulting to user installation because normal site-packages is not writeable 
ERROR: Could not find a version that satisfies the requirement timaccop (from versions: none)
ERROR: No matching distribution found for timaccop
Also googel ich, finde das hier (die Antwort mit den 22 Punkten, die genau meinen Fall beschreibt), und dort steht, dass das Modul, wenn man's laden will, oft anders heisst als wenn man's benutzen will (warum zur Hölle). Also im Beispiel bei denen z.B. hiesse es python-aalib und nicht aalib. Man soll also...

Code: Alles auswählen

But it actually wrong package name, ... search on pypi site to get the accurate package name
Pypi kennt das Modul aber nicht.
Irgendwie geht es mir bei Python immer so. Ich wunder mich im Rückblick immer wieder, wie ich die zwei, drei Programme zusammengekriegt hab, die bei mir laufen.
Kann mich jemand auf den rechten Weg bringen, bitte?
(System ist MacOS 12.6 mit Python 3.9.6.)
Benutzeravatar
Hightech
Beiträge: 11466
Registriert: So 11. Aug 2013, 18:37

Re: Elektronisches Preisschild Sammelbestellung - Ansteuerung

Beitrag von Hightech »

Du musst schon alle Dateien aus dem git Repository herunter laden. Das Station.Py ist nur die Steuerzentrale.

https://github.com/danielkucera/epaper-station
caprivi
Beiträge: 585
Registriert: Mi 9. Mär 2016, 14:44
Wohnort: Am ehemaligen Schorbaer Berg.

Re: Elektronisches Preisschild Sammelbestellung - Ansteuerung

Beitrag von caprivi »

Sehr geil! Danke schön. Bis auf eins habe ich jetzt bei allen das discovery.png zu sehen bekommen. Das ist für heute genug Erfolg :) morgen muss da ein Katzenbild drauf.
Und vielen Dank für Deine Arbeit! Ich hätte mich nie an so etwas herangetraut.
Benutzeravatar
Hightech
Beiträge: 11466
Registriert: So 11. Aug 2013, 18:37

Re: Elektronisches Preisschild Sammelbestellung - Ansteuerung

Beitrag von Hightech »

Die Teile wollen schon minimum 2,9V sehen. Drunter ist die Reichweite =0.
Benutzeravatar
Hightech
Beiträge: 11466
Registriert: So 11. Aug 2013, 18:37

Re: Elektronisches Preisschild Sammelbestellung - Ansteuerung

Beitrag von Hightech »

Eine weitere Möglichkeit die Displays mit Inhalt zu bespaßen:
Man nimmt einen ESP32 und kann da ein Display als Station dran laufen lassen.
Die Frage hier ist nur, braucht man noch einen extra Server oder reicht der esp, das hab ich noch nicht raus gefunden
Kerko
Beiträge: 336
Registriert: Mo 12. Aug 2013, 22:18

Re: Elektronisches Preisschild Sammelbestellung - Ansteuerung

Beitrag von Kerko »

Hightech hat geschrieben: Fr 21. Okt 2022, 15:23 Die "Pairen" sich nur, wenn eine passende macID.png Datei vorliegt, einfach mal die Ausgabe der Station.py beobachten.

Man kann auch das Display debuggen, wenn man an dem Pin UartTx des Display mitschneidet.
Ich dachte das macht das station.py Skript von dir im Discovery Modus automatisch?
Benutzeravatar
Hightech
Beiträge: 11466
Registriert: So 11. Aug 2013, 18:37

Re: Elektronisches Preisschild Sammelbestellung - Ansteuerung

Beitrag von Hightech »

Ja, im Discovery Modus müsste es so gehen.
Poste mal die Ausgabe der Station.
Hast du die Adresse des Stick korrekt in der Station eingetragen?
Benutzeravatar
phettsack
Beiträge: 1202
Registriert: Mo 12. Aug 2013, 18:17

Re: Elektronisches Preisschild Sammelbestellung - Ansteuerung

Beitrag von phettsack »

Hightech hat geschrieben: Fr 21. Okt 2022, 23:08 Eine weitere Möglichkeit die Displays mit Inhalt zu bespaßen:
Man nimmt einen ESP32 und kann da ein Display als Station dran laufen lassen.
Die Frage hier ist nur, braucht man noch einen extra Server oder reicht der esp, das hab ich noch nicht raus gefunden
Das Projekt kenne ich noch gar nicht, hört sich interessant an. Hast du einen Link dazu?
Wäre interessant wenn der ESP ähnlich deinem discovery auch gleich Schilder generieren könnte. Power müsste der doch genug haben.
Wenn man dann auch noch die Texte direkt auf dem ESP ablegen könnte und on demand aussendet.

Ein Schild als repeater an neuralgischen Punkten wäre auch noch was.
Benutzeravatar
Hightech
Beiträge: 11466
Registriert: So 11. Aug 2013, 18:37

Re: Elektronisches Preisschild Sammelbestellung - Ansteuerung

Beitrag von Hightech »

https://github.com/jjwbruijn/ESP32-epaper-station
phettsack hat geschrieben: Sa 22. Okt 2022, 08:22
Hightech hat geschrieben: Fr 21. Okt 2022, 23:08 Eine weitere Möglichkeit die Displays mit Inhalt zu bespaßen:
Man nimmt einen ESP32 und kann da ein Display als Station dran laufen lassen.
Die Frage hier ist nur, braucht man noch einen extra Server oder reicht der esp, das hab ich noch nicht raus gefunden
Das Projekt kenne ich noch gar nicht, hört sich interessant an. Hast du einen Link dazu?
Wäre interessant wenn der ESP ähnlich deinem discovery auch gleich Schilder generieren könnte. Power müsste der doch genug haben.
Wenn man dann auch noch die Texte direkt auf dem ESP ablegen könnte und on demand aussendet.

Ein Schild als repeater an neuralgischen Punkten wäre auch noch was.
Kerko
Beiträge: 336
Registriert: Mo 12. Aug 2013, 22:18

Re: Elektronisches Preisschild Sammelbestellung - Ansteuerung

Beitrag von Kerko »

Wenn ich die station.py imDiscovery Mode starte sieht das so aus:

Code: Alles auswählen

python station.py --d
DISCOVER-MODE
2022-10-22 08:36:50,649 Station started
Dann Batterien raus, Batterien rein, Display macht seinen Bootvorgang aber es passiert nichts weiter.

Wenn ich den Stick abstecke kommen diverse Meldungen. Also scheint die station.py mit dem Stick zu kommunizieren. Was habt Ihr für eine Baudrate für den seriellen Port eingestellt?
Benutzeravatar
phettsack
Beiträge: 1202
Registriert: Mo 12. Aug 2013, 18:17

Re: Elektronisches Preisschild Sammelbestellung - Ansteuerung

Beitrag von phettsack »

Danke!
Ja, da bräuchte man noch einen Webserver . Könnte wohl sogar bei einem hoster liegen. Der ESP müsste eben nur dran kommen.
Im Moment macht das nur Sinn für Leute die keinen CC2531 haben finde ich.
caprivi
Beiträge: 585
Registriert: Mi 9. Mär 2016, 14:44
Wohnort: Am ehemaligen Schorbaer Berg.

Re: Elektronisches Preisschild Sammelbestellung - Ansteuerung

Beitrag von caprivi »

Kerko hat geschrieben: Sa 22. Okt 2022, 08:41 Wenn ich die station.py imDiscovery Mode starte sieht das so aus:

Code: Alles auswählen

python station.py --d
DISCOVER-MODE
2022-10-22 08:36:50,649 Station started
Dann Batterien raus, Batterien rein, Display macht seinen Bootvorgang aber es passiert nichts weiter.
Mal ne Viertelstunde warten.
Vielleicht sind auch die Batterien vom Schild runter?
Antworten