mac70
Published © CC BY-NC-SA

Homematic Display Clock

An Arduino based self-setting clock which can display temperature and other data from Homematic systems.

IntermediateFull instructions provided6 hours5,797
Homematic Display Clock

Things used in this project

Hardware components

Arduino MKR Wifi 1010
×1
Adafruit 4-Digit 7-Segment Display with I2C Backpack - bright White
×1
Adafruit Bicolor 8x8 LED Square Pixel Matrix with I2C Backpack
×1
LiPo Battery with connector JST PHR-2 (3,7 V; 1200mAh)
×1

Software apps and online services

Arduino IDE
Arduino IDE

Story

Read more

Schematics

Homematic Display Clock Schematics

Homematic Display Clock Breadboard

Code

Homematic Display Clock main source code (V8)

C/C++
the Arduino code, new version V8 : added WiFi commands for GMT/DST settings
/*
Homematic Clock Display 
=======================

An interactive clock display for Homematic with WiFi Control 
Based on the Arduino MKR WiFi 1010 Board 

Features :
- accurate, self-setting clock (accesses NTP internet time service to set the RTC of the microcontroller)
- receives and displays 2 temperatures (inside and outside) from Homematic (or similar smart-home systems) 
- displays time, date and temperatures on bright 7-segment-LED displays
- 7-segment LEDs will be dimmed at night time (programmable)
- an additional 8x8 bicolor dot-matrix display shows status symbols (e.g. WiFi, Temperature or NTP updates etc)
- can display additional information (e.g. I added a visual door-bell triggered from my Homematic door-bell sensor) 
- can be controlled via Webpage (access in local WiFi using the IP address or router symbolic name)
- has a backup battery, measures supply voltage and battery level (remaining %) and knows when it's USB-powered

V1 16.10.2021 initial version with 16x2LCD and 2x white 7-seg displays for time&date
V2 23.10.2021 add additional displays: 8x8 matrix and 2x 7-seg displays for temperature
V3 24.10.2021 better HTML menu , remote temperature setting and changed to different temp 7-seg displays
V4 01.11.2021 Watchdog implemented : need to reset after USB-repowering (BQ24195 charger IC goes in safe mode=current limited!)
V5 04.11.2021 Startup improved, WiFi connection status check added
V6 13.11.2021 fixed "WiFi repeating effect", deleted LCD, swap 7seg positions, different reset method, add log buffer
V7 05.12.2021 fix of minor issues and brush up 
V8 27.03.2022 added commands for GMT and DST correction 

future to do's:
- automatic DST correction

https://www.hackster.io/mac70/projects
mac70 March 2022
  
*/

#include <WiFiNINA.h>
#include <RTCZero.h>
#include <Wire.h>
#include <WDTZero.h>
#include <Adafruit_GFX.h>
#include "Adafruit_LEDBackpack.h"
#include "LedControl.h"

// -----------------------------------------------------------------------------------------
// USER settings :

// WIFI Settings
char ssid[] = "XXX";           // your WiFi network name
char pass[] = "XXX";       // your WiFi password

// Timezone Settings
int GMT = 1;                      // adapt to your time zone (e.g. Germany is GMT+1 -> set to 1 )
int DST = 0;                      // adjust daylight saving time (default = 0 : no DST (Wintertime),... 
                                  // ...from 31-March thru 31-Oct -> set to +1)

// -----------------------------------------------------------------------------------------

const String Version = "1.8";     // Version of this module

// some instances
RTCZero rtc;                      // create instance of real time clock
WiFiServer server(80);            // create server instance
WDTZero MyWatchDoggy;             // create WDT for reset 

// Define all displays :
Adafruit_7segment Time7SegDis = Adafruit_7segment();      // 7 seg display for Time Display
Adafruit_7segment Date7SegDis = Adafruit_7segment();      // 7 seg display for Date Display
Adafruit_7segment TempL7SegDis = Adafruit_7segment();     // 7 seg display for Temp Display
Adafruit_7segment TempR7SegDis = Adafruit_7segment();     // 7 seg display for Temp Display
Adafruit_BicolorMatrix matrix = Adafruit_BicolorMatrix(); // 8x8 dot matrix display

// Variables

// status variables
int status = WL_IDLE_STATUS;    // WiFi connection status
unsigned long lastepochrec=0;   // last successful update of Epoc record
unsigned long lastNTPupdate=0;  // last update time received from NTP  
unsigned long tempupdaterec=0;  // last successful temp update time
unsigned long starttime;        // holds millis() value in setup routine

// display controls
int brightness=14;              // 7seg LED normal display brightness (0..15)
int dim_brightness=4;           // 7seg LED reduced brightness level (for night time display)
int dimstart=21;                // dimming of LEDs period start...
int dimend=6;                   // ...end time (h)
boolean drawDots = false;       // show dots on 7 seg display 
boolean drawCol = false;        // show colon on 7 seg display
int ledpin=6;                   // LED connected to pin 6
bool led1=false;                // LED status
int showdotmatrix=-1;           // indicates if something should be displayed on dot matrix

// date and time
int myhours, mins, secs;        // current time
int myday, mymonth, myyear;     // current date 
int myClock = 24;               // default is 24h (can be 12 alternativly, untested)
int dateOrder = 0;              // date format default is 0=DMY (can be set to 1=MDY, untested)
bool IsPM = false;              // only used in case of 12h clock
String resetTime;               // holds inital time&date after last reset in readable format
String currenttime,currentdate; // holds current time&date in readable format

// temperatures
float temp_in=-99.0;            // temperature value for inside ...
float temp_out=-99.0;           // ... and outside (invalid if -99)

// log buffer
const unsigned int logsize=50;  // number of lines in log buffer (can be adjusted if needed)
String loglines[logsize];       // buffer array for loglines
unsigned int logpointer=0;      // write-pointer to next line in logbuffer
signed int logstart=-logsize;   // read-pointer for complete buffer readout

// battery and ext voltage monitoring
int sensorValue;                // direct ADC channel for Bat
float voltage;                  // converted reading into real voltage 
float batlevel;                 // batlevel as remaining capacity 0...100%
float batbars;                  // batlevel as "5 bar" battery symbol 
float power5;                   // status of 5V pin (shows "on bat" or "on ext power")
boolean onbattery=false;        // indicates if no external power is connected

// some simple 8x8 bitmaps for the matrix display (stored in the following "include" file :)
#include "symbols.h"


