TrueNAS Display fertig und verbaut

Bohnenhans

Captain
Registriert
Okt. 2022
Beiträge
3.100
Zumindest vorerst - auch wenn ich das nochmal evtl ausdrucken werde, das Filament lag jetzt nen Jahr offen rum xD daüfr ist es aber echt noch ganz ok. Und die Abdeckung rastet auch richtig gut ein.

Wegen dem abgerupften und reparierten SATA Ports musste ich jetzt auf ein Gehäuse umsteigen in dem die SATA HDDs NICHT quer eingebaut sind - das Coolermaster ist da ganz ok - die HDD Temps passen auch wenn 7 HDDs + 1 SSD drin sind.

Das Display ist soweit aber erst mal fertig. Ich hab mal manuell die Modi aufgerufen die ich aktuell anzeigen lassen. Das halt "OK Status mit freiem Platz und HDD Temp", "ZFS Fehler", "Scrubbing" und "Ohne Strom"

Glaube den weissen Rand oben und unten in der "Normalanzeige" werde ich noch ein paar Pixel grösser machen, das sieht glaub besser aus und die 3 Zeilen etwas enger machen.
 

Anhänge

  • 20240106_131509.mp4
    4,6 MB
Zuletzt bearbeitet:
  • Gefällt mir
Reaktionen: Domski und s1erra
Gut, aber ohne Kontext schon sehr seltsam der Thread.
 
  • Gefällt mir
Reaktionen: wesch2000, Yesman9277, H3llF15H und eine weitere Person
  • Gefällt mir
Reaktionen: konkretor
Naja der Kontext ist doch in der Überschift - ist halt ein kleines Display AddOn für TrueNas (Scale) hehe glaub so viel mehr kann man da doch gar nicht dazu sagen.

Hihi ja die rote LED ist halt im Vergleich zu grünen echt hell :D aber die soll ja auch auffallen. Ich hab halt 220 Ohm genommen bei 3.3V denke das passt schon. Die güne ist halt zu dunkel weil ich einfach da auch den gleichen Widerstandswert genommen habe - obwohl der sicher kleiner besser wäre.
 
Bohnenhans schrieb:
Naja der Kontext ist doch in der Überschift - ist halt ein kleines Display AddOn für TrueNas (Scale) hehe glaub so viel mehr kann man da doch gar nicht dazu sagen oder?
Dann hätte man es besser als ein Leserartikel mit mehr Informationen verpacken sollen. So steht das lose da.
 
  • Gefällt mir
Reaktionen: Yesman9277, H3llF15H und SpiII
Man könnte viel mehr schreiben. Sinn/Zweck, Material, Programmierung, irgendwelche Fehler/Probleme, Inspiration, Timeline/investierte Zeit, paar Bilder mit Zwischenständen.
Zudem setzt du irgendwelches Wissen von defekten SATA Ports voraus... auch ohne Kontext.

So steht es einfach im Raum, ohne das jemand nachgefragt hat. Als würde ich ein Stück Käse in die Runde werfen.

EDIT: Im unten verlinkten Thread kamen ja auch fragen auf nach mehr Infos. Wenn du ein Projekt hast und Leute sollen daran Teilhaben im Forum: Thread zum Projekt erstellen und den dann immer wieder erweitern/editieren.
Der verlinkte Thread ist einfach zu Ende und aus dem nichts gibts einen Thread mit der Fortsetzung... gehört alles in einen Thread. Diese zusammenhangslosen Posts wirken wie Statusmeldungen bei Facebook oder Instagram.
 
Zuletzt bearbeitet:
  • Gefällt mir
Reaktionen: Yesman9277, duAffentier und H3llF15H
Jo naja das fing ja für einen anderen Server an (FreeBSD und Linux) und ist dann halt schliesslich im TrueNAS Scale gelandet, wiel ich das TrueNAS mal ausprobiert habe und dann dachte hui das aber echt nicht schlecht - auch wegen der guten API zum selber erweitern.

https://www.computerbase.de/forum/t...erver-bastelei-epaper-fuers-neue-nas.2158751/

Kennt doch jeder bei so einer Nebenherbastelei da ändert man doch immer wieder viel bis das dann halt soweit fertig ist das dass dann zum aktuellen passt.
 
Zuletzt bearbeitet:
SpiII schrieb:
Gut, aber ohne Kontext schon sehr seltsam der Thread.
Ich hab auch nicht gelesen, was er will. Keine Anleitung, wenig GLiederung, Slang als Sprache...
Es ist keine Anleitung, keiner kann das nachbauen. Also eigentlich nur ein Report, was gemacht worden ist.
Aber wie es gemacht worden ist im Detail, fehlt.

"TrueNAS Display fertig und verbaut" - Jeden Tag verbauen Leute hier Displays, nichts besonderes.
 
  • Gefällt mir
Reaktionen: GaborDenes, H3llF15H, Yesman9277 und 2 andere
Hab ich doch nicht gesagt dass es was Besonderes ist? Deshalb lohnt es sich doch auch gar nicht das gross weiter zu beschreiben als eh schon im verlinkten Thread - es sind halt nur ein paar Scripte und ein ESP32 mnit Display und 2 LEDs und mehr ist das nicht. Das halt eine einfach für mich ganz nette 2 oder 3 Tage Erweiterung, weil bei uns die Server im Keller stehen und ich einfach beim Vorbeilaufen sehen will ob die "Ok" sind - falls sie an sind. DIe sind zwar auch im HA eingebunden aber da schaue ich vor allem im Sommer selten nach.

Wenn ich irgendwo was sehe wo ich denke och jo das ist für mich interessant bastel ich das halt nach - und wenn ich was bastel wo ich denk das könnt jermand anders interssant finden poste ich das halt.
 
Zuletzt bearbeitet:
Bohnenhans schrieb:
und wenn ich was bastel wo ich denk das könnt jermand anders interssant finden poste ich das halt.
Nett gemeint. Man kann es aber immer noch nicht nachbauen weil du entweder die Quelle nicht verlinkt hast oder jegliche Info zurück hältst um es von hier aus nachbauen zu können.
 
  • Gefällt mir
Reaktionen: SpiII
Hmmm naja ich hab ja den ESP32 Code schon gepostet im anderen Threa so arg viel habe ich da nicht dran geändert hier die aktuelle Version - das Blinken kam halt noch dazu.

