Anzeige von PNG-Bitmaps aus Grafana auf einem e-Paper Display

Der war entgegen der Dokumentation noch nicht implementiert. Mea culpa.

Jetzt aber: http://imagecast.hiveeyes.org/. Beispiele:

2 Likes

Hi Michael,

upng_new_from_bytes will einen Pointer auf einen C-style buffer:

Die c_str()-Methode der Arduino String-Implementierung liefert Dir einen solchen, siehe Arduino > String > Functions > C str.

Es könnte also so in der Art klappen:

upng_t* upng;

HTTPClient http;
http.begin(client, server, 80, uri);
int httpCode = http.GET();
if (httpCode == HTTP_CODE_OK) {
    String payload = http.getString();
    upng = upng_new_from_bytes(payload.c_str(), payload.length());
}

if (upng != NULL) {
    
    // Decode PNG image.
    upng_decode(upng);
    if (upng_get_error(upng) == UPNG_EOK) {

        // Get pointer to bitmap buffer.
        const uint8_t *bitmap = upng_get_buffer(upng);

        // Display bitmap on e-Paper.
        //display.fillScreen(GxEPD_WHITE);
        display.writeScreenBuffer(); // use default for white

        display.drawImage(bitmap, 0, 0, 200, 200, false, false, true);
        //display.writeImage(bitmap, 0, 0, 200, 200, false, false, true);
        display.refresh(true);

    }

    upng_free(upng);
}

Unfinished spike to load PNG via HTTP and display on e-Paper display with ESP32 · GitHub

Viele Grüße,
Andreas.

Leider auch keine Chance.

readString = client.readString(); //gets byte from ethernet buffer
upng = upng_new_from_bytes(readString.c_str(), png_length);

Ergebnis:

test.ino:141:48: error: invalid conversion from 'const char*' to 'const unsigned char*' [-fpermissive]
upng = upng_new_from_bytes(payload.c_str(), payload.length());
                                        ^

Hab noch eine Idee, aber es geht erst morgen Abend weiter.

Hat sonnst noch jemand Ideen man braucht ja nicht unbedingt ein Display, um den Stream in einen buffer zu laden und an den decoder weiter zu geben.

Hi Michael,

a) Was ist mit http.getString() statt .readString()?
b) Ansonsten: Vielleicht hilft reinterpret_cast<const char*> weiter.

Also evtl.:

upng = upng_new_from_bytes(reinterpret_cast<const unsigned char*>(payload.c_str()), payload.length());

Ohne Gewähr natürlich. Hab ich einfach nur so ins Blaue hinein hingeschrieben.

Viele Grüße,
Andreas.

WifiSecure:: nimmt nur read und readString

(Const unsigned Char*)mychar*

Hatte ich auch schon probiert da kommt nur so etwas wie.

.test.ino:141:48: error: invalid conversion from 'const unsigned char*' to 'const unsigned char*' [-fpermissive] 

Alternative (ebenfalls “untested”):

unsigned char *tmp;
int length = payload.length();
tmp = malloc(length);
memcpy(tmp, payload.c_str(), length);
upng = upng_new_from_bytes(tmp, length);
free(tmp);

Ah, Du nimmst arduino-esp32/libraries/WiFiClientSecure at master · espressif/arduino-esp32 · GitHub? Versuche doch weiterhin einmal den HTTPClient, falls möglich, siehe ESP32 Arduino: HTTPS GET Request - techtutorialsx.

Vielleicht klappts damit…

  1. git pull
  2. Muss noch angepasst werden: hiveeyes-epaper-display/lib/image/image_client.h at e1b4ce06fcc0ba9f4aaabe088ad4a446c880f8ca · hiveeyes/hiveeyes-epaper-display · GitHub

https://github.com/hiveeyes/hiveeyes-epaper-display/blob/e1b4ce06fcc0ba9f4aaabe088ad4a446c880f8ca/src/hiveeyes-epaper.ino#L192-L192

1 Like

Im Editor schaut das bei mir komisch aus

ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿóÿÿÿÿÿÿ¿ÿÿÿÿÿÿÿÿÿÿÿóüÿÏÿÃó¿ÿþ?ðÿÿÿÿÿÿÿóüÿÏÿ™ó¿ÿü.÷ÿÿÿÿÿÿÿÿó.@‡.¹ãƒÿø.÷þ.ÿÿÿÿÿÿòdüÎgùË™ÿð.àüÏÿÿÿÿÿÿòäùÎçûÛ¹ÿà.ö}ïÿÿÿÿÿÿð.ùÌ.ó›¹ÿÂ!ÿ}ïÿÿÿÿÿÿðüóÌÿ绹ÿæ3ÿ}ïÿÿÿÿÿÿòüçÎÿÏ

Hätte jetzt so was erwartet:

Ist schon in Ordnung so. Das sind die echten Bytes.