/* --------------------------------------------------------------------------------------
 Setup after Reset
-------------------------------------------------------------------------------------- */
void setup() 
{

  starttime=millis();
  addlogentry("Start after reset t="+String(millis()-starttime, DEC));
 
  // init IOs
  analogReadResolution(12);  // set ADC resolution (4096)
  pinMode(ledpin, OUTPUT);   // for built-in LED
  
  // init UART0 for serial monitor
  Serial.begin(9600); //Initialize serial port

   // Init Time&Date 7seg displays (on I2C bus)
   Time7SegDis.begin(0x70);    // 3 Address Select pins: 0x70 thru 0x77
   Time7SegDis.setBrightness(brightness);  // 0..15
   Time7SegDis.blinkRate(3);  //  0 is no blinking. 1, 2 or 3 is for display blinking
   Time7SegDis.print(88.88);  // show "88:88" initially
   Time7SegDis.writeDisplay();
   Date7SegDis.begin(0x71);    // 3 Address Select pins: 0x70 thru 0x77
   Date7SegDis.setBrightness(brightness);  // 0..15
   Date7SegDis.blinkRate(3);  //  0 is no blinking. 1, 2 or 3 is for display blinking
   Date7SegDis.print(88.88);  // show "88:88" initially
   Date7SegDis.writeDisplay();

   // Init Temperature 7 seg display setup (on I2C bus)
   TempL7SegDis.begin(0x74);       // 3 Address Select pins: 0x70 thru 0x77 
   TempL7SegDis.setBrightness(brightness); // 0..15
   TempL7SegDis.blinkRate(0);      //  0 is no blinking. 1, 2 or 3 is for display blinking
   TempL7SegDis.drawColon(false);  // no ":" will be shown
   TempL7SegDis.writeDigitRaw(0, 0b01000000);  // display "---C" initially
   TempL7SegDis.writeDigitRaw(1, 0b01000000);
   TempL7SegDis.writeDigitRaw(3, 0b01000000);
   TempL7SegDis.writeDigitNum(4, 0xC, false); 
   TempL7SegDis.writeDisplay();    // update display
   TempR7SegDis.begin(0x73);       // 3 Address Select pins: 0x70 thru 0x77 
   TempR7SegDis.setBrightness(brightness); // 0..15
   TempR7SegDis.blinkRate(0);      //  0 is no blinking. 1, 2 or 3 is for display blinking
   TempR7SegDis.drawColon(false);  // no ":" will be shown
   TempR7SegDis.writeDigitRaw(0, 0b01000000);  // display "---C" initially
   TempR7SegDis.writeDigitRaw(1, 0b01000000);
   TempR7SegDis.writeDigitRaw(3, 0b01000000);
   TempR7SegDis.writeDigitNum(4, 0xC, false); 
   TempR7SegDis.writeDisplay();    // update display

  
    // Init 8x8 Dot Matrix Display
    matrix.begin(0x72);  // I2C address of display 
    matrix.setBrightness(15);
    matrix.blinkRate(0);
    matrix.setRotation(3);  // set rotation orientation of display - here : pin connectors are top 
    matrix.clear();
    matrix.drawPixel(0, 0, LED_RED);   // show one pixel
    matrix.writeDisplay();  // write the changes we just made to the display
     
    // first UART message
     int t = 10; //wait for serial port to open, max 5 seconds
     while (!Serial) {
        delay(500);
        if ( (t--) == 0 ) break;
     }
    Serial.print("\nHomematic Display Clock\n"); 
    Serial.println("======================="); 
    Serial.print("Version =");
    Serial.println(Version);
    
    // check if there is the WiFi module accessable
    if (WiFi.status() == WL_NO_MODULE) 
    {
     Serial.println("Fatal Error : Communication with WiFi module failed! - Abort...!!");
     addlogentry("Fatal Error : Communication with WiFi module failed!");
     matrix.print("E");
     matrix.writeDisplay();
     matrix.blinkRate(1);
     // don't continue
     while (true);
     }
    Serial.println("Found WiFi module.");

  String fv = WiFi.firmwareVersion();
  if (fv < WIFI_FIRMWARE_LATEST_VERSION) {
    Serial.println("Warning : Please upgrade the WiFi module firmware !");
    addlogentry("Warning : Please upgrade the WiFi module firmware !");
  }
  else
  {
    Serial.println("WiFi module Firmware OK.");
    addlogentry("WiFi module Firmware OK");
  }

   // print your MAC address:
  byte mac[6];
  WiFi.macAddress(mac);
  Serial.print("MAC: ");
  printMacAddress(mac);

   // show a blinking red WiFi Symbol 
  matrix.clear();
  matrix.drawBitmap(0, 0, WiFi_bmp, 8, 8, LED_RED);
  matrix.blinkRate(1);
  matrix.writeDisplay();

  // Begin WiFi
  Serial.println("Scanning available networks...");
  int numSsid = WiFi.scanNetworks();
  if (numSsid == -1) // Fatal Error: Couldn't get a WiFi connection
  {
    Serial.println("WiFi ERROR...");
    matrix.blinkRate(3);  // fast blinking WiFi symbol 
    matrix.writeDisplay();    
    while (true); // application will hang...
  }

  // print the list of networks found:
  Serial.print("number of available networks:");
  Serial.println(numSsid);

  if (numSsid == 0) // no WiFi networks found
  {
    Serial.println("!! No WiFi Networks found ... change position of device for better reception !!");
   // show a fast blinking red WiFi Symbol 
   matrix.clear();
   matrix.drawBitmap(0, 0, WiFi_bmp, 8, 8, LED_RED);
   matrix.blinkRate(3);
   matrix.writeDisplay();
   delay(1000);
  }
  else // WiFi networks found
  {
   matrix.blinkRate(0);
   matrix.writeDisplay();
  }

  // print the network number and name for each network found:
  for (int thisNet = 0; thisNet < numSsid; thisNet++) {
    Serial.print(thisNet);
    Serial.print(") ");
    Serial.print(WiFi.SSID(thisNet));
    Serial.print("\tSignal: ");
    Serial.print(WiFi.RSSI(thisNet));
    Serial.println(" dBm");
  }
  
  // connect to WiFi network
  int attempts=0;
  Serial.println("Try to connect to WiFi...");

  while (status != WL_CONNECTED) // as we need WiFi, keep trying until WiFi is connected...
  {
    if (status != WL_CONNECTED)
    {
      delay(250);
      matrix.drawPixel(7, 7, 0);  // indicate connection attempts by flashing pixel
      matrix.writeDisplay();   
    }
    Serial.print(attempts);
    Serial.print(" attempts to connect to SSID: ");
    Serial.print(ssid);

    // Connect to WPA/WPA2 network. Change this line if using open or WEP network:
    status = WiFi.begin(ssid, pass);
    // print the received signal strength:
    long rssi = WiFi.RSSI();
    Serial.print(" - signal strength (RSSI):");
    Serial.print(rssi);
    Serial.println(" dBm");
    
    attempts++;

    delay(250);
    matrix.drawPixel(7, 7, LED_RED);
    matrix.writeDisplay();  

  }
 
  // WiFi connected, show a green WiFi Symbol
  matrix.clear();
  matrix.drawBitmap(0, 0, WiFi_bmp, 8, 8, LED_GREEN);
  matrix.writeDisplay();
  Serial.println("Connected to WiFi.");
  addlogentry("Connected to WiFi t="+String(millis()-starttime, DEC));
  delay(250);

  // Try to connect to NTP and get time intially
  Serial.println("trying to get NTP time...");
  addlogentry("trying to get NTP time...");
  WiFi.setDNS(IPAddress(8, 8, 8, 8));  
  rtc.begin();
  
  // show a Red NTP Symbol
  matrix.clear();
  matrix.drawBitmap(0, 0, NTP_bmp, 8, 8, LED_RED);
  matrix.writeDisplay();

  // get Epoch time from Internet Time Service and set RTC
  setRTC();  
  fixTimeZone();

  // NTP received, show a green NTP Symbol
  matrix.clear();
  matrix.blinkRate(0);
  matrix.drawBitmap(0, 0, NTP_bmp, 8, 8, LED_GREEN);
  matrix.writeDisplay();
  showdotmatrix=8;

  // output initial time
  Serial.println("\nInitial Time after Reset : ");
  print2digitsSer(myhours);
  Serial.print(":");
  print2digitsSer(mins);
  Serial.print(":");
  print2digitsSer(secs);
  Serial.print(" ");
  Serial.print(myday);
  Serial.print(".");
  Serial.print(mymonth);
  Serial.print(" ");  

  resetTime = String(myday)+"."+String(mymonth)+" "+String(myhours)+":"+String(mins); 
  addlogentry("Reset Time= "+resetTime);
  
  // start to act as Internet Server to enable the HTML menu
  server.begin();  

  // end of setup routine
  Time7SegDis.blinkRate(0);  // stop blinking
  Date7SegDis.blinkRate(0);
  Serial.print("Setup completed t="+String(millis()-starttime, DEC));
  addlogentry("Setup completed t="+String(millis()-starttime, DEC));
  addlogentry("Start normal operation...");
  
}


