#include <ESP8266WiFi.h>
#include <ESP8266WebServer.h>
#include <ArduinoJson.h>
#include "FS.h"
#include "Time.h"
#include "TimeLib.h"
#include <SoftwareSerial.h>
#include <Wire.h>
#include "RTClib.h"
RTC_DS3231 rtc;
int SS_TXPin = D5;
int BWM_Pin = D7;
SoftwareSerial Serial1t(SW_SERIAL_UNUSED_PIN, SS_TXPin);
ESP8266WebServer server(80);
int citycount = 0;
int myintervall = 60;
int mymethod = 0;
const char signMessage[] PROGMEM = { };
long mainconfig[10] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
String citys[20] = { "", "", "", "", "", "", "", "", "", "", "", "", "", "", "",
"", "", "", "", ""
};
long gmt[20] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
int dst[20] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
String ssid = "";
String key = "";
String ip = "";
int waiting = 1000;
String NTPurl = "";
String setRow1 = "";
String setRow2 = "";
String olddate = "";
int col = 0;
int steps = 0;
int cursor1 = -1;
int cursor2 = -2;
int cursor3 = -3;
boolean updated = false;
boolean startanim = false;
unsigned long lastupdate = millis();
byte helper1[] = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09,
0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13
};
byte helper2[] = { 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D,
0x1E, 0x1F, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27
};
IPAddress local_IP(192, 168, 4, 22);
IPAddress gateway(192, 168, 4, 9);
IPAddress subnet(255, 255, 255, 0);
boolean startAP = false;
int tzoffset = 0;
void setup() {
pinMode(D7, INPUT);
if (!rtc.begin()) {
Serial.println("Couldn't find RTC");
while (1)
;
}
int apstatus = HIGH;
Serial.begin(9600);
if (!SPIFFS.begin()) {
Serial.println("Failed to mount file system");
} else if (loadConfig()) {
}
WiFi.hostname("weltuhr");
Serial.println(ssid + key);
if (ssid == "" || key == "" || apstatus == LOW) {
WiFi.softAP("weltuhr", "weltuhr");
WiFi.softAPConfig(local_IP, gateway, subnet);
} else {
WiFi.begin((const char*) ssid.c_str(), (const char*) key.c_str());
while (WiFi.status() != WL_CONNECTED) {
delay(500);
}
}
server.on("/", handleRoot);
server.on("/index.html", handleRoot);
server.serveStatic("/config.json", SPIFFS, "/config.json");
server.serveStatic("/stylesheet.css", SPIFFS, "/stylesheet.css");
server.begin();
startAP = true;
waiting = mainconfig[0];
myintervall = mainconfig[1];
Serial1t.begin(9600);
Serial1t.write(0x1B);
Serial1t.write(0x05);
Serial1t.write(0x1B);
Serial1t.write(0x0A);
Serial1t.write(0x1B);
Serial1t.write(0x17);
Serial1t.write(mainconfig[6] + 1);
if (myintervall == 0)
myintervall = 60 * 1000;
setSyncProvider (rtcsync);
setSyncInterval(500);
}
boolean first = true;
boolean waitprogress = false;
unsigned long lastwaitprogress = 0;
boolean updatewaitprogress = false;
unsigned long lastupdatewaitprogress = 0;
boolean cyclewaitprogress = false;
unsigned long lastcyclewaitprogress = 0;
boolean screensaver = false;
unsigned long lastscreensaver = 0;
int cycles = 0;
int cityscount = 0;
unsigned long speedupdate = 200;
boolean bwm_active = false;
void loop() {
unsigned long current Millis = millis();
int tempbwm = digitalRead(D7);
if ((tempbwm == HIGH && screensaver ) || (tempbwm == HIGH && cyclewaitprogress)) {
lastscreensaver = currentMillis;
screensaver = false;
cyclewaitprogress = false;
Serial1t.write(0x1B);
Serial1t.write(0x05);
Serial.println("BWM");
}
if (currentMillis - lastwaitprogress >= (myintervall * 1000) || first) {
lastwaitprogress = currentMillis;
waitprogress = false;
}
if (currentMillis - lastupdatewaitprogress >= speedupdate) {
lastupdatewaitprogress = currentMillis;
updatewaitprogress = false;
}
if (currentMillis - lastcyclewaitprogress >= mainconfig[0] * 1000) {
lastcyclewaitprogress = currentMillis;
cyclewaitprogress = false;
}
if (currentMillis - lastscreensaver >= mainconfig[5] * 1000
&& cyclewaitprogress && mainconfig[3] == 1) {
lastscreensaver = currentMillis;
screensaver = true;
Serial1t.write(0x1B);
Serial1t.write(0x0B);
Serial1t.write(0x1B);
Serial1t.write(0x17);
Serial1t.write(mainconfig[6] + 1);
}
if (!screensaver)
if (cycles < mainconfig[4]) {
if (!cyclewaitprogress) {
lastcyclewaitprogress = currentMillis;
if (!startanim && !waitprogress) {
cityscount++;
if (citys[cityscount] == "") {
cityscount = 0;
cycles++;
}
if (mainconfig[2] == 0)
tzoffset = 0;
else if (mainconfig[2] == 1)
tzoffset = dst[cityscount] * 3600;
else if (mainconfig[2] == 2)
if (summertime_EU)
tzoffset = dst[cityscount] * 3600;
olddate = centerString(
createDateTime(now(), tzoffset + gmt[cityscount]));
prepareAnimation(centerString(citys[cityscount]), olddate);
waitprogress = true;
if (first)
first = false;
}
}
} else {
cycles = 0;
cyclewaitprogress = true;
Serial1t.write(0x1B);
Serial1t.write(0x06);
}
if (startanim && !updatewaitprogress) {
updatewaitprogress = true;
updateAnimation();
lastcyclewaitprogress = currentMillis;
}
String testdate = createDateTime(now(), tzoffset + gmt[cityscount]);
if (olddate != testdate && !startanim) {
replaceonlytime(tzoffset + gmt[cityscount] + now());
olddate = testdate;
}
server.handleClient();
delay(20);
}
void handleRoot() {
if (server.arg("setzen") != "") {
rtc.adjust(server.arg("unixtimeset").toInt());
Serial.println("Setzen");
File indexFile = SPIFFS.open("/index.html", "r");
if (!indexFile) {
}
size_t sent = server.streamFile(indexFile, "text/html");
indexFile.close();
} else if (server.arg("network") != "") {
ssid = const_cast<char*>(server.arg("ssid").c_str());
key = const_cast<char*>(server.arg("key").c_str());
ip = const_cast<char*>(server.arg("ip").c_str());
saveConfig();
} else if (server.arg("speichern") != "") {
mainconfig[0] = server.arg("waiting").toInt();
mainconfig[1] = server.arg("myintervall").toInt();
mainconfig[2] = server.arg("mod").toInt();
server.arg("bwm") == "on" ? mainconfig[3] = 1 : mainconfig[3] = 0;
mainconfig[4] = server.arg("cycles").toInt();
mainconfig[5] = server.arg("screensaver").toInt();
mainconfig[6] = server.arg("brightness").toInt();
citys[0] = server.arg("s0");
citys[1] = server.arg("s1");
citys[2] = server.arg("s2");
citys[3] = server.arg("s3");
citys[4] = server.arg("s4");
citys[5] = server.arg("s5");
citys[6] = server.arg("s6");
citys[7] = server.arg("s7");
citys[8] = server.arg("s8");
citys[9] = server.arg("s9");
citys[10] = server.arg("s10");
citys[11] = server.arg("s11");
citys[12] = server.arg("s12");
citys[13] = server.arg("s13");
citys[14] = server.arg("s14");
citys[15] = server.arg("s15");
citys[16] = server.arg("s16");
citys[17] = server.arg("s17");
citys[18] = server.arg("s18");
citys[19] = server.arg("s19");
gmt[0] = server.arg("z0").toInt();
gmt[1] = server.arg("z1").toInt();
gmt[2] = server.arg("z2").toInt();
gmt[3] = server.arg("z3").toInt();
gmt[4] = server.arg("z4").toInt();
gmt[5] = server.arg("z5").toInt();
gmt[6] = server.arg("z6").toInt();
gmt[7] = server.arg("z7").toInt();
gmt[8] = server.arg("z8").toInt();
gmt[9] = server.arg("z9").toInt();
gmt[10] = server.arg("z10").toInt();
gmt[11] = server.arg("z11").toInt();
gmt[12] = server.arg("z12").toInt();
gmt[13] = server.arg("z13").toInt();
gmt[14] = server.arg("z14").toInt();
gmt[15] = server.arg("z15").toInt();
gmt[16] = server.arg("z16").toInt();
gmt[17] = server.arg("z17").toInt();
gmt[18] = server.arg("z18").toInt();
gmt[19] = server.arg("z19").toInt();
server.arg("dst0") == "on" ? dst[0] = 1 : dst[0] = 1;
server.arg("dst1") == "on" ? dst[1] = 1 : dst[1] = 0;
server.arg("dst2") == "on" ? dst[2] = 1 : dst[2] = 0;
server.arg("dst3") == "on" ? dst[3] = 1 : dst[3] = 0;
server.arg("dst4") == "on" ? dst[4] = 1 : dst[4] = 0;
server.arg("dst5") == "on" ? dst[5] = 1 : dst[5] = 0;
server.arg("dst6") == "on" ? dst[6] = 1 : dst[6] = 0;
server.arg("dst7") == "on" ? dst[7] = 1 : dst[7] = 0;
server.arg("dst8") == "on" ? dst[8] = 1 : dst[8] = 0;
server.arg("dst9") == "on" ? dst[9] = 1 : dst[9] = 0;
server.arg("dst10") == "on" ? dst[10] = 1 : dst[10] = 0;
server.arg("dst11") == "on" ? dst[11] = 1 : dst[11] = 0;
server.arg("dst12") == "on" ? dst[12] = 1 : dst[12] = 0;
server.arg("dst13") == "on" ? dst[13] = 1 : dst[13] = 0;
server.arg("dst14") == "on" ? dst[14] = 1 : dst[14] = 0;
server.arg("dst15") == "on" ? dst[15] = 1 : dst[15] = 0;
server.arg("dst16") == "on" ? dst[16] = 1 : dst[16] = 0;
server.arg("dst17") == "on" ? dst[17] = 1 : dst[17] = 0;
server.arg("dst18") == "on" ? dst[18] = 1 : dst[18] = 0;
server.arg("dst19") == "on" ? dst[19] = 1 : dst[19] = 0;
Serial1t.write(0x1B);
Serial1t.write(0x17);
Serial1t.write(mainconfig[6] + 1);
waiting = mainconfig[0];
myintervall = mainconfig[1];
mymethod = mainconfig[2];
saveConfig();
File configFile = SPIFFS.open("/index.html", "r");
if (!configFile) {
}
size_t sent = server.streamFile(configFile, "text/html");
configFile.close();
} else {
File indexFile = SPIFFS.open("/index.html", "r");
if (!indexFile) {
Serial.println("Failed to open config file");
}
size_t sent = server.streamFile(indexFile, "text/html");
indexFile.close();
}
}
bool loadConfig() {
File configFile = SPIFFS.open("/config.json", "r");
if (!configFile) {
return false;
}
size_t size = configFile.size();
if (size > 3000) {
return false;
}
std::unique_ptr<char[]> buf(new char[size]);
configFile.readBytes(buf.get(), size);
StaticJsonBuffer<3000> jsonBuffer;
JsonObject& json = jsonBuffer.parseObject(buf.get());
if (!json.success()) {
Serial.println("Failed to parse config file");
return false;
}
const char *string_table[20];
json["citys"].as<JsonArray>().copyTo(string_table);
for (int i = 0; i < 19; i++) {
citys[i] = String(string_table[i]);
}
json["gmt"].as<JsonArray>().copyTo(gmt);
json["dst"].as<JsonArray>().copyTo(dst);
json["mainconfig"].as<JsonArray>().copyTo(mainconfig);
ssid = json["ssid"].as<String>();
key = json["key"].as<String>();
ip = json["ip"].as<String>();
NTPurl = json["ntpurl"].as<String>();
configFile.close();
return true;
}
bool saveConfig() {
StaticJsonBuffer<2000> jsonBuffer;
JsonObject& root = jsonBuffer.createObject();
JsonArray& array4 = root.createNestedArray("mainconfig");
array4.copyFrom(mainconfig);
JsonArray& array1 = root.createNestedArray("citys");
array1.copyFrom(citys);
JsonArray& array2 = root.createNestedArray("gmt");
array2.copyFrom(gmt);
JsonArray& array3 = root.createNestedArray("dst");
array3.copyFrom(dst);
root["ssid"] = ssid;
root["key"] = key;
root["ip"] = ip;
root["ntpurl"] = NTPurl;
File configFile = SPIFFS.open("/config.json", "w");
if (!configFile) {
return false;
}
root.printTo(configFile);
configFile.close();
return true;
}
void prepareAnimation(String newRow1, String newRow2) {
setRow1 = newRow1;
setRow2 = newRow2;
startanim = true;
}
void updateAnimation() {
if (startanim) {
if (cursor1 >= 0 && cursor1 <= 19) {
setCharAtvfd(1, cursor1, 0xB2);
setCharAtvfd(2, cursor1, 0xB2);
}
if (cursor2 >= 0 && cursor2 <= 19) {
setCharAtvfd(1, cursor2, 0xB1);
setCharAtvfd(2, cursor2, 0xB1);
}
if (cursor3 >= 0 && cursor3 <= 19) {
setCharAtvfd(1, cursor3, 0xB0);
setCharAtvfd(2, cursor3, 0xB0);
}
cursor1++;
cursor2++;
cursor3++;
if (cursor3 > 1) {
setCharAtvfd(1, steps, setRow1.charAt(steps));
setCharAtvfd(2, steps, setRow2.charAt(steps));
steps++;
}
}
if (steps > 19)
{
steps = 0;
startanim = false;
cursor1 = -1;
cursor2 = -2;
cursor3 = -3;
}
}
String createDateTime(time_t tt, int offset) {
time_t t = offset + tt;
String t_str = " ";
if (day(t) < 10)
t_str += "0";
t_str += day(t);
t_str += ".";
if (month(t) < 10)
t_str += "0";
t_str += month(t);
t_str += ".";
t_str += year(t);
t_str += " ";
if (hour(t) < 10)
t_str += "0";
t_str += hour(t);
t_str += ":";
if (minute(t) < 10)
t_str += "0";
t_str += minute(t);
return t_str;
}
void setCharAtvfd(int row, int pos, int setchar) {
byte setcellcommand = 0;
if (row == 1) {
setcellcommand = helper1[pos];
} else {
setcellcommand = helper2[pos];
}
Serial1t.write(0x1B);
Serial1t.write(0x13);
Serial1t.write(setcellcommand);
Serial1t.write(setchar);
}
String centerString(String text) {
String returns = "";
int lengths = text.length();
int rest = 20 - lengths;
float siderest = rest / 2;
siderest = (int) floor(siderest);
for (int u = 0; u < siderest; u++)
returns += " ";
returns += text;
for (int u = returns.length(); u < 20; u++)
returns += " ";
return returns;
}
time_t rtcsync() {
return rtc.now().unixtime();
}
void replaceonlytime(time_t t) {
String t_str = "";
int myhour = hour(t);
int myminute = minute(t);
if (myhour < 10)
t_str += "0";
t_str += myhour;
t_str += ":";
if (myminute < 10)
t_str += "0";
t_str += myminute;
int myset = 0;
for (int s = 14; s < 19; s++) {
Serial1t.write(0x1B);
Serial1t.write(0x13);
Serial1t.write(helper2[s]);
Serial1t.write(t_str.charAt(s - 14));
myset++;
}
}
static int x1, x2, lastyear;
static byte lasttzHours;
int x3;
String inString = "";
boolean complete = false;
unsigned long latest = 0;
boolean summertime_EU() {
if (month() < 3 || month() > 10)
return false;
if (month() > 3 && month() < 10)
return true;
if (year() != lastyear || 0 != lasttzHours) {
x1 = 1 + 0 + 24 * (31 - (5 * year() / 4 + 4) % 7);
x2 = 1 + 0 + 24 * (31 - (5 * year() / 4 + 1) % 7);
lastyear = year();
lasttzHours = 0;
}
x3 = hour() + 24 * day();
if (month() == 3 && x3 >= x1 || month() == 10 && x3 < x2)
return true;
else
return false;
}