Das ist die entsprechende ASCII-Notation als Hex-String, die auf dem Kabel natürlich viel mehr auftragen würde. Siehe auch https://www.ascii-code.com/.

Hier der Link zum XBM-Format: Letzte Werte (Boom Table) via imagecast.hiveeyes.org als XBM

In Python:

>>> import sys
>>> _ = sys.stdout.buffer.write(bytearray([0xff, 0xff, 0xfb]))
���
>>> ord('ÿ')
255
>>> bytearray([0xff, 0xff, 0xfb]).hex()
'fffffb'
2 Likes

konnte heute Nacht endlich wieder ein wenig weiter machen.

Leider noch nicht Perfekt, aber dank @Andreas läd er schon mal die PNG.
Allerdings sind bei der Anzeige unter dem Bild noch Datenmatsch.


Edit: Dieses Foto zeigt einen Testgraphen mit abgeschnittener Legende bzw. Achsbeschriftung, der für die Anzeige auf einem E-Paper Display neu gerendert und beschnitten wurde. Die Informationen des Graphen sind für diesen Test irrelevant. Falls sie dennoch ein interesse an einer Achsbeschriftung haben, entnehmen sie dies bitte dem Originalgraphen Hier

Das Decodieren der Daten geschied sehr schnell und das Bild läd gefühlt nicht langsamer als ein BMP.
Habe es aber upng vorerst einfach gemacht und ein auf ein vorverdautes SW-PNG Bild von Imagecast.hiveeyes.org genommen. Es stehen also noch Tests aus.
Es besteht auch noch ein Problem mit der GxEPD2 Libary. DrawImage läd die Dateien in eine Art Vorpuffer die dann beim anzeigen mit dem Displaypuffer ausgetauscht wird und die String und Zeichenroutinen arbeiten direkt im Displaypuffer, die dann einfach nur aktualiesiert werden.
Zeichnungen und Bilder habe ich bereits irgendwo schon gleichzeitig auf einem Bild gesehen allerdings muß ich erst rausfinden wie das geschied.

2 Likes

Leute, ick mein das ernst!

1 Like

Hi Michael,

Exzellent!

Du hast absolut recht.

Das Cropping in dieser Art und Weise sollte wirklich nur dann angewendet werden, wenn man das Bild in Mikrogrößen rendern will und hat dann die Pflicht, selbst noch per Text etwas an die Achsen hinzuzurendern.

Wenn man das Bild also größer anzeigt, so wie oben zu sehen, dann sollten wir die Achsenbeschriftungen nicht abschneiden. Vielleicht kannst Du uns zuliebe nocheinmal eine nicht beschnittene Version rendern lassen und den Screenshot oben ersetzen, damit niemand auf falsche Gedanken kommt?

Merci schon im Voraus und viele Grüße,
Andreas.

Ist ja erst mal proof of concept! Im Original schaut das, wie Andreas schon vermutet hat, unschön aus, da muss man im Grafana noch nachbessern und ggf. eine extra Version erzeugen, die dann auch gut ausschaut (nur Striche auf der Skala und größere Achsenbeschriftung).

1 Like

Und woher weiß man was man an die Achse schreiben soll? Werteste noch das PNG mit ner OCR aus und stellst ne Metadaten-API zur Verfügung? ;)

Habe das Foto jetzt mit einer Fußnote versehen. Hoffe das ist jetzt auch nachvollziehbar und Fachlich korrekt.

Wollte zuerst auf die entsprechenden Einzelwerttabellen verweisen, das habe ich mir aber dann doch nicht, auf Grund des ernstes der Lage, getraut.

1 Like

das einzige was mit diesbzgl. irgendwie sinnvoll einfällt, isses im Graph-Plugin feste Min.- und Max.-Werte für die Achsen zu setzen. Nur dann könnte Dein Kopf oder Endgerät aus ner Erinnerung raus einigermaßen sicher erfahren welche Werte gemeint sind.

Jau und “süß” :) … Klar, erstmal alles nur Geteste. Sorg mich ja nur um die Nachwelt oder dass sich das noch jemand abguckt … und unseren Ruf! ;)

1 Like

Es kommt auf das Diagramm an, gerade beim Gewicht interessiert das absolute Gewicht wenig, eher das relative, wenn die Achse alle 2 oder 5 kg einen Strich hat, hilft das schon. Oder wie du schreibst feste Werte, immer 20-30 kg bringt aber auch nix, da das eine Volk 20 kg “Grundgrwicht” das andere 60 kg hat.

Na dit muss ja nicht für alle Völker der Welt derselbe Wert sein. Muss man sich halt einmal pro Bien einstellen. [Ggf. anpassen wenn Brutraum draufkommt … saying that: ick fänds ja geil, wenn wa das Konzept Stockkarte auch als Zeitreihe abbilden. Dann könnte man leicht das Gewicht von n Bruträumen automatisiert abziehen und aus der Info “Brutraum hinzugefügt/weggenommen” ne Annotation machen.]

1 Like