/* --------------------------------------------------------------------------------------
 Main Loop
-------------------------------------------------------------------------------------- */
void loop() 
{
  secs = rtc.getSeconds();      // get current time from real time clock
  if (secs == 0) fixTimeZone(); // each minute at 0s, correct time zone

  showTime();                   // Display time and date

  showTemp();                   // Display temperatures

  show_battery_status();        // Detect Supply voltage and get battery level

  showMatrixDisplay();          // Display Symbols on 8x8 dot matrix display (if required)

  adjustDimming();              // adjust 7seg LED brightness depending on time
  
  handleWifiClient();           // handle WiFi clients (browser for HTML Menu etc)

  // wait for next second ...
  while (secs == rtc.getSeconds())delay(10); // wait until seconds change
  
  if (mins==59 && secs ==0)   setRTC();      // get NTP time every hour at minute 59 and update RTC
  
}


/* --------------------------------------------------------------------------------------
 Display/Output current Time 
-------------------------------------------------------------------------------------- */
void showTime()
{
  // UART0 output
  if (secs==0)    // print full time&date, temp and and battery stats each minute at 0 secs 
  {
    Serial.println();
    print2digitsSer(myhours);
    Serial.print(":");
    print2digitsSer(mins);
    Serial.print(":");
    print2digitsSer(secs);
    if (myClock==12) 
    {
      if(IsPM) Serial.print("  PM");
      else Serial.print("  AM");
    }
    Serial.print(" ");
    Serial.print(myday);
    Serial.print(".");
    Serial.print(mymonth);
    Serial.print(" TempI=");
    Serial.print(temp_in);    
    Serial.print(" TempO=");
    Serial.print(temp_out);    
    if (onbattery)
    {
      Serial.print(" on battery (Bat=");  
      Serial.print(batlevel);
      Serial.print("% =");
      Serial.print(voltage);
      Serial.print("V) |");
    }
    else
      Serial.print(" USB powered |");  
    
  }
  else   // for each second print "."
  {
    if ((secs==10) || (secs==20) || (secs==40) || (secs==50)) Serial.print("*");
    else if ((secs==30) || (secs==59)) Serial.print("|");
    else Serial.print(".");      
    currenttime=String(myhours)+":"+String(mins)+":"+String(secs);  
    currentdate=String(myday)+"."+String(mymonth);   
  }
  
 //7-seg display Time output
  Time7SegDis.writeDigitNum(0, (myhours / 10) % 10, drawDots);
  Time7SegDis.writeDigitNum(1, myhours % 10, drawDots); 
  Time7SegDis.drawColon(drawCol); 
  Time7SegDis.writeDigitNum(3, (mins / 10) % 10, drawDots);
  Time7SegDis.writeDigitNum(4, (mins % 10), drawDots);
  Time7SegDis.writeDisplay();
  drawCol=!drawCol;
   
  //7-seg display Date output
  Date7SegDis.writeDigitNum(0, (myday / 10) % 10, false);
  Date7SegDis.writeDigitNum(1, myday % 10, true); 
  Date7SegDis.drawColon(false); 
  Date7SegDis.writeDigitNum(3, (mymonth / 10) % 10, false);
  Date7SegDis.writeDigitNum(4, (mymonth % 10), false);
  Date7SegDis.writeDisplay();

  
}

/* --------------------------------------------------------------------------------------
 Display/Output Temperature on 7seg LEDs 
-------------------------------------------------------------------------------------- */
void showTemp()
{
  if (temp_in > -99.0)
  {
      displayTempL(temp_in);  // display on left display
  }
  
  
  if (temp_out > -99.0)
  {
      displayTempR(temp_out);  // display on right display
  }
  
}