Wenn das jemand nachbauen mag kann ich shcon mal ein Anleitung machen, aber denke halt das ist ja wie gesgat wurde eigentlich ja nichts so Besonderes - das Display ist ganz normal angeschlossen an den ESP über SPI, die LEDs natürlich auch.

Und gerade beim Display nimmt doch eh jeder ein anderes - ich hab halt epaper genommen weil die sowieso rumlagen.

Das "OFF Image" habe ich erzeugt mit

https://mischianti.org/images-to-byte-array-online-converter-cpp-arduino/

Echt cool dass es sowas gibt :)

Und der Rest sind halt nur Scripte auf dem TrueNAS

Code:
#include <Arduino.h>

String PROGVERSION = "0.30-6";
#define HASDISPLAY
// #undef HASDISPLAY

//---[ Display ]------------------------------------
#ifdef HASDISPLAY
  #include <SPI.h>
  #include <GxEPD2_BW.h>
  #include "GxEPD2_display_selection.h"
  #include <Fonts/FreeMonoBold9pt7b.h>
  #include <Fonts/FreeMonoBold12pt7b.h>
#endif
//---[ OTA Updates ]------------------------------
#include <WiFi.h>
#include <WiFiClient.h>
#include <WebServer.h>
#include <ESPmDNS.h>
#include <Update.h>
#ifdef HASDISPLAY
const uint8_t myDisplayRotation = 3;
int8_t myFullScreenRefreshCounter = 99;
const unsigned char epd_bitmap_Poweroff[] PROGMEM = {
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x08, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0d, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x35, 0x06, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x67, 0x04, 0xa0, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01, 0x9a, 0x09, 0x20, 0x00, 0x00, 0xdb, 0x6d, 0xb0, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x40, 0x06, 0x80, 0x01, 0xa0, 0x00, 0x19, 0x68, 0x00, 0x00,
    0x00, 0x06, 0xfb, 0x0b, 0x58, 0x00, 0x00, 0x24, 0x92, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x01, 0x40, 0x01, 0x80, 0x02, 0x60, 0x00, 0x26, 0x4c, 0x00, 0x00, 0x00, 0x1b, 0x26, 0x02, 0x4e,
    0x00, 0x00, 0x24, 0x92, 0x48, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x40, 0x02, 0x00, 0x02,
    0x40, 0x00, 0xa4, 0x93, 0x00, 0x00, 0x00, 0x33, 0x6d, 0x0c, 0xa3, 0x40, 0x00, 0x00, 0x60, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xb0, 0x02, 0x80, 0x01, 0x90, 0x00, 0x98, 0x12, 0x80,
    0x00, 0x00, 0xdc, 0xd8, 0x01, 0x99, 0x40, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x01, 0x80, 0x04, 0x80, 0x04, 0xb0, 0x00, 0x40, 0x04, 0x00, 0x00, 0x00, 0x67, 0x90, 0x00,
    0x44, 0xb0, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x58, 0x01, 0x00,
    0x06, 0x20, 0x01, 0x60, 0x01, 0x00, 0x00, 0x00, 0x36, 0x60, 0x00, 0x66, 0x80, 0x00, 0x00, 0x40,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x48, 0x03, 0x40, 0x03, 0x28, 0x01, 0x20, 0x00,
    0x00, 0x00, 0x00, 0x09, 0x80, 0xe0, 0x18, 0x00, 0x00, 0x00, 0x50, 0x02, 0x34, 0x02, 0x00, 0x10,
    0x05, 0x90, 0x01, 0xa4, 0x04, 0x80, 0x08, 0x48, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x03, 0x01,
    0xb8, 0x00, 0x02, 0x00, 0x00, 0x50, 0x06, 0x4d, 0x86, 0x00, 0x30, 0x12, 0x60, 0x02, 0x32, 0x01,
    0x80, 0x0c, 0x34, 0x00, 0xd0, 0x00, 0x00, 0x00, 0x03, 0x00, 0x07, 0x6e, 0x00, 0x0c, 0x00, 0x00,
    0x20, 0x01, 0x42, 0x41, 0x00, 0x00, 0x18, 0x2c, 0x02, 0x8a, 0x02, 0x00, 0x06, 0x04, 0x00, 0x50,
    0x00, 0x00, 0x00, 0x01, 0x00, 0x1d, 0xdb, 0x00, 0x34, 0x00, 0x00, 0x20, 0x05, 0x00, 0x04, 0x00,
    0x30, 0x20, 0x04, 0x01, 0x89, 0x06, 0x40, 0x12, 0x18, 0x00, 0x4c, 0x00, 0x00, 0x00, 0x04, 0xc0,
    0x1b, 0x77, 0x80, 0xdc, 0x00, 0x00, 0x50, 0x04, 0x80, 0x06, 0x00, 0x20, 0x60, 0x06, 0x02, 0x45,
    0x01, 0x80, 0x18, 0x12, 0x00, 0x63, 0x00, 0x00, 0x00, 0x02, 0x68, 0x06, 0xdc, 0x03, 0x66, 0x00,
    0x00, 0x40, 0x02, 0x00, 0x02, 0x00, 0x18, 0x10, 0x02, 0x02, 0x44, 0x81, 0x00, 0x08, 0x0c, 0x00,
    0x18, 0xe0, 0x00, 0x00, 0x03, 0x28, 0x01, 0xb0, 0x06, 0x68, 0x00, 0x00, 0x30, 0x06, 0x00, 0x02,
    0x00, 0x10, 0x80, 0x02, 0x01, 0x82, 0x86, 0x40, 0x24, 0x09, 0x00, 0x0c, 0x9c, 0x00, 0x00, 0x01,
    0x26, 0x00, 0x60, 0x19, 0xbc, 0x00, 0x00, 0x40, 0x01, 0x00, 0x04, 0x00, 0x60, 0x60, 0x05, 0x02,
    0x02, 0x42, 0x80, 0x34, 0x06, 0x00, 0x03, 0x25, 0x00, 0x00, 0x01, 0x93, 0x80, 0x00, 0x6f, 0x96,
    0x00, 0x00, 0x40, 0x04, 0x00, 0x05, 0x00, 0x08, 0x5b, 0x6c, 0x02, 0xc1, 0x42, 0x80, 0x48, 0x04,
    0x80, 0x00, 0x25, 0x00, 0x00, 0x02, 0x58, 0xd0, 0x01, 0xa8, 0xd8, 0x00, 0x00, 0x30, 0x06, 0x00,
    0x02, 0x00, 0x30, 0x12, 0x4a, 0x01, 0x01, 0x31, 0x00, 0x48, 0x05, 0x00, 0x00, 0x09, 0x80, 0x00,
    0x00, 0xc6, 0x54, 0x03, 0x3b, 0x60, 0x00, 0x00, 0x40, 0x02, 0x00, 0x02, 0x00, 0x10, 0xc4, 0x91,
    0x03, 0x00, 0x95, 0x00, 0x30, 0x93, 0x00, 0x00, 0x02, 0x40, 0x00, 0x00, 0x24, 0x92, 0x0d, 0xd7,
    0x60, 0x00, 0x00, 0x50, 0x02, 0x00, 0x04, 0x00, 0x10, 0x20, 0x00, 0x00, 0xc0, 0x44, 0xc0, 0x96,
    0x68, 0x80, 0x00, 0x06, 0x40, 0x00, 0x00, 0x19, 0x9a, 0x0c, 0xd5, 0x80, 0x00, 0x00, 0x20, 0x04,
    0x00, 0x05, 0x00, 0x20, 0x60, 0x00, 0x04, 0x80, 0x5a, 0x00, 0xc5, 0x2c, 0x80, 0x00, 0x01, 0x80,
    0x00, 0x00, 0x02, 0x63, 0x0b, 0x3c, 0x00, 0x00, 0x00, 0x20, 0x05, 0x00, 0x02, 0x00, 0x28, 0x10,
    0x00, 0x03, 0x00, 0x13, 0x00, 0x69, 0x86, 0x40, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x24, 0x0b,
    0xc8, 0x00, 0x00, 0x00, 0x50, 0x02, 0x00, 0x02, 0x00, 0x48, 0x40, 0x00, 0x01, 0x40, 0x24, 0xc1,
    0x00, 0x01, 0x40, 0x40, 0x06, 0x40, 0x00, 0x00, 0x00, 0x4c, 0x0c, 0xd0, 0x00, 0x00, 0x00, 0x40,
    0x02, 0x00, 0x05, 0x00, 0x50, 0x60, 0x00, 0x01, 0x00, 0x0c, 0x81, 0xa0, 0x01, 0x21, 0x60, 0x04,
    0x80, 0x00, 0x00, 0x00, 0x13, 0x0d, 0x20, 0x00, 0x00, 0x00, 0x20, 0x04, 0x00, 0x01, 0x00, 0x50,
    0x18, 0x06, 0x02, 0xc0, 0x09, 0x00, 0xa0, 0x00, 0xa1, 0x2c, 0x59, 0x00, 0x00, 0x00, 0x00, 0x09,
    0x0b, 0x00, 0x00, 0x00, 0x00, 0x60, 0x05, 0x00, 0x02, 0xc5, 0x80, 0x09, 0x24, 0x02, 0x00, 0x03,
    0x02, 0x40, 0x00, 0x90, 0x93, 0x13, 0x00, 0x00, 0x00, 0x00, 0x02, 0x0a, 0x00, 0x00, 0x00, 0x00,
    0x10, 0x02, 0x00, 0x00, 0xb2, 0x30, 0x0c, 0x98, 0x03, 0x00, 0x04, 0x83, 0x40, 0x01, 0x40, 0x12,
    0xcc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x40, 0x02, 0x00, 0x00, 0x2a,
    0x10, 0x02, 0xc0, 0x00, 0xc0, 0x04, 0x81, 0x00, 0x00, 0x60, 0x0c, 0x60, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x21, 0x06, 0x00, 0x10, 0xc3, 0x10, 0x00, 0x86, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd3, 0x48, 0x6c,
    0x24, 0x44, 0x96, 0x33, 0x48, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x48, 0x60, 0x20, 0x44, 0x92, 0x60, 0x08,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x89, 0x8e, 0x58, 0x18, 0x4c, 0x9c, 0x52, 0xce, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x92, 0x08,
    0x48, 0x04, 0x40, 0x90, 0x52, 0x48, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x72, 0x0a, 0x48, 0x34, 0x47, 0x12, 0x89,
    0x8b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x60, 0x00,
    0x1e, 0x07, 0x00, 0xfb, 0x9c, 0x00, 0x00, 0x00, 0x00, 0x78, 0x02, 0x06, 0x1c, 0x07, 0xd1, 0xe0,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x00, 0x23, 0x0c, 0xc0, 0x1a, 0x13,
    0x80, 0x06, 0x00, 0x00, 0x46, 0x07, 0x02, 0x33, 0x80, 0x72, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x01, 0x00, 0xc0, 0x08, 0x10, 0x80, 0x02, 0x00, 0x00, 0x43,
    0x05, 0x02, 0x30, 0xc0, 0x20, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x44,
    0x10, 0x01, 0x00, 0x40, 0x08, 0x10, 0x90, 0x2e, 0x86, 0x00, 0x43, 0x05, 0x82, 0x10, 0x60, 0x60,
    0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x42, 0x20, 0x01, 0x00, 0xc0, 0x08,
    0x10, 0x88, 0x66, 0x09, 0x80, 0x42, 0x0c, 0x82, 0x30, 0x20, 0xc0, 0x10, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0xc3, 0x60, 0x01, 0x00, 0x80, 0x08, 0x1f, 0x0c, 0x46, 0x10, 0xc0,
    0x6c, 0x08, 0x82, 0x30, 0x20, 0x80, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x81, 0xc0, 0x02, 0x01, 0x80, 0x08, 0x19, 0x84, 0x42, 0x10, 0xc0, 0x7c, 0x08, 0xc2, 0x10, 0x21,
    0x80, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x80, 0xc0, 0x06, 0x01, 0x00,
    0x08, 0x10, 0xc4, 0x86, 0x3f, 0x80, 0x46, 0x18, 0xc2, 0x30, 0x21, 0x00, 0x60, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0xc0, 0x0c, 0x02, 0x00, 0x08, 0x10, 0x46, 0x84, 0x10,
    0x00, 0x42, 0x1f, 0xc2, 0x30, 0x63, 0x00, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x03, 0x03, 0x40, 0x18, 0x04, 0x00, 0x08, 0x10, 0x42, 0x82, 0x10, 0x00, 0x42, 0x30, 0x62, 0x10,
    0x46, 0x01, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x02, 0x20, 0x30, 0x0c,
    0x00, 0x08, 0x11, 0xc3, 0x02, 0x18, 0x40, 0x41, 0x20, 0x22, 0x31, 0xc4, 0x03, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x04, 0x30, 0x3f, 0x9f, 0xe0, 0x08, 0x1f, 0x03, 0x03,
    0x87, 0x80, 0x41, 0x20, 0x22, 0x1e, 0x07, 0xf3, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x08, 0x18, 0x70, 0x0e, 0x07, 0xe1, 0xc0, 0xf0, 0x81,
    0x03, 0x01, 0x0e, 0xd3, 0xf3, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x0c, 0x0c, 0x08, 0xcc, 0x31, 0x8c, 0x06, 0x61, 0x98, 0x81, 0x03, 0x03, 0x01, 0x82, 0x04,
    0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x08, 0x18, 0x80,
    0x60, 0x0c, 0x04, 0x03, 0x00, 0x81, 0x03, 0x82, 0x01, 0x02, 0x00, 0x60, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1a, 0x08, 0x09, 0x80, 0xc0, 0x04, 0x04, 0x02, 0x00,
    0xc1, 0x06, 0x82, 0x01, 0x02, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x13, 0x0c, 0x08, 0xc0, 0x80, 0x04, 0x06, 0x02, 0x00, 0x81, 0x04, 0xc3, 0x01, 0x03,
    0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x08, 0x18,
    0x60, 0x81, 0x0f, 0xc3, 0x86, 0x00, 0xff, 0x04, 0x41, 0x01, 0x03, 0xf0, 0x60, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x08, 0x10, 0x18, 0x87, 0x8c, 0x00, 0xc6,
    0x00, 0xc3, 0x0c, 0x42, 0x01, 0x82, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x01, 0xe0, 0x23, 0x8c, 0x08, 0x0c, 0xc0, 0x84, 0x00, 0x62, 0x00, 0x81, 0x09, 0x63, 0x01,
    0x02, 0x00, 0x60, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0x88,
    0x18, 0x04, 0xc0, 0x8c, 0x00, 0x22, 0x00, 0x81, 0x1f, 0xe1, 0x01, 0x02, 0x00, 0x60, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x8c, 0x10, 0x04, 0x40, 0x8c, 0x00,
    0x23, 0x00, 0x81, 0x10, 0x22, 0x01, 0x03, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x40, 0xc6, 0x31, 0x0c, 0x31, 0x84, 0x0c, 0x61, 0x8c, 0x81, 0x10, 0x33,
    0x01, 0x03, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0,
    0x43, 0xc0, 0xf0, 0x1f, 0x07, 0xe7, 0xc0, 0xf0, 0x81, 0x30, 0x11, 0xf1, 0x03, 0xf0, 0x60, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
#endif



const uint8_t myCPUFrequency = 80;

uint8_t GREENLED_PIN = 21;
uint8_t REDLED_PIN = 20;
boolean LED_GREEN_BLINK = false;
boolean LED_RED_BLINK = false;
boolean LED_RED_BLINK_FLAG = true;
boolean LED_GREEN_BLINK_FLAG = true;
uint64_t myBlink_TimeStamp = 0l;
uint64_t myBlink_Frequency = 500l;



uint32_t mySerialBaud = 9600;
const uint8_t MAXSERIALLENGTH=200;
uint8_t mySerialMessageIndex=0;
char mySerialMessage[MAXSERIALLENGTH];
char mySerialMessageSeparator = '\r';
String mySerialReceivedData_Old = "";


//---[ OTA WiFi Updateserver ]--------------------------------------------
const char* myHostID = "truenasdisplay";
WebServer myOTAWebServer(80);
bool myOTAUpdateServerIsActive=false;


//---[ OTA Firmware Page ]--------------------------------------------
String buildOTAIndexPage()
{
  String myHTMLPage = "<html><h2>Firmware Update</h2><br>Aktuell installiert ist V" + PROGVERSION + "<br><br>";
  myHTMLPage += "Reboot des Displays erfolgt (eigentlich) automatisch...<br><br><br>";
  myHTMLPage += "<form method='POST' action='/update' enctype='multipart/form-data' id='upload_form'>";
  myHTMLPage += "<input type='file' name='update'>";
  myHTMLPage += "<input type='submit' value='Update'>";
  myHTMLPage += "</form><br>";
  myHTMLPage += "<a href=\"/abort\">OTA Firmware Modus Abbrechen</a>";
  myHTMLPage += "</html>";
  return (myHTMLPage);
}
//---[]----------------------------------------------------------------------

#ifdef HASDISPLAY
// Display.Font muss gesetzt sein
String shortenToDisplay(String _myMessage)
{
    if (_myMessage == nullptr)
      _myMessage = "";
      
    if (_myMessage.length() > 0)
    {
      int16_t myTextX, myTextY;
      uint16_t myTextWidth, myTextHeight;
      uint16_t myTextMaxHeight;
      // weil automatischer Zeilenumbruch auf virt. Display
      display.getTextBounds("8ygF", 0, 0, &myTextX, &myTextY, &myTextWidth, &myTextMaxHeight);
      myTextMaxHeight++;
      myTextMaxHeight++;
      display.getTextBounds(_myMessage, 0, 0, &myTextX, &myTextY, &myTextWidth, &myTextHeight);
      while (myTextHeight > myTextMaxHeight)
      {
        if (_myMessage.length() > 0)
          _myMessage.remove(_myMessage.length() - 1, 1);
        else
          return ("");
        display.getTextBounds(_myMessage, 0, 0, &myTextX, &myTextY, &myTextWidth, &myTextHeight);
      }
    }
    return (_myMessage);
}
#endif
//-----------------------------------------------------------------------------------------------------------------------------------
#ifdef HASDISPLAY
void drawAlert(String _Message1, String _Message2)
{
  #ifndef HASDISPLAY
      return;
  #endif
  if (_Message1 == nullptr)
    _Message1 = "";
  if (_Message2 == nullptr)
    _Message2 = "";
  if ((_Message1.length() == 0) && (_Message2.length() == 0))
    return;
  uint16_t myTextPosX = 0;
  uint16_t myTextPosY = 0;
  int16_t myTextX, myTextY;
  uint16_t myTextWidth, myTextHeight;
  display.setFullWindow();
  display.setRotation(myDisplayRotation);
  // Tut aktuell nicht auch invertDisplay mag nicht 
  display.fillScreen(GxEPD_BLACK);             
  display.setTextColor(GxEPD_WHITE);

  // Temp Fix damit uerberhaupt was angezeigt wird...  
  display.fillScreen(GxEPD_WHITE);             
  display.setTextColor(GxEPD_BLACK);

  display.firstPage();
  do
  {
    if (_Message1.length() > 0)
    {
      display.setFont(&FreeMonoBold12pt7b);
      _Message1 = shortenToDisplay(_Message1);
      display.getTextBounds(_Message1, 0, 0, &myTextX, &myTextY, &myTextWidth, &myTextHeight);
      myTextPosX = ((display.width() - myTextWidth) / 2) - myTextX;
      myTextPosY = ((display.height() - myTextHeight) / 2) - myTextY;
      if (_Message2.length() > 0)
        myTextPosY = myTextPosY - (myTextHeight / 2);
      display.setCursor(myTextPosX, myTextPosY);
      display.print(_Message1.c_str());
    }
    if (_Message2.length() > 0)
    {
      display.setFont(&FreeMonoBold9pt7b);
      _Message2 = shortenToDisplay(_Message2);
      display.getTextBounds(_Message2, 0, 0, &myTextX, &myTextY, &myTextWidth, &myTextHeight);
      myTextPosX = ((display.width() - myTextWidth) / 2) - myTextX;
      display.setCursor(myTextPosX, (display.height() - myTextHeight));
      display.print(_Message2.c_str());
    }
  } while (display.nextPage());
  
  myFullScreenRefreshCounter = 99;
}
#endif

#ifdef HASDISPLAY
void drawUrgent(String _Message1, String _Message2)
{
  if (_Message1 == nullptr)
    _Message1 = "";
  if (_Message2 == nullptr)
    _Message2 = "";
  if ((_Message1.length() == 0) && (_Message2.length() == 0))
    return;
  uint16_t myTextPosX = 0;
  uint16_t myTextPosY = 0;
  int16_t myTextX, myTextY;
  uint16_t myTextWidth, myTextHeight;
  display.setFullWindow();
  display.setRotation(myDisplayRotation);
  display.fillScreen(GxEPD_WHITE);          // Siehe drawAlert
  display.setTextColor(GxEPD_BLACK);
  if (_Message1.length() > 0)
  {
    display.setFont(&FreeMonoBold12pt7b);
    _Message1 = shortenToDisplay(_Message1);
    display.getTextBounds(_Message1, 0, 0, &myTextX, &myTextY, &myTextWidth, &myTextHeight);
    myTextPosX = ((display.width() - myTextWidth) / 2) - myTextX;
    myTextPosY = ((display.height() - myTextHeight) / 2) - myTextY;
    if (_Message2.length() > 0)
      myTextPosY = myTextPosY - (myTextHeight / 2);
    display.setCursor(myTextPosX, myTextPosY);
    display.print(_Message1.c_str());
  }
  if (_Message2.length() > 0)
  {
    display.setFont(&FreeMonoBold9pt7b);
    _Message2 = shortenToDisplay(_Message2);
    display.getTextBounds(_Message2, 0, 0, &myTextX, &myTextY, &myTextWidth, &myTextHeight);
    myTextPosX = ((display.width() - myTextWidth) / 2) - myTextX;
    display.setCursor(myTextPosX, (display.height() - myTextHeight));
    display.print(_Message2.c_str());
  }
  myFullScreenRefreshCounter = 99;
}
#endif
//---------------------------------------------------------------------------------------------------------------------------
#ifdef HASDISPLAY
void drawInfo(String _Message1, String _Message2)
{
  
  if (_Message1 == nullptr)
    _Message1 = "";
  if (_Message2 == nullptr)
    _Message2 = "";
  if ((_Message1.length() == 0) && (_Message2.length() == 0))
    return;
  uint16_t myTextPosX = 0;
  uint16_t myTextPosY = 0;
  int16_t myTextX, myTextY;
  uint16_t myTextWidth, myTextHeight;
  myFullScreenRefreshCounter++;
  if (myFullScreenRefreshCounter < 10)
    display.setPartialWindow(0,0,display.width(),display.height());
  else
  {
    display.setFullWindow();
    myFullScreenRefreshCounter = 0;
  }
  display.setRotation(myDisplayRotation);
  display.fillScreen(GxEPD_WHITE);
  display.setTextColor(GxEPD_BLACK);
  display.firstPage();
  do
  {
    if (_Message1.length() > 0)
    {
      display.setFont(&FreeMonoBold12pt7b);
      _Message1 = shortenToDisplay(_Message1);
      display.getTextBounds(_Message1, 0, 0, &myTextX, &myTextY, &myTextWidth, &myTextHeight);
      myTextPosX = ((display.width() - myTextWidth) / 2) - myTextX;
      myTextPosY = ((display.height() - myTextHeight) / 2) - myTextY;
      if (_Message2.length() > 0)
        myTextPosY = myTextPosY - (myTextHeight / 2);
      display.setCursor(myTextPosX, myTextPosY);
      display.print(_Message1.c_str());
    }
    if (_Message2.length() > 0)
    {
      display.setFont(&FreeMonoBold9pt7b);
      _Message2 = shortenToDisplay(_Message2);
      display.getTextBounds(_Message2, 0, 0, &myTextX, &myTextY, &myTextWidth, &myTextHeight);
      myTextPosX = ((display.width() - myTextWidth) / 2) - myTextX;
      display.setCursor(myTextPosX, (display.height() - myTextHeight));
      display.print(_Message2.c_str());
    }
  } while (display.nextPage());
}
#endif
//-----------------------------------------------------------------------------------------------------------------------------
#ifdef HASDISPLAY
void drawStatus(String _Message1, String _Message2, String _Message3, String _Message4) 
{
  display.setRotation(myDisplayRotation);
  display.setTextColor(GxEPD_BLACK);
  display.fillScreen(GxEPD_WHITE);
  display.setFont(&FreeMonoBold9pt7b);
  _Message1 = shortenToDisplay(_Message1);
  _Message2 = shortenToDisplay(_Message2);
  _Message3 = shortenToDisplay(_Message3);
  _Message4 = shortenToDisplay(_Message4);
  uint16_t myTextPosX = 0;
  uint16_t myTextPosY = 0;
  int16_t myTextX, myTextY;
  uint16_t myTextWidth, myTextHeight;
  display.getTextBounds("8ygF", 0, 0, &myTextX, &myTextY, &myTextWidth, &myTextHeight);
  uint16_t myYPosAdd = (display.height() - 5) / 4;
  display.firstPage();
  //  display.setPartialWindow(0,0,display.width(), display.height());
  do
  {
    if (_Message1.length() > 0)
    {
      display.setCursor(0, myYPosAdd);
      display.print(_Message1.c_str());
    }
    if (_Message2.length() > 0)
    {
      display.setCursor(0, myYPosAdd * 2);
      display.print(_Message2.c_str());
    }
    if (_Message3.length() > 0)
    {
      display.setCursor(0, myYPosAdd * 3);
      display.print(_Message3.c_str());
    }
    if (_Message4.length() > 0)
    {
      display.setCursor(0, myYPosAdd * 4);
      display.print(_Message4.c_str());
    }
  } while (display.nextPage());
}
#endif

#ifdef HASDISPLAY
void draw3Liner(String _Message1, String _Message2, String _Message3)
{
  #ifndef HASDISPLAY
    return;
  #endif
  display.setRotation(myDisplayRotation);
  display.setTextColor(GxEPD_BLACK);
  display.fillScreen(GxEPD_WHITE);
  display.setFont(&FreeMonoBold12pt7b);
  _Message1 = shortenToDisplay(_Message1);
  _Message2 = shortenToDisplay(_Message2);
  _Message3 = shortenToDisplay(_Message3);
  uint16_t myTextPosX = 0;
  uint16_t myTextPosY = 0;
  int16_t myTextX, myTextY;
  uint16_t myTextWidth, myTextHeight;
  display.getTextBounds("8ygF", 0, 0, &myTextX, &myTextY, &myTextWidth, &myTextHeight);
  uint16_t myYPosAdd = (display.height()) / 3;
  display.firstPage();
  if (myFullScreenRefreshCounter < 10)
  {
    display.setPartialWindow(0, 0, display.width(), display.height());
    myFullScreenRefreshCounter++;
  }
  else
    myFullScreenRefreshCounter = 0;
  do
  {
    if (_Message1.length() > 0)
    {
      display.setCursor(0, myTextHeight+7);
      display.print(_Message1.c_str());
    }
    if (_Message2.length() > 0)
    {
      display.setCursor(0, (display.height() / 2) + (myTextHeight / 3));
      display.print(_Message2.c_str());
    }
    if (_Message3.length() > 0)
    {
      display.setCursor(0, myYPosAdd * 3 - (myTextHeight / 5)-7);
      display.print(_Message3.c_str());
    }
  } while (display.nextPage());
  display.setFullWindow();
}
#endif
//------------------------------------------------------------------------------------------------------------------------------
void switchLED(String _myMessage)
{
  if (_myMessage != nullptr)
  {
    _myMessage.toUpperCase();
    if (_myMessage.startsWith("RED=ON"))
      digitalWrite(REDLED_PIN, HIGH);
    else if (_myMessage.startsWith("RED=OFF"))
      digitalWrite(REDLED_PIN, LOW);
    else if (_myMessage.startsWith("GREEN=ON"))
      digitalWrite(GREENLED_PIN, HIGH);
    else if (_myMessage.startsWith("GREEN=OFF"))
      digitalWrite(GREENLED_PIN, LOW); 
    else if (_myMessage.startsWith("GREEN=BLINK"))
      LED_GREEN_BLINK = true;
    else if (_myMessage.startsWith("RED=BLINK"))
      LED_RED_BLINK = true;
    else if (_myMessage.startsWith("ALLOFF"))
    {
      LED_RED_BLINK = false;
      LED_GREEN_BLINK = false;
      digitalWrite(GREENLED_PIN, LOW);
      digitalWrite(REDLED_PIN, LOW);
    }
    else if (_myMessage.startsWith("REDGREEN=BLINK"))
    {
      LED_RED_BLINK = true;
      LED_GREEN_BLINK = true;
      LED_RED_BLINK_FLAG = !LED_GREEN_BLINK_FLAG;
    }
  } 
}
//--------------------------------------------------------------------------------------------------------------------------------
String getSubString(String _myString, String _mySeparator, uint8_t _myPos)
{
  int16_t LastPos = 0;
  String myResultString = "";
  for (int i = 0; i < _myPos; i++)
  {
    LastPos = _myString.indexOf(_mySeparator, LastPos);
    if (LastPos < 0)
      return (myResultString);
    LastPos = LastPos + _mySeparator.length();
  }
  if (LastPos >= 0)
  {
    myResultString = _myString.substring(LastPos);
    if (myResultString.indexOf(_mySeparator) > -1)
      return (myResultString.substring(0, myResultString.indexOf(_mySeparator)));
    else
      return (myResultString);
  }
  else
    return (myResultString);
}
//------------------------------------------------------------------------------------------------------------------------------
#ifdef HASDISPLAY
void drawPowerOFFImage()
{
  display.setRotation(myDisplayRotation);
  display.firstPage();
  display.setFullWindow();
  do
  {
    display.drawBitmap(0, 0, &epd_bitmap_Poweroff[0], display.width(), display.height(), GxEPD_BLACK);
  } while (display.nextPage());
}
#endif
//---------------------------------------------------------------------------------------------------------------------------------
void startWIFIServerForOTA(String _myString)
{
  String mySSID = "";
  String myPassword = "";
  if ((_myString != nullptr) && (_myString.length() > 0))
  {
      if ((_myString.indexOf("SSID=") == 0) && (_myString.indexOf("&PASSWORD=") > 0))
      {
        mySSID=_myString.substring(String("SSID=").length(), _myString.indexOf("&PASSWORD="));
        myPassword=_myString.substring(_myString.indexOf("&PASSWORD=")+String("&PASSWORD=").length());
      }
  }
  WiFi.mode(WIFI_STA);
  WiFi.begin(mySSID.c_str(), myPassword.c_str());
  uint8_t myWiFiRetryCounter=0;

  while (WiFi.status() != WL_CONNECTED) 
  {
    myWiFiRetryCounter++;
    delay(500);
    if (myWiFiRetryCounter > 50)
    {
      WiFi.disconnect(true, true);
      WiFi.mode(WIFI_OFF);
      #ifdef HASDISPLAY
        drawAlert("Kein Connect!", mySSID);
      #endif
      switchLED("GREEN=OFF");
      switchLED("RED=ON");
      delay(5*1000);   // Fehler 5 Sekunden anzeigen
      return;
    }
  }
  if (myHostID != nullptr)
    MDNS.begin(myHostID);
  myOTAWebServer.on("/", HTTP_GET, []() 
  {
    myOTAWebServer.sendHeader("Connection", "close");
    myOTAWebServer.send(200, "text/html", buildOTAIndexPage().c_str());
  });
  myOTAWebServer.on("/abort", HTTP_GET, []() 
  {
    myOTAWebServer.sendHeader("Connection", "close");
    myOTAWebServer.send(200, "text/plain", "Beende Firmware Modus => Zurueck zum Anzeigemodus");
    switchLED("ALLOFF");
    #ifdef HASDISPLAY
       draw3Liner("FW Update Modus", "abgebrochen", "=> Normal-Modus");
    #endif
    MDNS.end();
    WiFi.disconnect();
    WiFi.mode(WIFI_OFF);
    myOTAUpdateServerIsActive = false;
    mySerialReceivedData_Old = "~";
    return;
  });
  // -- Firmware hochladen ueber POST => Bloecke dann schreiben 
  myOTAWebServer.on("/update", HTTP_POST, []() 
  {
    myOTAWebServer.sendHeader("Connection", "close");
    myOTAWebServer.send(200, "text/plain", (Update.hasError()) ? "Fehler Ohje alles defekt :O" : "OK - Display wird neu gestartet...");
    ESP.restart();
  }, []() 
  {
    HTTPUpload& myFWUploadData = myOTAWebServer.upload();
    if (myFWUploadData.status == UPLOAD_FILE_START) 
    {
      if (!Update.begin(UPDATE_SIZE_UNKNOWN)) 
      { 
        // Update.printError(Serial);
      }
    } 
    else if (myFWUploadData.status == UPLOAD_FILE_WRITE) 
    {
      if (Update.write(myFWUploadData.buf, myFWUploadData.currentSize) != myFWUploadData.currentSize) 
      {
         //  Update.printError(Serial);
      }
    } 
    else if (myFWUploadData.status == UPLOAD_FILE_END) 
    {
      if (Update.end(true)) 
      {
        // Serial.printf("Update OK: %u\nRebooting...\n", upload.totalSize);
      } 
      else 
      {
        // Update.printError(Serial);
      }
    }
  });
  if (WiFi.isConnected())
  {
    myOTAWebServer.begin();
    myOTAUpdateServerIsActive = true;
    switchLED("ALLOFF");
    switchLED("GREEN=ON");
    switchLED("RED=ON");
    #ifdef HASDISPLAY
      drawInfo("FIRMW. UPDATE", WiFi.localIP().toString());
    #endif
  }
}
//---------------------------------------------------------------------------------------------------------------------------------
void setup()
{
  // Defualt WiFi aus  
  WiFi.disconnect(true);
  WiFi.mode(WIFI_OFF);
  // 80 Mhz reichen eigentlich dicke
  setCpuFrequencyMhz(myCPUFrequency);
  Serial.begin(mySerialBaud);
  pinMode(GREENLED_PIN, OUTPUT);
  pinMode(REDLED_PIN, OUTPUT);
  switchLED("ALLOFF");
  #ifdef HASDISPLAY
    display.init(0);
    drawInfo("STARTE...", "");
    display.powerOff();
  #endif
  Serial.flush();
  Serial.clearWriteError();
  // erst mal aufraeumen
  while (Serial.available()) 
    Serial.read();
}
//----------------------------------------------------------------------------------------------


void loop()
{
  if (myOTAUpdateServerIsActive)
  {
    myOTAWebServer.handleClient();
    delay(5);
    return;      // im OTA Modus mache sonst nix anderes mehr
  }
  if (LED_GREEN_BLINK | LED_RED_BLINK)
  {
    if (millis()-myBlink_TimeStamp > myBlink_Frequency)
    {
      if (LED_GREEN_BLINK)
      {
        if (LED_GREEN_BLINK_FLAG)
             switchLED("GREEN=OFF");
        else switchLED("GREEN=ON");
        LED_GREEN_BLINK_FLAG = !LED_GREEN_BLINK_FLAG;
      }
      if (LED_RED_BLINK)
      {
        if (LED_RED_BLINK_FLAG)
             switchLED("RED=OFF");
        else switchLED("RED=ON");
        LED_RED_BLINK_FLAG = !LED_RED_BLINK_FLAG;
      }
      myBlink_TimeStamp = millis();
    }
  }
  //---[ Ab hier serielle Schnittselle ]------------------------------------------------------
  if (!Serial.available())
     return;
  char mySerialReadChar = 0;
  while (Serial.available())
  {
    delay(1);
    mySerialReadChar = Serial.read();
    if (mySerialReadChar == mySerialMessageSeparator)
    {
      mySerialMessage[mySerialMessageIndex] = 0;
      break;
    }
    else 
    {
      if ((mySerialReadChar > 31) && (mySerialReadChar < 128))
      {
        mySerialMessage[mySerialMessageIndex] = mySerialReadChar;
        if (mySerialMessageIndex < (MAXSERIALLENGTH-1))
          mySerialMessageIndex++;
      } 
    }
  }
  if (mySerialReadChar != mySerialMessageSeparator)
    return;
  mySerialMessageIndex = 0;
  String myReceivedSerialDataString = String(mySerialMessage);
    if (myReceivedSerialDataString.length() < 5)
      return;
    String myStatusMessageLine1 = "";
    String myStatusMessageLine2 = "";
    String myStatusMessageLine3 = "";
    String myStatusMessageLine4 = "";
    if (myReceivedSerialDataString.startsWith("[ALERT]"))
    {
      if (mySerialReceivedData_Old.equals(myReceivedSerialDataString))
         return;
      mySerialReceivedData_Old = myReceivedSerialDataString;
      myReceivedSerialDataString.remove(0, String("[ALERT]").length());
      if (myReceivedSerialDataString.indexOf("[NEWLINE]") >= 0)
      {
        myStatusMessageLine2 = myReceivedSerialDataString.substring(myReceivedSerialDataString.indexOf("[NEWLINE]") + 9);
        myStatusMessageLine1 = myReceivedSerialDataString.substring(0, myReceivedSerialDataString.indexOf("[NEWLINE]"));
      }
      else myStatusMessageLine1 = myReceivedSerialDataString;
      #ifdef HASDISPLAY
        drawAlert(myStatusMessageLine1, myStatusMessageLine2);
      #endif
    }
    else if (myReceivedSerialDataString.startsWith("[INFO]"))
    {
      if (mySerialReceivedData_Old.equals(myReceivedSerialDataString))
         return;
      mySerialReceivedData_Old = myReceivedSerialDataString;
      myReceivedSerialDataString.remove(0, String("[INFO]").length());
      if (myReceivedSerialDataString.indexOf("[NEWLINE]") >= 0)
      {
        myStatusMessageLine2 = myReceivedSerialDataString.substring(myReceivedSerialDataString.indexOf("[NEWLINE]") + 9);
        myStatusMessageLine1 = myReceivedSerialDataString.substring(0, myReceivedSerialDataString.indexOf("[NEWLINE]"));
      }
      else myStatusMessageLine1 = myReceivedSerialDataString;
      #ifdef HASDISPLAY
        drawInfo(myStatusMessageLine1, myStatusMessageLine2);
      #endif
    }
    else if (myReceivedSerialDataString.startsWith("[URGENT]"))
    {
      if (mySerialReceivedData_Old.equals(myReceivedSerialDataString))
         return;
      mySerialReceivedData_Old = myReceivedSerialDataString;
      myReceivedSerialDataString.remove(0, String("[URGENT]").length());
      if (myReceivedSerialDataString.indexOf("[NEWLINE]") >= 0)
      {
        myStatusMessageLine2 = myReceivedSerialDataString.substring(myReceivedSerialDataString.indexOf("[NEWLINE]") + 9);
        myStatusMessageLine1 = myReceivedSerialDataString.substring(0, myReceivedSerialDataString.indexOf("[NEWLINE]"));
      }
      else myStatusMessageLine1 = myReceivedSerialDataString;
      #ifdef HASDISPLAY
        drawUrgent(myStatusMessageLine1, myStatusMessageLine2);
      #endif
    }
    else if (myReceivedSerialDataString.startsWith("[POWEROFFIMAGE]"))
    {
      if (mySerialReceivedData_Old.equals(myReceivedSerialDataString))
        return;
      mySerialReceivedData_Old = myReceivedSerialDataString;
      #ifdef HASDISPLAY
        drawPowerOFFImage();
      #endif
    }
    else if (myReceivedSerialDataString.startsWith("[LED]"))
    {
      myReceivedSerialDataString.remove(0, String("[LED]").length());
      LED_RED_BLINK = false;
      LED_GREEN_BLINK = false;
      switchLED(myReceivedSerialDataString);
    }
    else if (myReceivedSerialDataString.startsWith("[WIFIMODUS]"))
    {
      myReceivedSerialDataString.remove(0, String("[WIFIMODUS]").length());
      startWIFIServerForOTA(myReceivedSerialDataString);
    }
    else if (myReceivedSerialDataString.startsWith("[REBOOT]"))
    {
      ESP.restart();
      sleep(10);
    }
         
    else if (myReceivedSerialDataString.startsWith("[STATUS]"))
    {
      if (mySerialReceivedData_Old.equals(myReceivedSerialDataString))
         return;
      mySerialReceivedData_Old = myReceivedSerialDataString;
      myReceivedSerialDataString.remove(0, String("[STATUS]").length());
      myStatusMessageLine1 = getSubString(myReceivedSerialDataString, "[NEWLINE]", 0);
      myStatusMessageLine2 = getSubString(myReceivedSerialDataString, "[NEWLINE]", 1);
      myStatusMessageLine3 = getSubString(myReceivedSerialDataString, "[NEWLINE]", 2);
      myStatusMessageLine4 = getSubString(myReceivedSerialDataString, "[NEWLINE]", 3);
      #ifdef HASDISPLAY
        if (myStatusMessageLine4.equals(""))
          draw3Liner(myStatusMessageLine1, myStatusMessageLine2, myStatusMessageLine3);
        else
          drawStatus(myStatusMessageLine1, myStatusMessageLine2, myStatusMessageLine3, myStatusMessageLine4);
      #endif
    }
    #ifdef HASDISPLAY
      display.powerOff();
    #endif
};

Der Rest sind halt nur ein paar Scripte auf dem TrueNAS selber das halt alles nichts wirklich aufregendes.
 

Anhänge

Zuletzt bearbeitet:
Schicklich und eine nette Spielerei bzw. Add-On :)
Mal eine etwas andere Frage, die etwas aus dem Kontext ist: Was zum Henker sichert man mit 422TB bzw 300TB 😁? Private Filmsammlung der letzten 30 Jahre in 4k 😁?
 
