Welcome to MattzoBricks Forums MattzoBricks General Forum Projekt: Layout Statusanzeige

Viewing 14 reply threads
  • Author
    Posts
    • #2918
      Matthias EnderMatthias Ender
      Participant

      In meiner Legoanlage setze ich auf eine Reihe von batteriebetrieben MattzoLayoutControllern deren Funktion ich natürlich überwachen möchte.

      RocRail läuft bei mir auf einem RasBerry Pi 4, sodass die ganze Anlage am Ende ohne PC betrieben werden kann. Also nur mit einem Tablet und diesem RocRail Webinterface.

      Damit das klappt brauche ich natrürlich eine Überwachung der Kontroller:

      Meine erste Version hier ist eine HTML Seite, welche die Kontroller anpingt und damit feststellt ob diese eingeschaltet sind:

      Server-Test

      <!DOCTYPE html>
      <html lang="de">
        <head>
          <meta charset="utf-8">
          <meta name="viewport" content="width=device-width, initial-scale=1.0">
          <title>Status Mattzo Controller</title>
      	<script>
      		function ping(ip,fieldName) {
      			document.getElementById(fieldName).innerHTML = "";
      
      			url = "http://" + ip + "/gwrsg" + Math.random().toString(36).substring(7);
      
      			var httpRequest = new XMLHttpRequest();
      		
      			httpRequest.onreadystatechange = function() {
      
      				if (httpRequest.readyState == 4) {
      					document.getElementById(fieldName).innerHTML = "<span style='color:green'>ONLINE</span>";
      				}
      			}
      
      			httpRequest.ontimeout = function() {
      				document.getElementById(fieldName).innerHTML = "<span style='color:red'>OFFLINE</span>";
      			}
      			
      			httpRequest.timeout = 9000;
      			httpRequest.open("GET", url, true);
      			httpRequest.send();
      		}
      		function test(){
      				
      				ping("192.168.178.93","statusServer0"); 
      				ping("192.168.178.103","statusServer1"); 
      				ping("192.168.178.117","statusServer2"); 
      				ping("192.168.178.104","statusServer3"); 
      				ping("192.168.178.107","statusServer4"); 
      				ping("192.168.178.109","statusServer5"); 
      				
      		};
      	</script>
        </head>
        <body onload="test();">
      	  <table>
      		  <tr>
      			<th>System</th>
      			<th>Status</th>
      		  </tr>
      		  <tr>
      			<td>RocRailServer</td>
      			<td><div id="statusServer0"></div></td>
      		  </tr>
      		  <tr>
      			<td>Train Controller</td>
      			<td><div id="statusServer1"></div></td>
      		  </tr>
      		  <tr>
      			<td>LayoutController 1</td>
      			<td><div id="statusServer2"></div></td>
      		  </tr>
      		  <tr>
      			<td>LayoutController 2</td>
      			<td><div id="statusServer3"></div></td>
      		  </tr>
      		  <tr>
      			<td>LayoutController 3</td>
      			<td><div id="statusServer4"></div></td>
      		  </tr>
      		  <tr>
      			<td>LayoutController 4</td>
      			<td><div id="statusServer5"></div></td>
      		  </tr>
      	  </table>
      	  <input type="submit" value="Reload" onclick="test()"> 
        </body>
      </html>
      • This topic was modified 3 years ago by Matthias EnderMatthias Ender.
      • This topic was modified 2 years, 10 months ago by Thomas RodriguesMax.
    • #2920
      Matthias EnderMatthias Ender
      Participant

      Um das ganze zu erweitern möchte ich jetzt die Kontroller so erweitern, dass diese mir ein Statusfeedback geben. D.h. die MattzoLayoutController sollen mir bei einem GET Request das Batterielevel zurückgeben und der MTC4PU soll mir sagen, welche Züge aktuell verbunden sind. Ggf. gerne auch mit dem Batterielevel der Züge.

      Hat da jemand von euch Ahnung, wie ich sowas programmiere?

    • #2921
      Thomas RodriguesMax
      Participant

      Ich hatte in Matzes Videos den Batteriestatus nativ mal in Rocrail gesehen. Allerdings war dies dann ein Zug Controller..

    • #2923
      Matthias EnderMatthias Ender
      Participant

      So, das ganze geht vorwärts:
      status

      Jetzt habe ich irgendeine Spannung bei den LayoutControllern und meine Züge. Nun muss ich mal die Spannung beobachten und schauen wie ich an den Batteriestatus bei den Zügen rankomme.

      Die werden ja regelmäßig abgefragt und dann ins Log geschrieben. Ich muss die irgendwie Speichen ums sie dann beim HTTP Request abzurufen.

      Dann mal schauen, wie ich euch den Quellcode teilen kann, wenn das jemanden interessiert.

      EDIT:
      Achso, diese HTML Seite ist natürlich nur ein Zwischenschritt. Am Ende soll ein Arduino mit Bildschirm den Status der Kontroller und Züge anzeigen.

    • #2924
      Matthias EnderMatthias Ender
      Participant

      2 Stunden später:
      statusV2

    • #2948
      Matthias EnderMatthias Ender
      Participant

      Nicht ganz einfach, aber auch keine Raketenwissenschaft:

      c34f7418-cf22-4eb2-8143-a1a34f749e9b

      Wie gesagt, wenn jemand interessiert wie ich das realisiert habe, dann meldet euch hier.

      • #2949
        Thomas RodriguesMax
        Participant

        Ich finde die Lösung wirklich sehr schick!

        Wie hast dus realisiert?

    • #2966
      Matthias EnderMatthias Ender
      Participant

      Ok, dann versuche ich mich mal im Erklären:

      Zunächst das Prinzip:
      prinzip

      Der RocRailServer wird von mir im Moment nur angepingt. Damit weiß ich zwar nicht ob die Serversoftware wirklich läuft, allerdings weiß ich ob der Rechner an ist und ob er mit dem WLAN verbunden ist.

      Die MattzoController werden allerdings mit einem HTTP Request angefragt. Als Antwort kommt ein JSON zurück. Diese JSON Daten geben mir dann etwas mehr Informationen.
      Wenn ich also in den Browser die IP Adresse vom TrainServer eingebe, kommt folgende Antwort:
      Die Rohdaten sehen so aus:
      json2

      Und wenn man das etwas sauberer aufschreibt, sieht das so aus:

      json1
      Dabei ist das “isConnected” 0 wenn der Zug Offline ist und 1 wenn der Zug verbunden ist. Ausserdem wird dann bei batteryLevel eine Zahl zwischen 0 und 100 übertragen, was das BatteryLevel darstellt.

      Bei den LayoutControllern sieht das etwas einfacher aus:
      json3

      json4

      Man könnte auch eine komplette HTML Seite anzeigen, aber das wäre schwer maschinell zu lesen. Deshalb verwende ich dort diese JSONs.

    • #2967
      Matthias EnderMatthias Ender
      Participant

      Die Realisierung besteht nun also aus 3 Teilen.
      1. Anpassung der MattzoLayoutController
      2. Anpassung der MTC4PU
      3. Displaybau

      1. Teil MattzoLayoutController

      Hier wiederum habe ich 2 Anpassungen gemacht.
      1.1. Spannung Messen
      1.2. HTTP Response

      1.1. Spannung Messen
      Ich habe mich an folgende Anleitung gehalten um die Spannung zu messen:
      Quelle

      Als erstes wird die Kontrollerspannung mit dem A0 verbunden:
      d867b6d4-3d7e-4fbc-9cba-afdc17e765bf

      und dann kann man mit folgenden Zeilen Code die Spannung auslesen:
      <a href="https://ibb.co/ZBmctMX"><img src="https://i.ibb.co/ZBmctMX/d867b6d4-3d7e-4fbc-9cba-afdc17e765bf.jpg" alt="d867b6d4-3d7e-4fbc-9cba-afdc17e765bf" border="0" /></a>

      Also wenn die Funktion checkVoltage() aufruft ist dannach die aktuelle Spannung als String in Ubatt gespeichert.

      1.2. HTTP Response

      Um den HTTP Response zu erzeugen muss zunächst ein WIFI Server initialisiert werden
      WiFiServer server(80);

      Dieser wird gestartet, wenn das WIFI verbunden ist:
      server.begin();

      Dann gibt es ein Funktion, welche in der loop() Funktion aufgerufen wird und prüft ob eine Anfrage reinkommt:

      void HTTPLoop(){
        WiFiClient client = server.available();
        if (!client) {
          return;
        }
        client.flush();
        webpage(client);
      }

      Diese Funktion ruft die Funktion webpage auf, wenn eine Antwort gesendet wird.

      Die Funktion “webpage” prüft zunächst die Spannung und baut dann die JSON Antwort zusammen:

      void webpage(WiFiClient client){/* function webpage */ 
         checkVoltage();
         client.println("HTTP/1.1 200 OK");
         client.println("Access-Control-Allow-Origin: *");   
         client.println("Access-Control-Allow-Methods: GET");
         client.println("Content-Type: application/json");
         client.println("");
         client.println("{\"type\":\"layout\",\"status\":true,\"batLevel\":" + Ubatt + "}"); 
      }

      Der gesamte Code ist dann hier:

      
      WiFiServer server(80);
      bool globalLastKnownWifiConnectedStatus = false;
      String Ubatt = "";
      ADC_MODE(ADC_VCC);
      
      void checkVoltage(){
        uint16_t my_getVcc_Voltage = ESP.getVcc();
        float_t my_Voltage_calculated = ((float)my_getVcc_Voltage/1024.0f);
        Ubatt = String(my_Voltage_calculated, 3);
      }
      
      void webpage(WiFiClient client){/* function webpage */ 
         checkVoltage();
         client.println("HTTP/1.1 200 OK");
         client.println("Access-Control-Allow-Origin: *");   
         client.println("Access-Control-Allow-Methods: GET");
         client.println("Content-Type: application/json");
         client.println("");
         client.println("{\"type\":\"layout\",\"status\":true,\"batLevel\":" + Ubatt + "}"); 
      }
      
      void HTTPLoop(){
        WiFiClient client = server.available();
        if (!client) {
          return;
        }
      //  while(!client.available()){
      //    delay(1);
      //    Serial.println("HTTP Server ERROR");
      //  }
        client.flush();
        webpage(client);
      }
      
      void checkHTTPServerStart() {
        if (WiFi.status() != WL_CONNECTED && globalLastKnownWifiConnectedStatus) {
          globalLastKnownWifiConnectedStatus = false;
        }
        else if (WiFi.status() == WL_CONNECTED && !globalLastKnownWifiConnectedStatus) {
          globalLastKnownWifiConnectedStatus = true;
          server.begin();
          Serial.println("HTTP Server started");
        }
        if (WiFi.status() == WL_CONNECTED) {
          HTTPLoop();
        }
      }

      Dieser Code wird vor die “void loop()” Funktion koppiert und innerhalb der loop-Funktion aufgerufen:

      void loop() {
        loopMattzoController();
      
        checkHTTPServerStart();
          
        checkEnableServoSleepMode();
        monitorSensors();
        levelCrossingLoop();
        basculeBridgeLoop();
      }

      Nun antworten die LayoutController auf einen HTTP Request wie benötigt. Es lässt sich über den Aufruf der IP im Browser testen.

    • #2968
      Matthias EnderMatthias Ender
      Participant

      2. Anpassung der MTC4PU

      Die Layoutcontroller waren noch einfach, jetzt wird es etwas Komlizierter:

      Zunächst muss die Klasse MattzoPUHub angepasst werden:
      Das Abrufen des Batterylevels kann zwar schon ausgeführt werden, bisher wird das aber nicht gespeichert. Deshalb bekommt die Klasse zunächst einen neuen Parameter:
      String batteryLevel = "0";
      Dann brauche ich zwei neue Zugriffe auf Parameter:

      
      String getName() {
        return _hubName;
      }
      
      String getAddress() {
        return _macAddress;
      }
      

      Es muss die Konfigration des MTC4PU angepasst werden.
      1. Soll der MTC4PU das Batterylevel auslesen und das auch alle 10 Sekunden:

      
      const bool REPORT_BATTERYLEVEL = true;          // set to true or false to allow or omit battery level reports
      const int SEND_BATTERYLEVEL_INTERVAL = 10000;
      

      ^^ Diese Zeilen werden nur abgeändert.

      Um den Log nicht zuzumüllen entferne ich das Logging des Batterylevel aus der requestPoweredUpBatteryLevel() Funktion:

      
      //mcLog2("Requesting battery level for hub " + String(nextBatteryLevelReportingHub), LOG_DEBUG);
      

      Die Funktion hubPropertyChangeCallback() habe ich so angepasst, dass sie erstens nichts mehr ins Log schreibt und zweitens das Batterylevel im MattzoPUHub Objekt abspeichert:

      
      void hubPropertyChangeCallback(void* hub, HubPropertyReference hubProperty, uint8_t* pData)
      {
        Lpf2Hub* myHub = (Lpf2Hub*)hub;
        String hubAddress = myHub->getHubAddress().toString().c_str();
        //mcLog("PU Message received from " + hubAddress + ", hub property " + String((byte)hubProperty, HEX));
      
        for (int i = 0; i < NUM_HUBS; i++) {
          if(myHubs[i].getAddress()==hubAddress){
            //mcLog("Hub found!!");
            if (hubProperty == HubPropertyReference::BATTERY_VOLTAGE){
              myHubs[i].batteryLevel=String(myHub->parseBatteryLevel(pData), DEC);
              mcLog(myHubs[i].getName() + " BatteryLevel: " + myHubs[i].batteryLevel);
            }
          }
        }
      
        if (hubProperty == HubPropertyReference::BATTERY_VOLTAGE)
        {
          //mcLog("BatteryLevel: " + String(myHub->parseBatteryLevel(pData), DEC));
          sendMQTTMessage("roc2bricks/battery", hubAddress + " " + myHub->parseBatteryLevel(pData));
          return;
        }
      
        if (hubProperty == HubPropertyReference::BUTTON)
        {
          //mcLog("Button: " + String((byte)myHub->parseHubButton(pData), HEX));
          sendMQTTMessage("roc2bricks/button", hubAddress + " button pressed.");
          return;
        }
      }
      

      Nun kommt der HTTP Response so ähnlich wie beim LayoutController. Die JSON ist etwas komplexer aber sonst ist das ziemlich ähnlich:

      WiFiServer server(80);
      bool globalLastKnownWifiConnectedStatus = false;
      
      void webpage(WiFiClient client){
         client.println("HTTP/1.1 200 OK");
         client.println("Access-Control-Allow-Origin: *");   
         client.println("Access-Control-Allow-Methods: GET");
         client.println("Content-Type: application/json");
         client.println("");
         client.print("{\"type\":\"train\",\"status\":true, \"Hubs\":["); 
         for (int i = 0; i < NUM_HUBS; i++) {
            client.print("{\"" + myHubs[i].getName() + "\": ");
              client.print("{\"isConnected\": " + String(myHubs[i].isConnected()) + ", \"batteryLevel\": \"" + myHubs[i].batteryLevel + "\"}");   
            client.print("}");
            if(i+1<NUM_HUBS){
              client.print(",");
            }
         }
         client.println("]}"); 
      }
      
      void HTTPLoop(){
        WiFiClient client = server.available();
        if (!client) {
          return;
        }
        client.flush();
        webpage(client);
      }
      
      void checkHTTPServerStart() {
        if (WiFi.status() != WL_CONNECTED && globalLastKnownWifiConnectedStatus) {
          globalLastKnownWifiConnectedStatus = false;
        }
        else if (WiFi.status() == WL_CONNECTED && !globalLastKnownWifiConnectedStatus) {
          globalLastKnownWifiConnectedStatus = true;
          server.begin();
          Serial.println("HTTP Server started");
        }
        if (WiFi.status() == WL_CONNECTED) {
          HTTPLoop();
        }
      }

      Dieser Code gehört vor die loop() Funktion und auch hier wird die LoopFunktion angepasst:

      
      void loop() {
        loopMattzoController();
      
        checkHTTPServerStart();
        
        sendDiscoveredHub2mqtt();
        connectPoweredUpHubs();
        requestPoweredUpBatteryLevel();
        accelerateTrainSpeed();
        setLights();
      
        debugInfo();
      }

      Nun antwortet auch der Traincontroller, so wie er es soll.

      Nochmal zusammengefasst:

      Anpassung der Klasse:
      klasse

      Anpassung der Konfig:
      konfig

      Die Funktionen:
      funktionen

      und der Response:
      response

    • #2969
      Matthias EnderMatthias Ender
      Participant

      Jetzt funktioniert die HTML Seite:

      <!DOCTYPE html>
      <html lang="de">
        <head>
          <meta charset="utf-8">
          <meta name="viewport" content="width=device-width, initial-scale=1.0">
          <title>Status Mattzo Controller</title>
      	<script>
      		var controllers = {
      			"RocRailServer":"192.168.178.93",
      			"Train Controller":"192.168.178.103",
      			"LayoutController 1":"192.168.178.117",
      			"LayoutController 2":"192.168.178.104",
      			"LayoutController 3":"192.168.178.107",
      			"LayoutController 4":"192.168.178.109"
      		}
      	
      		var siteBuild=false;
      		
      		function ping(ip,fieldName) {
      		
      			if(!siteBuild){
      				document.getElementById(fieldName).innerHTML = "";
      			}
      
      			url = "http://" + ip + "/?rand=" + Math.random().toString(36).substring(7);
      
      			var httpRequest = new XMLHttpRequest();
      		
      			httpRequest.onreadystatechange = function() {
      
      				if (httpRequest.readyState == 4) {
      					if (httpRequest.status == 200) {
      						var jsonArray = JSON.parse(httpRequest.responseText);
      						decodeJson(fieldName,jsonArray);
      					}else{
      						document.getElementById(fieldName).innerHTML = "<span style='color:green'>ONLINE</span>";
      					}
      				}
      			}
      
      			httpRequest.ontimeout = function() {
      				document.getElementById(fieldName).innerHTML = "<span style='color:red'>OFFLINE</span>";
      				document.getElementById(fieldName + "2").innerHTML = "";
      			}
      			
      			httpRequest.timeout = 5000;
      			httpRequest.open("GET", url, true);
      			httpRequest.send();
      		}
      		
      		function setTrains(hubs){
      			var out = "<table><tr><th>Zug</th><th>Status</th><th>Battery</th></tr>"
      			hubs.forEach(hub => 
      				Object.keys(hub).forEach(key => {
      					out += "<tr>";
      					out += "<td>" + key + "</td>";
      					out += "<td>";
      					if(hub[key]["isConnected"]==1){
      						out += "<span style='color:green'>ONLINE</span>";
      					}else{
      						out += "<span style='color:red'>OFFLINE</span>";
      					}
      					out += "</td>";
      					out += "<td>";
      					out += hub[key]["batteryLevel"]
      					out += "</td>"
      					out += "</tr>";
      				})
      			);
      			out += "</table>";
      			document.getElementById("trains").innerHTML = out;			
      		}
      		
      		function decodeJson(fieldName,jsonArray){
      			if("type" in jsonArray){
      				switch (jsonArray["type"]) {
      				  case "layout":
      					document.getElementById(fieldName).innerHTML = "<span style='color:green'>ONLINE</span>";
      					document.getElementById(fieldName + "2").innerHTML = jsonArray["batLevel"];
      					break;
      				  case "train":
      					document.getElementById(fieldName).innerHTML = "<span style='color:green'>ONLINE</span>";
      					setTrains(jsonArray.Hubs);
      					break;
      				  default:
      					document.getElementById(fieldName).innerHTML = "<span style='color:green'>ONLINE</span>";
      					break;
      				}
      			}
      		};
      		
      		function test(){
      			var out = "<table><tr><th>System</th><th>Status</th><th>Volt</th></tr>";
      			console.log(controllers);
      			var i = 0;
      			Object.keys(controllers).forEach(key => {
      				i++;
      				out += "<tr>";
      				out += "<td>" + key + "</td>";
      				out += "<td id=\"controller" + i + "\">";
      				out += "</td>";
      				out += "<td id=\"controller" + i + "2\">";
      				out += "</td>";
      				out += "</tr>";
      			});
      			out += "</table>";
      			if(!siteBuild){
      				document.getElementById("controller").innerHTML = out;
      				siteBuild=true;
      			}
      			
      			
      			i = 0;
      			Object.keys(controllers).forEach(key => {
      				i++;
      				ping(controllers[key],"controller" + i); 
      			});
      		};
      	</script>
        </head>
        <body onload="test();">
      	<div style="float: left;margin:20px;margin-right: 50px;">
      	  <div id="controller"></div>
      	  <div style="margin-top:20px;">
      		<input type="submit" value="Reload" onclick="test()"> 
      	  </div>
      	</div>	
      	<div id="trains" style="padding:20px"></div>
        </body>
      </html>
      
    • #2970
      Matthias EnderMatthias Ender
      Participant

      3. Displaybau

      Nun kommt der komplizierteste Part.

      Dabei sind die Bauteile recht einfach:
      – Display
      – Controller(Der selbe wie die LayoutController)
      – Batteriebox
      – Akkus
      Und gelötet werden muss auch nicht 😀

      Meine Quellen waren:
      Youtube
      Fontgenerator fürs Display
      JSON Assistent
      Pinger für ESP8266

      Im Prinzip habe ich gemacht, was in dem Youtube Video erklärt wird:
      – zunächst von https://nextion.tech/ den Nextion Editor geladen und installiert.
      – dann mit dem Fontgenerator eine Schrift erstellt:
      font
      – Im Editor habe ich dann ein Template für das Display erstellt:
      nextion
      Dabei sind im Hintergrund als Bild die ganzen Texte.
      Die Elemente hub1-hub6 und train1-train4 sind Bilder. Hier wechsel ich das Bild von leer zu offline oder online.
      Die Elemente hub3v-hub6v und train1v-train4v sind Textboxen, da schreibe ich die Spannung oder den Status jeweils rein.
      Das Element status ist ebenfalls eine Textbox.
      Das Element process ist eine Progressbar.

      Jetzt das ganze Ding speichern und dann mit einer MicroSD Karte auf das Display übertragen. Wie das geht wird im Video ja erklärt.

      Wie das Angeschlossen wird, wird auch im Video erklärt. Ist nich kompliziert. Hier ist nur zubeachten, dass man kein Programm auf den Kontroller spielen kann, wenn das Display angeschlossen ist.

      Und dann der Quellcode für den Kontroller:

      #include <ESP8266WiFi.h>
      #include <Pinger.h>
      #include <ESP8266HTTPClient.h>
      #include <ArduinoJson.h>
      
      extern "C"
      {
        #include <lwip/icmp.h> // needed for icmp packet definitions
      }
      
      Pinger rocPinger;
      
      char ssid[] = "WLANN SSID";
      char pass[] = "WLAN PASSWORT";
      WiFiServer server(80);
      IPAddress ip(192, 168, 178, 80);
      IPAddress gateway(192, 168, 178, 1);
      IPAddress subnet(255, 255, 255, 0);
      
      void setup() {
        Serial.begin(9600);
        resetDisplay();
        sendstring("status.txt","OFFLINE");
        sendint("status.pco",63650);
        WiFi.config(ip, gateway, subnet);
        WiFi.begin(ssid, pass);
        while (WiFi.status() != WL_CONNECTED) {
          delay(500);
        }
        server.begin();
        sendstring("status.txt","ONLINE");
        sendint("status.pco",5248);
      
        rocPinger.OnReceive([](const PingerResponse& response)
        {
          if (response.ReceivedResponse){
            sendint("hub1.pic",2);
          }else{
            sendint("hub1.pic",3);
          }
          return true;
        });
      }
      
      String data;
      bool pingResult;
      
      void loop() {
        HTTPClient http;
        StaticJsonDocument<512> doc;
        DeserializationError error;
        int httpCode;
        String json;
        float batLevel;
          
        //RocRailServer 192.168.178.93
        rocPinger.Ping("192.168.178.93",1);
        sendint("process.val",16);
      
       //TrainServer 192.168.178.103
        http.begin("http://192.168.178.103/?rand=2222");
        httpCode = http.GET();
       
        if (httpCode > 0) {
          json = http.getString();
          error = deserializeJson(doc, json);
          
          if (error) {
            sendint("hub2.pic",3);
          }else{
            JsonArray Hubs = doc["Hubs"];
            if(Hubs[0]["CityExpress"]["isConnected"]==1){
              sendint("train1.pic",2);
              sendstring("train1v.txt",Hubs[0]["CityExpress"]["batteryLevel"]);
            }else{
              sendint("train1.pic",3);
              sendstring("train1v.txt","");
            }
      
            if(Hubs[1]["CityCargo"]["isConnected"]==1){
              sendint("train2.pic",2);
              sendstring("train2v.txt",Hubs[1]["CityCargo"]["batteryLevel"]);
            }else{
              sendint("train2.pic",3);
              sendstring("train2v.txt","");
            }
            
            if(Hubs[2]["BR23"]["isConnected"]==1){
              sendint("train3.pic",2);
              sendstring("train3v.txt",Hubs[2]["BR23"]["batteryLevel"]);
            }else{
              sendint("train3.pic",3);
              sendstring("train3v.txt","");
            }
      
            if(Hubs[3]["Krokodil"]["isConnected"]==1){
              sendint("train4.pic",2);
              sendstring("train4v.txt",Hubs[3]["Krokodil"]["batteryLevel"]);
            }else{
              sendint("train4.pic",3);
              sendstring("train4v.txt","");
            }
      
            sendint("hub2.pic",2);
          }
        }else{
          sendint("hub2.pic",3);
        }
       
        http.end();
        sendint("process.val",33);  
      
        //Layout Server 1 192.168.178.117
        http.begin("http://192.168.178.117/?rand=2222");
        httpCode = http.GET();
       
        if (httpCode > 0) {
          json = http.getString();
          error = deserializeJson(doc, json);
          
          if (error) {
            sendint("hub3.pic",3);
          }else{
            sendstring("hub3v.txt",doc["batLevel"]);
            sendint("hub3.pic",2);
          }
        }else{
          sendint("hub3.pic",3);
        }
       
        http.end();
        sendint("process.val",50);
      
        //Layout Server 2 192.168.178.104
        http.begin("http://192.168.178.104/?rand=2222");
        httpCode = http.GET();
       
        if (httpCode > 0) {
          json = http.getString();
          error = deserializeJson(doc, json);
          
          if (error) {
            sendint("hub4.pic",3);
          }else{
            sendstring("hub4v.txt",doc["batLevel"]);
            sendint("hub4.pic",2);
          }
        }else{
          sendint("hub4.pic",3);
        }
       
        http.end();
        sendint("process.val",66);
        
        //Layout Server 3 192.168.178.107
        http.begin("http://192.168.178.107/?rand=2222");
        httpCode = http.GET();
       
        if (httpCode > 0) {
          json = http.getString();
          error = deserializeJson(doc, json);
          
          if (error) {
            sendint("hub5.pic",3);
          }else{
            sendstring("hub5v.txt",doc["batLevel"]);
            sendint("hub5.pic",2);
          }
        }else{
          sendint("hub5.pic",3);
        }
       
        http.end();
        sendint("process.val",83);
        
        //Layout Server 4 192.168.178.109
        http.begin("http://192.168.178.109/?rand=2222");
        httpCode = http.GET();
       
        if (httpCode > 0) {
          json = http.getString();
          error = deserializeJson(doc, json);
          
          if (error) {
            sendint("hub6.pic",3);
          }else{
            sendstring("hub6v.txt",doc["batLevel"]);
            sendint("hub6.pic",2);
          }
        }else{
          sendint("hub6.pic",3);
        }
       
        http.end();
        sendint("process.val",100);
        
      }
      
      void resetDisplay(){
        sendstring("status.txt","");
        sendint("process.val",0);
        sendint("hub1.pic",1);
        sendint("hub2.pic",1);
        sendint("hub3.pic",1);
        sendint("hub4.pic",1);
        sendint("hub5.pic",1);
        sendint("hub6.pic",1);
        sendint("train1.pic",1);
        sendint("train2.pic",1);
        sendint("train3.pic",1);
        sendint("train4.pic",1);
      }
      
      void sendstring(String field, String value){
        data = field + "=\"" +value + "\"";
        Serial.write(0xff);
        Serial.write(0xff);
        Serial.write(0xff);
        Serial.print(data);
        Serial.write(0xff);
        Serial.write(0xff);
        Serial.write(0xff);
        Serial.println();
      }
      
      void sendint(String field, int value){
        data = field + "=" +value + "";
        Serial.write(0xff);
        Serial.write(0xff);
        Serial.write(0xff);
        Serial.print(data);
        Serial.write(0xff);
        Serial.write(0xff);
        Serial.write(0xff);
        Serial.println();
      }

      In den Code müsst ihr euch leider etwas einarbeiten:
      Die Bibliotheken Pinger.h, ESP8266HTTPClient.h und ArduinoJson.h installieren.
      Die Funktionen sendstring() und sendint() senden die Steuersigale an das Display zum Ändern der Bilder bzw. Texte.
      Der Pinger ist dafür da, den RocRailServer anzupingen.
      Mit dem ArduinoJson müsst ihre euch etwas beschäftigen. Ist ziemlich komplex.
      Im Prinzip resettet das Programm am Anfang das Display und dann werden der Reihe nach alle Kontroller abgefragt und die Anzeige entsprechend ans Display gesendet. Wenn alle Abgefragt wurden, gehts von vorne los.

      Jetzt noch etwas Lego und fertig ist die Kontrolleinheit.
      ff858281-3dc4-4d52-8b42-ca005d67c7b1

    • #2971
      Matthias EnderMatthias Ender
      Participant

      Sollte jemand von euch das Projekt so, oder so ähnlich nachbauen würde ich mich freuen, wenn ihr davon berichtet.

    • #2972
      Thomas RodriguesMax
      Participant

      Hallo Matthias,

      vielen Dank nochmal für die ausführliche Anleitung!
      Hat mich direkt dazu verleitet größer zu denken und ein paar Sachen zu bestellen.
      Das Display werde ich nicht nachbauen. Aber die Website ist für mich eine klasse Anwendung!!

    • #5005
      Thorsten SchmeiserThorsten
      Participant

      Hallo Matthias,

      Super Projekt von dir. Habe es wegen der Batterieanzeige der Züge bis Punkt 2 nachgebaut.
      Punkt 3 habe ich erstmal weggelassen.

      Der Batteriestatus der Züge wird Prima angezeigt.

      Liebe Grüße

      Thorsten

    • #5556
      Thorsten SchmeiserThorsten
      Participant

      Gibt es auch die Möglichkeit den Batteriestatus der Züge in MTC4BT zu Integrieren, hat das vielleicht schon jemand gemacht ?

      Lg

      • This reply was modified 1 year, 5 months ago by Thorsten SchmeiserThorsten.
Viewing 14 reply threads
  • You must be logged in to reply to this topic.