/* --------------------------------------------------------------------------------------
 get exact time from Internet Time Service (NTP) and set the RTC module to this time
-------------------------------------------------------------------------------------- */
void setRTC() 
{ 
  unsigned long epoch;
  int numberOfTries = 0, maxTries = 15;

  // try to access NTP service until successful
  do
  {
      do 
      {
        numberOfTries++;
        epoch = WiFi.getTime(); // Try to get NTP time 
        if (epoch == 0)
          delay(500);           // failed, wait until next try
        else
        {
          lastNTPupdate=epoch; // success, remember last update time
          lastepochrec = millis()-starttime;
        }
      }
      while ((epoch == 0) && (numberOfTries < maxTries));  // repeat a number of times
    
      if (numberOfTries == maxTries) // not successful
      {
        Serial.print(currenttime+" "+currentdate+" could not reach NTP");
        addlogentry(currenttime+" "+currentdate+" could not reach NTP");        
        // show a Red blining NTP Symbol
        matrix.clear();
        matrix.drawBitmap(0, 0, NTP_bmp, 8, 8, LED_RED);
        matrix.blinkRate(2);
        matrix.writeDisplay();

      }
      else  // success
      {
        rtc.setEpoch(epoch);
        Serial.print(currenttime+" "+currentdate+" NTP update successful. Epoch= ");
        Serial.println(epoch);
        addlogentry(currenttime+" "+currentdate+" NTP update successful. Epoch="+String(epoch));        
         // show a green NTP Symbol for a few seconds
         matrix.clear();
         matrix.blinkRate(0);
         matrix.drawBitmap(0, 0, NTP_bmp, 8, 8, LED_GREEN);
         matrix.writeDisplay();
         showdotmatrix=8;  

         if (onbattery) addlogentry("Currently running on battery. Remaining="+String(batlevel)+"%");        // add a note here if on bat
                         
      }
  }
  while (lastNTPupdate==0);   // repeat again and again if no NTP access was achieved yet (endless loop only can happen at start-up)
}

/* --------------------------------------------------------------------------------------
 Adjust 7seg LED Brightness depending on time
-------------------------------------------------------------------------------------- */
void adjustDimming()
{
  if (mins==0 && secs==0 && myhours==dimstart) // if start-time of dimming has been reached
  {
    Time7SegDis.setBrightness(dim_brightness);  // set to reduce brightness
    Date7SegDis.setBrightness(dim_brightness); 
    TempL7SegDis.setBrightness(dim_brightness); 
    TempR7SegDis.setBrightness(dim_brightness);
    Serial.print("brightness level dimmed");
    addlogentry("brightness level dimmed");        
 
  }

  if (mins==0 && secs==0 && myhours==dimend) // if end-time of dimming has been reached
  {
    Time7SegDis.setBrightness(brightness);  // set brightness back to normal level
    Date7SegDis.setBrightness(brightness); 
    TempL7SegDis.setBrightness(brightness); 
    TempR7SegDis.setBrightness(brightness); 
    Serial.print("brightness level set to normal");
    addlogentry("brightness level set to normal");        
  }
}


/* --------------------------------------------------------------------------------------
 Show Dot Matrix Symbols for a few seconds if required
-------------------------------------------------------------------------------------- */
void showMatrixDisplay()
{
  if (showdotmatrix > 0)  
    {
      matrix.setBrightness(showdotmatrix); // adjust brightness of showing symbol on dotmatrix  
      showdotmatrix--;                     // decrease seconds to show
      if (showdotmatrix==0)                // if zero, clear matrix display again
      {
          matrix.clear();
          matrix.writeDisplay();
          matrix.setBrightness(15);
          showdotmatrix=-1;
      }
   }
   else if (showdotmatrix==-1 && onbattery) show_batbars(batbars);  // else show battery bar display if on battery 
  
}