hehe ne ich mach mit jemand mit dem ich zusammen studiert habe halt immer ein paar so Hobbyspass Projekte bei denen man ab und zu massig Platz braucht - und massig heisst halt ~ 60-80 TByte - die sichere ich dann 3-fach wenn die viel Rechenleistung gebraucht haben und lange wieder brazchen zur Rekonstruktion - eine (Fremd-) Film oder Mediensammlung braucht man in der Schweiz nicht, weil man wegen des im Vergleich zu D liberalen Urheberrechts solange man nicht verteilt das ganz legal bei Bedarf z.b. aus dem Usenet saugen darf - und bei 1 Gbit bis 25 Gbit lohnt sich das nicht mehr daheim zu lagern.

Mein Freund mit dem ich die Projekte mache hat dafür extremst viel Rechenleistung :D so gleicht sich das aus,
 
Zuletzt bearbeitet:
  • Gefällt mir
Reaktionen: Domski
Hehe naja inzwischen musste ich noch ein OTA Update Firmware Funktion nachrüsten weil ich beim finalen festzurren des ganzen TrueNAS-Rechners das dann falsch herum eingebaut habe und die Anzeige dann auf dem Kopf stand :D :D ist halt symetrisch gebaut - und ich dachte waaaahhh gerade mal endlich alle Schrauben reingemacht - die USB Verkabelung ist halt intern und geht von den Mainboardsteckern weg.

Naja geht ja zum Glück recht einfach dann temporär einen WebServer für OTA auf dem ESP aufzumachen.
 
Zurück
Oben