/* --------------------------------------------------------------------------------------
 // listen for incoming Wifi clients and process WiFi commands
-------------------------------------------------------------------------------------- */
void handleWifiClient()
{
  String currentLine = "";                // a String to hold incoming data from the client
  String commandLine = "";                // holds additional commands (after "?")
  String cmdpar = "";
  int clientcmd;                          // position of "?" 
  int len;
  boolean cmdproc = false;               // indicates if a command was executed with this current client alreday
  String lastepochrec2, tempupdaterec2;

  // first check if still connected with WiFi network
  if (WiFi.status() != WL_CONNECTED)  // if no longer connected...
  {
     // ...show a red WiFi Symbol ...
     matrix.clear();
     matrix.drawBitmap(0, 0, WiFi_bmp, 8, 8, LED_RED);
     matrix.writeDisplay();
     showdotmatrix=5;        

    // ... and (re-)connect to network.
    WiFi.disconnect();
    status = WiFi.begin(ssid, pass);
    Serial.println(currenttime+" re-connecting to WiFi...");
    addlogentry(currenttime+" re-connecting to WiFi ");   
     
  }
  else // if still connected to WiFi
  {
    // start server mode
    WiFiClient client = server.available();
    cmdproc=false;

    if (client) // if an outside client request was received (from a browser etc)
    {
     boolean currentLineIsBlank = true;
     currentLine = "";
     while (client.connected())  // as long as client is connected 
     {  
      if (client.available())   // and available
      {
        // prepare variables to show on HTML page
        IPAddress ip = WiFi.localIP();

        unsigned int ler_min = ((millis() - lastepochrec)/60000);
        unsigned int ler_sec = ((millis() - lastepochrec)/1000) - (ler_min*60);
        lastepochrec2 = String(ler_min)+":"+String(ler_sec);  // contains how long ago the last NTP update was

        if (tempupdaterec!=0)
        {
          unsigned int ltr_min = ((millis() - tempupdaterec)/60000);
          unsigned int ltr_sec = ((millis() - tempupdaterec)/1000) - (ltr_min*60);
          tempupdaterec2 = String(ltr_min)+":"+String(ltr_sec); // contains how long ago the last temperture update was
        }
        else tempupdaterec2 = "never";

        int ll=logstart;  // for the log buffer dump  
        if (ll<0) ll=0; 
        int li=0;

        // parse client message
        char c = client.read();
        if (c == '\n' && currentLineIsBlank) // repond to client after CR
        {
          // first send a standard HTTP response header
          client.println("HTTP/1.1 200 OK");
          client.println("Content-Type: text/html");
          client.println("Connection: close");  // the connection will be closed after completion of the response
//          client.println("Refresh: 5");  // refresh the page automatically every 5 sec
          client.println();

   // send entire HTML code for device website 
   // HTML (converted to C outputs) is located in external file :
#include "menu_inline_css7.h"
          
          break;
        }
        if (c == '\n') 
        {
          // starting a new line
//          Serial.println("WiFi Client request="+currentLine);   // for debugging : print each request line from client
          currentLineIsBlank = true;
          currentLine = "";
        } 
        else if (c != '\r') 
        {
          // received a character on the current line
          currentLineIsBlank = false;
          currentLine += c;      // add it to the end of the currentLine
        }


       // process received WiFi commands : 
       
       if ((c == '\r') && (cmdproc==false))  // if CR, look for additional commands received, if no already done (otherwise just a request to display the menu)
        {
            clientcmd = currentLine.indexOf('?');  // position of "?" in the request line ("?" indicates a command)
            if (clientcmd>0)    // if a command have been detected
            {
              // extract command out of received line
              len=currentLine.length();  
              commandLine = currentLine.substring(clientcmd+1,len);            // extract string from "?"..
              commandLine = commandLine.substring(0,commandLine.indexOf(' ')); // ..until first SPACE

              // output command on UART
              Serial.print("\nWiFi Command ");
              Serial.print(commandLine);

              // command handling :
              
              if (commandLine.endsWith("ibr"))   // adjust 7seg LED display brightness
              {
                Serial.println(" --> Inc LED backlight");
                if (brightness<14) brightness++;
                Time7SegDis.setBrightness(brightness);  
                Date7SegDis.setBrightness(brightness); 
                TempL7SegDis.setBrightness(brightness); 
                TempR7SegDis.setBrightness(brightness); 
                cmdproc=true; 
              }              
              if (commandLine.endsWith("dbr"))
              {
                Serial.println(" --> Dec LED backlight");
                if (brightness>0) brightness--;
                Time7SegDis.setBrightness(brightness);  
                Date7SegDis.setBrightness(brightness);  
                TempL7SegDis.setBrightness(brightness); 
                TempR7SegDis.setBrightness(brightness); 
                cmdproc=true;
              }
              
              if (commandLine.endsWith("idims"))   // adjust auto reduced brightness dimming time start and end times
              {
                Serial.println(" --> Inc dim time start");
                dimstart++;
                cmdproc=true;
              }
              if (commandLine.endsWith("ddims"))
              {
                Serial.println(" --> Dec dim time start");
                dimstart--;
                cmdproc=true;
              }
              if (commandLine.endsWith("idime"))
              {
                Serial.println(" --> Inc dim time end");
                dimend++;
                cmdproc=true;
              }
              if (commandLine.endsWith("ddime"))
              {
                Serial.println(" --> Dec dim time end");
                dimend--;
                cmdproc=true;
              }
                
              if (commandLine.startsWith("tempL="))  // set value on left temp display
              {
                cmdpar = commandLine.substring(6, commandLine.length());
                Serial.print(" --> set L temperature to ");
                Serial.println(cmdpar);
                temp_in=cmdpar.toFloat();
                // show a green Temp Symbol for a few seconds
                matrix.clear();
                matrix.blinkRate(0);
                matrix.drawBitmap(0, 0, temp_bmp, 8, 8, LED_GREEN);
                matrix.writeDisplay();
                showdotmatrix=5;  
                tempupdaterec = millis()-starttime;
                cmdproc=true;
              }              
              if (commandLine.startsWith("tempR=")) // set value on right temp display
              {
                cmdpar = commandLine.substring(6, commandLine.length());
                Serial.print(" --> set R temperature to ");
                Serial.println(cmdpar);
                temp_out=cmdpar.toFloat();
                // show a green Temp Symbol for a few seconds
                matrix.clear();
                matrix.blinkRate(0);
                matrix.drawBitmap(0, 0, temp_bmp, 8, 8, LED_GREEN);
                matrix.writeDisplay();
                showdotmatrix=5;        
                tempupdaterec = millis()-starttime;
                cmdproc=true;                
              }              

              if (commandLine.startsWith("mxteston")) // display a bell picture on matrix display for some seconds
              {
                // show a Symbol for a few seconds
                matrix.clear();
                matrix.blinkRate(0);
                matrix.drawBitmap(0, 0, bell_bmp, 8, 8, LED_RED);
                matrix.writeDisplay();
                showdotmatrix=10;        
                cmdproc=true;                
              }     
              if (commandLine.endsWith("ledon")) // mostly for testing only : toggle built-in LED
              {
                Serial.println(" --> Built-in LED ON");
                led1=true;
                digitalWrite(ledpin,HIGH);
                cmdproc=true;
              }              
              if (commandLine.endsWith("ledoff"))
              {
                Serial.println(" --> Built-in LED OFF");
                led1=false;
                digitalWrite(ledpin,LOW);
                cmdproc=true;
              }              

              if (commandLine.endsWith("igmt"))   // increase GMT time zone
              {
                Serial.println(" --> Inc GMT");
                GMT++;
                fixTimeZone();
                cmdproc=true;                
              }        
              if (commandLine.endsWith("dgmt"))   // decrease GMT time zone
              {
                Serial.println(" --> Dec GMT");
                GMT--;
                fixTimeZone();
                cmdproc=true;                
              }        
              if (commandLine.endsWith("idst"))   // set DST correction to +1h
              {
                Serial.println(" --> DST correction +1");
                DST=1;
                fixTimeZone();
                cmdproc=true;                
              }        
              if (commandLine.endsWith("ddst"))   // discable DST correction
              {
                Serial.println(" --> DST correction 0");
                DST=0;
                fixTimeZone();
                cmdproc=true;                
              }        
              
            }
         }
      }
    }
    delay(1);         // give the web browser time to receive the data
    client.stop();   // close the connection
   }
  } 
}





/* --------------------------------------------------------------------------------------
 Fix Time Zone 
 (adds GMT and DST and does all necessary corrections)
-------------------------------------------------------------------------------------- */
void fixTimeZone() 
{
  int daysMon[13] = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
  if (myyear % 4 == 0) daysMon[2] = 29; // fix for leap year
  
  // get current time from real time clock module
  myhours = rtc.getHours();
  mins = rtc.getMinutes();
  myday = rtc.getDay();
  mymonth = rtc.getMonth();
  myyear = rtc.getYear();

  myhours +=  GMT; // adjust time zone 

  myhours += DST;  // and correct DST  

  // To do : Auto DST corrections add later here ...

  // ...


  // do corrections in case necessary :
  
  if (myhours < 0)  // if hours rolls negative
  {  
    myhours += 24;   // keep in range of 0-23
    myday--;        // fix the day
    if (myday < 1)  // fix the month if necessary
    {  
      mymonth--;
      if (mymonth == 0) mymonth = 12;
      myday = daysMon[mymonth];
      if (mymonth == 12) myyear--; // fix the year if necessary
    }
  }
  if (myhours > 23)   // if hours rolls over 23
  {  
    myhours -= 24; // keep in range of 0-23
    myday++; // fix the day
    if (myday > daysMon[mymonth]) // fix the month if necessary
    {  
      mymonth++;
      if (mymonth > 12) mymonth = 1;
      myday = 1;
      if (mymonth == 1)myyear++; // fix the year if necessary
    }
  }

  if (myClock == 12) // this is for 12 hour clock
  {  
    IsPM = false;
    if (myhours > 11)IsPM = true;
    myhours = myhours % 12; // convert to 12 hour clock
    if (myhours == 0) myhours = 12;  // show noon or midnight as 12
  }
}




/* --------------------------------------------------------------------------------------
// measure and display external voltage supply condition
-------------------------------------------------------------------------------------- */
void show_battery_status()
{
  // Get Battery Level (available on Mkr1010 board)
  sensorValue = analogRead(ADC_BATTERY);
  
  // Convert the analog reading (which goes from 0 - 4095) to a real voltage (0 - 4.208V):
  voltage = sensorValue * (4.208 / 4095.000); // (0-4.208V)
  batlevel = 100*(voltage-3.3)/0.8; // calc bat level in % 

  if (batlevel < 0) batlevel=0;     // if no battery connected
  if (batlevel > 100) batlevel=100; // if charging

  // determine "bars" for battery gauge
  if (voltage < 3.4) 
    batbars =0;
  else if (voltage>=3.4 && voltage<3.46)
    batbars = 1;
  else if (voltage>=3.46 && voltage<3.62)
    batbars = 2;
  else if (voltage>=3.62 && voltage<3.78)
    batbars = 3;
  else if (voltage>=3.78 && voltage<3.94)
    batbars = 4;
  else if (voltage>=3.94)
    batbars = 5;

 // Detect USB-Power (Charging) or Battery Mode by measuring the 5V output pin of the Mkr1010
 // use 2:1 voltage divider (2xR) on 5V pin to A1 and GND to monitor voltage level  
  power5 = analogRead(A1) * (3.3 / 4095.000);   // USB(5V)>=2.5V ; Bat(3.3V)<=1.6V

  // detect USB Power (Charge) or Battery Mode
  if (power5 > 2.2) // ext.power,charging
  { 
    if (onbattery)  // switched from battery to USB -> need to RESET the board to fix the following behaviour :
    // if you have an arduino mkr wifi 1010 connected to a li-po battery and plug it in to charge 
    // but do not reset the arduino it will be dramatically current limited (100mA charge only), leading to an error after some time
    // the red charge LED will flash and the device will not work properly anymore, so we need a RESET 
    {
     MyWatchDoggy.setup(WDT_HARDCYCLE4S);  // initialize hardware watchdog after 4S if not cleared before

      //  show a blinking reset Symbol 
      matrix.clear();
      matrix.drawBitmap(0, 0, reset_bmp, 8, 8, LED_RED);
      matrix.blinkRate(2);
      matrix.writeDisplay();
      delay(1000);

      Serial.println(currenttime+" Watchdog reset in 4 sec - wait for reset \n");
      addlogentry(currenttime+" Switch from bat to USB power -> will RESET in 4 sec... ");        
      
      for (int t = 1; t > 0; ++t) {
        Serial.print(t);Serial.print(".");
        delay(950);
        }      
    }
     
  }
  else     // on backup battery
  {
      if (onbattery==false)  // if just switched from USB power to battery, output message
      {
        Serial.println(currenttime+" Swichted to Battery Supply! Remaining="+String(batlevel)+"%");
        addlogentry(currenttime+" Swichted to Battery Supply! Remaining="+String(batlevel)+"%");       
      }
      onbattery=true; // remember status "on battery" (also for next time it changes to USB power ...needs a reset then)
  }

}

/* --------------------------------------------------------------------------------------
// display battery status as bar symbol
-------------------------------------------------------------------------------------- */
void show_batbars(int bar)
{
      // draw the battery status using 5 bars (green and red)
      for (int i=1; i<=bar; i++)
      {
        matrix.drawLine(2,7-i, 5,7-i, LED_GREEN);
        matrix.writeDisplay();
      }
      for (int i=bar+1; i<=5; i++)
      {
        matrix.drawLine(2,7-i, 5,7-i, LED_RED);
        matrix.writeDisplay();
      }

     // show battery bitmap in 3 colors around
     if (bar>2)
      {
      matrix.drawBitmap(0, 0, battery_bmp, 8, 8, LED_GREEN);
      matrix.writeDisplay();
      }
      else if (bar==2)
      {
      matrix.drawBitmap(0, 0, battery_bmp, 8, 8, LED_YELLOW);
      matrix.writeDisplay();
...

This file has been truncated, please download it to see its full contents.

symbols.h

C/C++
symbols for the 8x8 dot matrix display
// some simple 8x8 bitmaps for the dot matrix matrix display
// symbols will be stored in flash memory

static const uint8_t PROGMEM   
  WiFi_bmp[] =
  { B01111110,
    B10000001,
    B00111100,
    B01000010,
    B00011000,
    B00000000,
    B00011000,
    B00011000 },
  NTP_bmp[] =
  { B10010111,
    B11010010,
    B10110010,
    B10010010,
    B00001100,
    B00001010,
    B00001100,
    B00001000 },
  TempAlert_bmp[] =
  { B00100000,
    B01110010,
    B01010010,
    B01010010,
    B01010000,
    B11111010,
    B11111000,
    B01110000 },
  extpower_bmp[] =
  { B00011100,
    B00111110,
    B00111110,
    B00001000,
    B00001000,
    B00010000,
    B01100000,
    B00000000 },
  battery_bmp[] =
  { B00011000,
    B01111110,
    B01000010,
    B01000010,
    B01000010,
    B01000010,
    B01000010,
    B01111110 },
  reset_bmp[] =
  { B00000000,
    B00011110,
    B00000010,
    B00100010,
    B01100010,
    B11111110,
    B01100000,
    B00100000 },
  temp_bmp[] =
  { B00000000,
    B01111100,
    B00010000,
    B00010000,
    B00010000,
    B00010000,
    B00000000,
    B00000000 },
  bell_bmp[] =
  { B00011000,
    B00111100,
    B00111100,
    B00111100,
    B01111110,
    B11111111,
    B00011000,
    B00000000 }
    ;

menu_inline_css7.h

C/C++
the HTML menu source code (for the website)
// HTML Content of Device Website :          
// Generated by Arduino HTMl Converter V1
// Date :  05.12.2021 19:27:46
//    
client.println("<!- HTML Menu for HM Display Clock V7  -!>"); 
client.println(""); 
client.println("<!DOCTYPE html>"); 
client.println("<html>"); 
client.println("<head>"); 
client.println("<meta charset=\"utf-8\"/>"); 
client.println("<title>HM Display Clock Menu </title>"); 
client.println(""); 
client.println("<style>"); 
client.println("* {  box-sizing: border-box; }"); 
client.println("html { font-family: sans-serif; }"); 
client.println("body {  margin: 0;   background-color:grey; }"); 
client.println("h1 {color:white; font-style:italic; font-size:22px;}"); 
client.println("table { border-collapse: collapse;  border: 4px solid rgb(200,200,200); letter-spacing: 1px;  font-size: 0.9rem; }"); 
client.println("td, th { border: 1px solid rgb(190,190,190);  padding: 10px 20px; }"); 
client.println("td { text-align: center; }"); 
client.println("a { padding: 1rem 2rem; background: #ccc; text-decoration: none; margin: 1rem;  border-radius: 8px; }"); 
client.println(".header {   background-color: black;   color: white;   text-align: center;   padding: 5px; }"); 
client.println(".footer {   background-color: #444;   color: white;   padding: 15px; }"); 
client.println(".topmenu {   list-style-type: none;   margin: 0;   padding: 0;   overflow: hidden;   background-color: #444; }"); 
client.println(".topmenu li {   float: left;   background-color: #444; }"); 
client.println(".topmenu li a {   display: inline-block;   color: white;   text-align: center;   padding: 16px;  text-decoration: none; }"); 
client.println(".topmenu li a:hover {   background-color: #888822; }"); 
client.println(".topmenu li a.active {   color: white;   background-color: blue; }"); 
client.println(".column {   float: left;   padding: 10px; }"); 
client.println(".clearfix::after {   content: \"\";   clear: both;   display: table; }"); 
client.println(".sidemenu {   width: 10%;   background-color: #444;  }"); 
client.println(".content {   width: 90%;   background-color: #999999; }"); 
client.println(".sidemenu ul {   list-style-type: none;   margin: 0;   padding: 0; }"); 
client.println(".sidemenu li a { margin-bottom: 2px;  display: block;  padding: 8px;  background-color: #eee;  text-decoration: none;  color: #666; }"); 
client.println(".sidemenu li a:hover {  background-color: #888822;  color: white; }"); 
client.println(".sidemenu li a.active {  background-color: #008CBA;   color: white; }"); 
client.println(".inline-block-buttons a { "); 
client.println(" display: inline-block; color: Black; background-color: #grey; border-radius: 4px;border-bottom: 3px solid #555;"); 
client.println(" box-shadow: 0 4px 16px 0 rgba(0,0,0,0.2), 0 6px 20px 0 rgba(0,0,0,0.19); }"); 
client.println("</style>"); 
client.println("</head>"); 
client.println(""); 
client.println("<body>"); 
client.println(""); 
client.println("<!- TOP-MENU with a few buttons -!>"); 
client.println(""); 
client.println("<ul class=\"topmenu\">"); 
client.println("  <li><a href=\"?Refresh\">Refresh Page</a></li>   <!- mit class=\"active\" kann Element aktiv angeziegt werden -!>"); 
client.println("  <lr> <h1 style=\"text-align:right\";>MENU V1.0   |</h1>  </lr>"); 
client.println("</ul>"); 
client.println(""); 
client.println("<!- SIDE-MENU (no Buttons here) -!>"); 
client.println(""); 
client.println("<div class=\"clearfix\">"); 
client.println("  <div class=\"column sidemenu\">"); 
client.println("    <ul>"); 
client.println(" <!- fill with empty lines until the button -!>"); 
client.println("   <br> <br> <br> <br> <br> <br> <br> <br> <br> <br> <br> <br> <br> <br> <br> <br> <br> <br> <br> <br> <br> <br> <br> <br> <br> <br> <br> <br> <br> <br> <br>"); 
client.println("   <br> <br> <br> <br> <br> <br> <br> <br> <br> <br> <br> <br> <br> <br> <br> <br> <br> <br> <br> <br> <br> <br> <br> <br> <br> <br> <br> <br> <br> <br> <br>"); 
client.println("   <br> <br> <br> <br> <br> <br> <br> <br> <br> <br> <br> <br> <br> <br> <br> <br> <br> <br> <br> <br> <br> <br> <br> <br> <br> <br> <br> <br> <br> <br> <br>"); 
client.println("    </ul>"); 
client.println("  </div>"); 
client.println(""); 
client.println(""); 
client.println("<!- Headline -!>"); 
client.println(""); 
client.println("  <div class=\"column content\">"); 
client.println("    <div class=\"header\">"); 
client.println("      <h1>HOMEMATIC DISPLAY CLOCK</h1>"); 
client.println("    </div>"); 
client.println(""); 
client.println("<!- Description -!>"); 
client.println("<p  style=\"color:white;background-color: black\"; > "); 
client.println("A precise clock based on the Arduino Mkr WiFi1010 Board.<br> "); 
client.println("Use the options below to change your desired settings.<br>"); 
client.println("</p>"); 
client.println(""); 
client.println("<! -- Table with all entries  --!>"); 
client.println(""); 
client.println("<table>  "); 
client.println("<caption style=\"color:white;background-color: black\";><b>Status and Settings</b></caption>"); 
client.println("  <colgroup>"); 
client.println("    <col style=\"background-color: White\" span=\"4\";>"); 
client.println("  </colgroup>"); 
client.println("  <tr>"); 
client.println("    <th> Parameter </th>"); 
client.println("    <th> Value </th>"); 
client.println("    <th> </th>"); 
client.println("    <th> </th>"); 
client.println("  </tr>"); 
client.println("  <tr>"); 
client.println("    <td>Current time</td>"); 
client.println("<td >"); 
client.println(currenttime);
client.println("</td>"); 
client.println("  </tr>"); 
client.println("  <tr>"); 
client.println("    <td>Current date</td>"); 
client.println("<td >"); 
client.println(currentdate);
client.println("</td>"); 
client.println("  </tr>"); 
client.println("  <tr>"); 
client.println("    <td>Last successful NTP time update</td>"); 
client.println("<td >"); 
client.println(lastepochrec2);
client.println("</td>"); 
client.println("    <td >min:sec ago</td>"); 
client.println("  </tr>"); 
client.println("  <tr>"); 
client.println("    <td>Last Epoch NTP</td>"); 
client.println("<td >"); 
client.println(lastNTPupdate);
client.println("</td>"); 
client.println("  </tr>"); 
client.println("  <tr>"); 
client.println("    <td>Last woke up from reset</td>"); 
client.println("<td >"); 
client.println(resetTime);
client.println("</td>"); 
client.println("    <td >d.m hh:mm</td>"); 
client.println("  </tr>"); 
client.println(""); 
client.println("  <tr>"); 
client.println("    <td>Time Zone Correction</td>"); 
client.println("<td >"); 
client.println(GMT);
client.println("</td>"); 
client.println("    <td  class=\"inline-block-buttons\"><a href=\"?igmt\"> + </a></td>"); 
client.println("    <td  class=\"inline-block-buttons\"><a href=\"?dgmt\"> - </a></td>"); 
client.println("  </tr>"); 
client.println("  <tr>"); 
client.println("    <td>Daylight Saving Time Correction <br>(set to 1 from 31.3.-31.10)</td>"); 
client.println("<td >"); 
client.println(DST);
client.println("</td>"); 
client.println("    <td  class=\"inline-block-buttons\"><a href=\"?idst\"> + </a></td>"); 
client.println("    <td  class=\"inline-block-buttons\"><a href=\"?ddst\"> - </a></td>"); 
client.println("  </tr>"); 
client.println(""); 
client.println("  <tr>   							<! -- Black Seperation Line in Table  --!>"); 
client.println("    <td style=\"background-color: black; border: 1px solid rgb(0,0,0); padding: 5px 5px;\"> </td>"); 
client.println("    <td style=\"background-color: black; border: 1px solid rgb(0,0,0); padding: 5px 5px;\"> </td>"); 
client.println("    <td style=\"background-color: black; border: 1px solid rgb(0,0,0); padding: 5px 5px;\"> </td>"); 
client.println("    <td style=\"background-color: black; border: 1px solid rgb(0,0,0); padding: 5px 5px;\"> </td>"); 
client.println("  </tr>"); 
client.println("  <tr>"); 
client.println("    <td>Current Temp In (C)</td>"); 
client.println("<td >"); 
client.println(temp_in);
client.println("</td>"); 
client.println("  </tr>"); 
client.println("  <tr>"); 
client.println("    <td>Current Temp Out (C)</td>"); 
client.println("<td >"); 
client.println(temp_out);
client.println("</td>"); 
client.println("  </tr>"); 
client.println("  <tr>"); 
client.println("    <td>Last HM Temp update received</td>"); 
client.println("<td >"); 
client.println(tempupdaterec2);
client.println("</td>"); 
client.println("    <td >min:sec ago</td>"); 
client.println("  </tr>"); 
client.println(""); 
client.println("  <tr>   							<! -- Black Seperation Line in Table  --!>"); 
client.println("    <td style=\"background-color: black; border: 1px solid rgb(0,0,0); padding: 5px 5px;\"> </td>"); 
client.println("    <td style=\"background-color: black; border: 1px solid rgb(0,0,0); padding: 5px 5px;\"> </td>"); 
client.println("    <td style=\"background-color: black; border: 1px solid rgb(0,0,0); padding: 5px 5px;\"> </td>"); 
client.println("    <td style=\"background-color: black; border: 1px solid rgb(0,0,0); padding: 5px 5px;\"> </td>"); 
client.println("  </tr>"); 
client.println("  <tr>"); 
client.println("    <td>Voltage (\"5V pin\")</td>"); 
client.println("<td >"); 
client.println(voltage);
client.println("</td>"); 
client.println("  </tr>"); 
client.println("  <tr>"); 
client.println("    <td>Battery Level (%)</td>"); 
client.println("<td >"); 
client.println(batlevel);
client.println("</td>"); 
client.println("  </tr>"); 
client.println("  <tr>"); 
client.println("    <td>7-Seg Brightness (0-15)</td>"); 
client.println("<td >"); 
client.println(brightness);
client.println("</td>"); 
client.println("    <td  class=\"inline-block-buttons\"><a href=\"?ibr\"> + </a></td>"); 
client.println("    <td  class=\"inline-block-buttons\"><a href=\"?dbr\"> - </a></td>"); 
client.println("  </tr>"); 
client.println("  <tr>"); 
client.println("    <td>Dim 7-Seg Brightness from h=</td>"); 
client.println("<td >"); 
client.println(dimstart);
client.println("</td>"); 
client.println("    <td  class=\"inline-block-buttons\"><a href=\"?idims\"> + </a></td>"); 
client.println("    <td  class=\"inline-block-buttons\"><a href=\"?ddims\"> - </a></td>"); 
client.println("  </tr>"); 
client.println("  <tr>"); 
client.println("    <td>...to  h=</td>"); 
client.println("<td >"); 
client.println(dimend);
client.println("</td>"); 
client.println("    <td  class=\"inline-block-buttons\"><a href=\"?idime\"> + </a></td>"); 
client.println("    <td  class=\"inline-block-buttons\"><a href=\"?ddime\"> - </a></td>"); 
client.println("  </tr>"); 
client.println("  <tr>"); 
client.println("    <td>Matrix Display Show Test Pattern</td>"); 
client.println("    <td > </td>"); 
client.println("    <td  class=\"inline-block-buttons\"><a href=\"?mxteston\">ON</a></td>"); 
client.println("    <td  class=\"inline-block-buttons\"><a href=\"?mxtestoff\">OFF</a></td>"); 
client.println("  </tr>"); 
client.println("  <tr>"); 
client.println("    <td>Built-in LED</td>"); 
client.println("<td >"); 
client.println(led1);
client.println("</td>"); 
client.println("    <td  class=\"inline-block-buttons\"><a href=\"?ledon\">ON</a></td>"); 
client.println("    <td  class=\"inline-block-buttons\"><a href=\"?ledoff\">OFF</a></td>"); 
client.println("  </tr>"); 
client.println(""); 
client.println("  <tr>   							<! -- Black Seperation Line in Table  --!>"); 
client.println("    <td style=\"background-color: black; border: 1px solid rgb(0,0,0); padding: 5px 5px;\"> </td>"); 
client.println("    <td style=\"background-color: black; border: 1px solid rgb(0,0,0); padding: 5px 5px;\"> </td>"); 
client.println("    <td style=\"background-color: black; border: 1px solid rgb(0,0,0); padding: 5px 5px;\"> </td>"); 
client.println("    <td style=\"background-color: black; border: 1px solid rgb(0,0,0); padding: 5px 5px;\"> </td>"); 
client.println("  </tr>"); 
client.println("  <tr>"); 
client.println("    <td>IP Address</td>"); 
client.println("<td >"); 
client.println(ip);
client.println("</td>"); 
client.println("  </tr>"); 
client.println(""); 
client.println("</table>"); 
client.println(""); 
client.println("<p  style=\"color:white;background-color: black\"; >  <! -- Beschreibung  -->"); 
client.println("Last log entries  :"); 
client.println("</p>"); 
client.println(""); 
client.println("<p>"); 
client.println(""); 
client.println("<textarea cols=\"120\" rows=\"10\" style=\"border:solid; resize:none\">"); 

// dumps current log buffer out to client 
  do
  {
    client.println(loglines[ll]);
    ll++;
    if (ll==logsize) ll=0;
    li++;
  } while( li < logsize);


client.println("</textarea>"); 
client.println(""); 
client.println("</p>"); 
client.println(""); 
client.println("</div>"); 
client.println("</div>"); 
client.println(""); 
client.println("<div class=\"footer\">"); 
client.println("  <p>Homematic Display Clock Website V"); 
client.println(Version);
client.println("</p>"); 
client.println("</div>"); 
client.println(""); 
client.println("</body>"); 
client.println("</html>"); 

Credits

mac70

mac70

5 projects • 25 followers

Comments