Hardware components | ||||||
| × | 1 | ||||
| × | 3 | ||||
| × | 1 | ||||
Software apps and online services | ||||||
| ||||||
Hand tools and fabrication machines | ||||||
| ||||||
|
The idea is to make a smart led display useful to display weather, news, time, and functionalities like timer and alert notifications. The hardware selected is no expensive and the assembling is very easy. The only tool I used is a tin soldering iron.
Here in the image the assembled display:
The display is made by 12 MAX 7291 (8x8 matrix red leds), on the market you can find a modules of 4 attached matrix, so it will be necessary to connect them only in two parts.
To control the device I selected the very powerful and versatile ESP32 microcontroller made by Espressif Systems. To speed-up the integration I used the ESP WROOM-32 on development board.
The ESP WROOM-32 development board is already integrated with a USB port that I used to power-on the artefact.
The last piece of hardware integrated was the Kemet SS-430 Pyroelectric Infrared Sensor Modules. The sensor was accomodate on the top of display near the USB port.
In the image is visible the connection of the Kemet sensor. The power was soldered to the Vin and GND pins in order to provide a 5V power request by specs. The Vout pin was instead soldered to the pin D25 (GPIO25).
Considering the maturity of Espressif library I decide to develop the software with the Arduino IDE.
The main software functionalities are listed hereafter:
- WiFi connection
- Web HMI with several controls
- Display rotation
- Weather forecast
- RSS feed display
- Allert
- Timer
- Automatic shout-down and power-on based on motion detection
- 2 slots schedule to disable automatic power-on
- Light intensity regulation through web-setup
- Speed regulation through web-setup
- Specular font
- Force refresh news update
- Force NTP update
- Custom message insertion through web-setup
To drive the display I used the library MD_parola available on the Arduino library. With this library was very easy to redefine a custom set of fonts also with some sprite to animate the display.
About future developmentsI'm actually working on control the display with Amazon Alexa. I've done some work but it is not enough mature to be presented here.
The idea is to use the display to show the title of songs reproduced by Alexa, display the timer created by Alexa commands and to activate a new security mode by vocal in order to be notified on the cell phone when a movement has been detected.
static const String APP_NAME = "T-Time";
static const String APP_VERSION = "V.1.0";
static const String APP_DATE = "01/03/2020";
// Define the number of devices we have in the chain and the hardware interface
#define MAX_DEVICES 12
#define CLK_PIN 14
#define DATA_PIN 12
#define CS_PIN 15
#define KEMET_PIN 25
#define AP_WIFI_SSID "LCD_SETUP"
#define AP_WIFI_PASSWD "XXXXXXXX"
#define ONBOARDLED 2 // Built in LED on ESP32 Node MCU
#define SPEED_TIME 14
#define INTENSITY 1
#define ALLERT_DURATION 25 //5 seconds = 200 ms * 25 allert_scorri
#define WEB_UPDATE 1 //minuti
unsigned long TIMEOUT_WEB = 15000; //milliseconds
#if DEBUG_TT
#define DEBUG_START Serial.begin(115200); Serial.println("Serial started @ 115200");
#define DEBUG_PRINT(x) Serial.print (x)
#define DEBUG_PRINTDEC(x) Serial.print (x, DEC)
#define DEBUG_PRINTLN(x) Serial.println (x)
#define DEBUG_PRINTLN2(x,y) Serial.println (x,y)
#define DEBUG_PRINTF1(x,y) Serial.printf (x,y)
#define DEBUG_PRINTF2(x,y,z) Serial.printf (x,y,z)
#else
#define DEBUG_PRINT(x)
#define DEBUG_PRINTDEC(x)
#define DEBUG_PRINTLN(x)
#define DEBUG_PRINTLN2(x,y)
#define DEBUG_PRINTF1(x,y)
#define DEBUG_PRINTF2(x,y,z)
#define DEBUG_START
#endif
// number of items in an array
#define NUMITEMS(arg) ((unsigned int) (sizeof (arg) / sizeof (arg [0])))
template< typename T, size_t N > size_t ArraySize (T (&) [N]) {
return N;
}
TaskHandle_t Task1;
TaskHandle_t Task2;
TaskHandle_t Task3;
AsyncWebServer server(80);
const String WIFIs[] = {"ID1XXXX", "PWD1XXXX","ID2XXXX", "PWD2XXXX"}; //add all wifi connection that you need
int8_t intensity = INTENSITY; //display intensity
int8_t speed = SPEED_TIME; //display speed time
int8_t allertDuration = ALLERT_DURATION; //display speed time
int8_t timeZone = 1;
int8_t minutesTimeZone = 0;
int8_t wifi = 0;
String ip = "IP NONE";
bool displayIP = true;
bool autostdbyActivate = true;
bool display_airbus_news = false;
//Multicore code
static int taskCore0 = 0;
static int taskCore1 = 1;
uint32_t lastTimeNews = 0; // millis() memory
long randNumber = 0;
// Read all the lines of the reply from server
#define MAX_LUNGH_RICERCA 512
#define MAX_MESG 300
char* ric = new char[MAX_LUNGH_RICERCA];
char* trovato = new char[MAX_MESG];
/*START NEWS NEWS*/
#define MAX_NEWS 20
uint32_t refresh_news_now = 10000;
uint8_t PREF_refresh_news_in_minutes = 30;
String NEWS_news[MAX_NEWS];
int NEWS_news_salvate = 0;
int NEWS_news_scorri = 0;
//http://feeds.bbci.co.uk/news/world/rss.xml
//http://www.NEWSimes.com/svc/collections/v1/publish/https://www.NEWSimes.com/section/world/rss.xml
String servernameNEWS = "feeds.bbci.co.uk"; // remote server we will connect to
String urlNEWS = "/news/world/rss.xml";
//DISPLAY
uint8_t STATO_SCENA_LOOP_2 = 0;
#define PAUSE_TIME 0
String CityID = "3180990";
String lang = "EN";
String APIKEY = "XXXXXXXXXXXXXXXXXXXXX"; //put your apikey here
const char* City[] = {"Roma,it"};
int CityInd = 0;
char* servername = "api.openweathermap.org"; // remote server we will connect to
// Global variables
uint8_t STATO_SCENA_LOOP_1 = 0; // current display mode
uint8_t STATO_SCORRI_PACMAN = 0;
bool STATO_GET_DISPLAY_ON = true;
char szSolo[9]; // mm:ss\0
char szMesg[MAX_MESG];
String message = String(APP_NAME) + " " + APP_VERSION; // a String to hold incoming data
boolean allertOn = false;
String allert = "ATTENZIONE!!!"; // a String to hold incoming data
char cmd[128] = "set time yyyy-mm-dd hh:mm:ss";
String meteo = " Meteo NaN";
String icon = "$";
uint8_t STATO_SCORRI_ALLERT = 0;
const uint8_t CONST_DISPLAY_MAX_LINES = 12 * 8;
char VAR_BARRA_STRING[2] = {0 , '\0'};
uint8_t lines_now = 0;
uint8_t lines_next = 0;
uint32_t timer[] = {0 , 0}; // { now secs , end secs }
boolean timer_on = false;
uint8_t colonT[] = { 1, 0, 0, 0, 0, 0, 0 }; // colonT
uint8_t PREF_h_m_s_on_1[] = { 10 , 0 , 0 };
uint8_t PREF_h_m_s_off_1[] = { 16 , 0 , 0 };
uint8_t PREF_h_m_s_on_2[] = { 18 , 0 , 0 };
uint8_t PREF_h_m_s_off_2[] = { 22 , 0 , 0 };
uint32_t lastTime = 0;
uint32_t lastTimeMain = 0;
uint32_t flash_interval = 200;
uint8_t tempo_display_time = 10; //any unit = 500 millis
// Generic output pins
MD_Parola parola = MD_Parola(MD_MAX72XX::FC16_HW, DATA_PIN, CLK_PIN, CS_PIN, MAX_DEVICES);
boolean PREF_rotate = 0;
int PREF_detection_time_out = 1;
boolean PREF_detection_on = true;
#if USE_PREFS
Preferences preferences;
#endif
/*T-Time Ver 1.0 2020-03-01*/
#define DEBUG_TT 1
#define USE_WIFI 1
#define USE_WEB 1
#define USE_NTP 1
#define USE_PREFS 1
#define USE_KEMET 1
#include "Include.h"
#include "Define.h"
void setup(void)
{
DEBUG_START
#if USE_PREFS
use_prefs();
#endif
initParola(PREF_rotate);
delay(3000);
#if USE_WIFI
use_wifi();
#endif
#if USE_WEB
use_web();
#endif
#if USE_KEMET
kemet_init();
#endif
//Multicore
xTaskCreatePinnedToCore(
updateTask, /* Function to implement the task */
"updateTask", /* Name of the task */
13000, /* Stack size in words */
NULL, /* Task input parameter */
1, /* Priority of the task */
&Task1, /* Task handle. */
taskCore0); /* Core where the task should be executed*/
DEBUG_PRINTLN("Task update created...");
}
void loop(void)
{
LOOP();
}
void connect(WiFiClient* client, String url,String host) {
(*client).print(String("GET ") + url + " HTTP/1.1\r\n" +
"Host: " + host + "\r\n");
(*client).println();
(*client).println();
}
void refresh_news() {
refresh_news_now = 0;
}
void getNEWSData() //client function to send/receive GET request data.
{
String result = "";
WiFiClient client;
const int httpPort = 80;
if (!client.connect(servernameNEWS.c_str(), httpPort)) {
return;
}
// This will send the request to the server
connect(&client,urlNEWS,servernameNEWS);
unsigned long timeout = millis();
while (client.available() == 0) {
if (millis() - timeout > TIMEOUT_WEB) {
client.stop();
return;
}
}
NEWS_news_salvate = 0;
while (client.available() && NEWS_news_salvate < MAX_NEWS) {
result = client.readStringUntil('\n');
if (cercaData(trovato, result, "<title><%!%[CDATA%[([^%]]*)", ric)) {
//news_title = String(trovato);
NEWS_news[NEWS_news_salvate] = String(trovato);
NEWS_news_salvate++;
} else
if (cercaData(trovato, result, "<description><%!%[CDATA%[([^%]]*)", ric)) {
NEWS_news[NEWS_news_salvate - 1] = String(NEWS_news[NEWS_news_salvate - 1] + " - " + trovato);
DEBUG_PRINTLN(NEWS_news[NEWS_news_salvate - 1]);
}
}
}
bool cercaData(char* buf, String testo, String regExp, char* cerca) {
MatchState ms;
if (testo.length() > MAX_LUNGH_RICERCA)
strncpy(cerca, testo.c_str(), MAX_LUNGH_RICERCA);
else
strcpy(cerca, testo.c_str());
//DEBUG_PRINTLN (cerca);
ms.Target(cerca);
char resultC = ms.Match(regExp.c_str());
switch (resultC)
{
case REGEXP_MATCHED:
DEBUG_PRINTLN ("-----");
DEBUG_PRINT("Matched on: ");
//matching offsets in ms.capture
DEBUG_PRINTF1("Captures: %d\n",ms.level);
for (int j = 0; j < ms.level; j++)
{
DEBUG_PRINTF1("Capture number: %d\n",j + 1);
DEBUG_PRINTF1("Text: '%s'\n",ms.GetCapture (buf, j));
#if !DEBUG_TT
ms.GetCapture (buf, j);
#endif
}
return true;
break;
case REGEXP_NOMATCH:
//DEBUG_PRINTLN ("No match.");
break;
default:
DEBUG_PRINTF1("Regexp error: %d\n",resultC);
break;
} // end of switch
return false;
}
bool contains(String s, String search) {
int lgsearch = search.length();
int max = s.length() - lgsearch;
for (int i = 0; i <= max; i++) {
if (s.substring(i,i+lgsearch) == search) return true; // or i
}
return false; //or -1
}
#if USE_KEMET
unsigned long PyroRead = 0;
unsigned long IR_threshold = 198000;
unsigned long sensor_time_out = 5000;
unsigned long sensor_time_in = 0;
// IR_threshold is in microsec (usec), therefore 198msec threshold
int IR_sensed = 0;
uint32_t KEMET_LAST_DETECTION = 0;
void kemet_init() {
pinMode(KEMET_PIN, INPUT); // sets the digital pin 25 as input
}
int kemet_loop() {
sensor_time_in = millis();
PyroRead = 0; // Reset readings
IR_sensed = 0;
while ((IR_sensed < 2) && ((millis()-sensor_time_in) < sensor_time_out)) { //Break after 2 good triggers or timeout
PyroRead = pulseIn(KEMET_PIN, HIGH); //Measure trigger point
if (PyroRead > IR_threshold) { //Make sure trigger is over 198msec)
IR_sensed++; //Mark as a good trigger
}
}
if(IR_sensed == 2) {
KEMET_LAST_DETECTION = millis();
DEBUG_PRINTLN("KEMET DETECTED");
return 1;
}
DEBUG_PRINTLN("KEMET EXPIRED");
return 0;
}
boolean kemet_time_out() {
static bool temp = true;
boolean val = (((millis()-KEMET_LAST_DETECTION) > PREF_detection_time_out * 60000) && PREF_detection_on);
if(val!=temp) DEBUG_PRINTLN(val?"KEMET TIME OUT":"KEMET ACTIVE");
temp = val;
return val;
}
#endif
#if USE_PREFS
void use_prefs() {
preferences.begin(APP_NAME.c_str(), false);
PREF_h_m_s_on_1[0]=preferences.getInt("h_on_1",PREF_h_m_s_on_1[0]);
PREF_h_m_s_on_1[1]=preferences.getInt("m_on_1",PREF_h_m_s_on_1[1]);
PREF_h_m_s_on_1[2]=preferences.getInt("s_on_1",PREF_h_m_s_on_1[2]);
PREF_h_m_s_off_1[0]=preferences.getInt("h_off_1",PREF_h_m_s_off_1[0]);
PREF_h_m_s_off_1[1]=preferences.getInt("m_off_1",PREF_h_m_s_off_1[1]);
PREF_h_m_s_off_1[2]=preferences.getInt("s_off_1",PREF_h_m_s_off_1[2]);
PREF_h_m_s_on_2[0]=preferences.getInt("h_on_2",PREF_h_m_s_on_2[0]);
PREF_h_m_s_on_2[1]=preferences.getInt("m_on_2",PREF_h_m_s_on_2[1]);
PREF_h_m_s_on_2[2]=preferences.getInt("s_on_2",PREF_h_m_s_on_2[2]);
PREF_h_m_s_off_2[0]=preferences.getInt("h_off_2",PREF_h_m_s_off_2[0]);
PREF_h_m_s_off_2[1]=preferences.getInt("m_off_2",PREF_h_m_s_off_2[1]);
PREF_h_m_s_off_2[2]=preferences.getInt("s_off_2",PREF_h_m_s_off_2[2]);
PREF_refresh_news_in_minutes=preferences.getUChar("refresh_news_in_minutes",PREF_refresh_news_in_minutes);
PREF_rotate=preferences.getBool("ROTATE",PREF_rotate);
PREF_detection_on=preferences.getBool("DETECTION",PREF_detection_on);
PREF_detection_time_out=preferences.getInt("DETECTION_TIME_OUT",PREF_detection_time_out);
}
void writePreferences() {
preferences.putInt("h_on_1",PREF_h_m_s_on_1[0]);
preferences.putInt("m_on_1",PREF_h_m_s_on_1[1]);
preferences.putInt("s_on_1",PREF_h_m_s_on_1[2]);
preferences.putInt("h_off_1",PREF_h_m_s_off_1[0]);
preferences.putInt("m_off_1",PREF_h_m_s_off_1[1]);
preferences.putInt("s_off_1",PREF_h_m_s_off_1[2]);
preferences.putInt("h_on_2",PREF_h_m_s_on_2[0]);
preferences.putInt("m_on_2",PREF_h_m_s_on_2[1]);
preferences.putInt("s_on_2",PREF_h_m_s_on_2[2]);
preferences.putInt("h_off_2",PREF_h_m_s_off_2[0]);
preferences.putInt("m_off_2",PREF_h_m_s_off_2[1]);
preferences.putInt("s_off_2",PREF_h_m_s_off_2[2]);
preferences.putUChar("refresh_news_in_minutes",PREF_refresh_news_in_minutes);
preferences.putBool("ROTATE",PREF_rotate);
preferences.putBool("DETECTION",PREF_detection_on);
preferences.putInt("DETECTION_TIME_OUT",PREF_detection_time_out);
}
void clearPreferences() {
preferences.clear();
}
#endif
void save(char* name,int value) {
#if USE_PREFS
preferences.putInt(name,value);
#endif
}
void save(char* name,String value) {
#if USE_PREFS
preferences.putString(name,value);
#endif
}
void save(char* name,boolean value) {
#if USE_PREFS
preferences.putBool(name,value);
#endif
}
void readCommand()
{
//Read command from the Arduino serial monitor to set the RTC.
//Case-sensitive and must be entered exactly as (24-hour clock):
// Set yyyy-mm-dd hh:mm:ss
// char cmd[255]="set time yyyy-mm-dd hh:mm:ss";
int i;
if (Serial.available() > 0) { //aNEWShing there?
i = 0; //yes, read the available characters
while (Serial.available() > 0) {
cmd[i++] = char(Serial.read());
}
cmd[i] = 0x00; //put in string terminator
int off = 9;
if (strncmp(cmd, "set time ", off) == 0) {
set_time(cmd, off);
} else if (strncmp(cmd, "set message ", 12) == 0) {
set_message(cmd, 12);
}
}
}
char *mon2str(uint8_t mon, char *psz, uint8_t len)
// Get a label from PROGMEM into a char array
{
static const __FlashStringHelper* str[] =
{
F("Jan"), F("Feb"), F("Mar"), F("Apr"),
F("May"), F("Jun"), F("Jul"), F("Aug"),
F("Sep"), F("Oct"), F("Nov"), F("Dec")
};
strncpy_P(psz, (const prog_char *)str[mon], len);
psz[len] = '\0';
return (psz);
}
char *dow2str(uint8_t code, char *psz, uint8_t len)
{
static const __FlashStringHelper* str[] =
{
F("Sun "), F("Mon "), F("Tue "),
F("Wed "), F("Thu "), F("Fri "),
F("Sat ")
};
strncpy_P(psz, (const prog_char *)str[code], len);
psz[len] = '\0';
return (psz);
}
void getTime(char *psz, boolean f)
// Code for reading clock time
{
String st = (f ? printTimeFormated("%H:%M") : printTimeFormated("%H^%M"));
sprintf(psz, "%s", st );
}
void getTime(char *psz)
// Code for reading clock time
{
getTime(psz, true);
}
void getDate(char *psz)
// Code for reading clock date
{
char szBuf[10];
struct tm time_tm = getTime_tm();
sprintf(psz, "%d %s %s", time_tm.tm_mday, mon2str(time_tm.tm_mon, szBuf, sizeof(szBuf) - 1), printTimeFormated("%Y"));
}
void getWday(char *psz)
// Code for reading clock date
{
struct tm time_tm = getTime_tm();
dow2str(time_tm.tm_wday, psz, MAX_MESG);
}
String web_clean(String from_web) {
from_web.replace("'","'");
from_web.replace("&","&");
from_web.replace("á","á");
from_web.replace("à","à");
from_web.replace("È","E'");
from_web.replace("é","é");
from_web.replace("è","è");
from_web.replace("í","í");
from_web.replace("ì","ì");
from_web.replace("ó","ó");
from_web.replace("ò","ò");
from_web.replace("ú","ú");
from_web.replace("ù","ù");
from_web.replace("’","'");//’
from_web.replace("‘","'");//‘
from_web.replace(""","\"");
from_web.replace("&ldquot;","\"");//“
from_web.replace("&rdquot;","\"");//”
from_web.replace("“","\"");//”
from_web.replace("”","\"");//”
return String(from_web);
}
void getTimer(char *psz, boolean f)
// Code for reading clock time
{
String st = (f ? printTimerFormated("%02d:%02d.%02d") : printTimerFormated("%02d^%02d.%02d"));
sprintf(psz, "%s", st );
}
#if USE_NTP
#include <sys/time.h>
const char* ntpServer = "pool.ntp.org";
const long gmtOffset_sec = 3600;
const int daylightOffset_sec = 3600;
void ntp() {
const char* ntpServer = "pool.ntp.org";
const long gmtOffset_sec = 3600;
const int daylightOffset_sec = 3600;
configTime(gmtOffset_sec, daylightOffset_sec, ntpServer);
printLocalTime();
}
void printLocalTime()
{
struct tm timeinfo;
if(!getLocalTime(&timeinfo)){
DEBUG_PRINTLN("Failed to obtain time");
return;
}
DEBUG_PRINTLN2(&timeinfo, "%A, %B %d %Y %H:%M:%S");
}
#endif
String printTimeFormated(String format)
{
struct tm timeinfo;
if(!getLocalTime(&timeinfo))
{
DEBUG_PRINTLN("Failed to obtain time");
return "00:00";
}
char timeStringBuff[50]; //50 chars should be enough
strftime(timeStringBuff, sizeof(timeStringBuff), format.c_str() , &timeinfo);
//"%A, %B %d %Y %H:%M:%S"
return String(timeStringBuff);
}
long getTimeSeconds()
{
struct tm timeinfo;
if(!getLocalTime(&timeinfo))
{
DEBUG_PRINTLN("Failed to obtain time");
return 0;
}
return timeinfo.tm_sec+timeinfo.tm_min*60L+timeinfo.tm_hour*3600L;
}
struct tm getTime_tm()
{
struct tm timeinfo;
if(!getLocalTime(&timeinfo))
{
DEBUG_PRINTLN("Failed to obtain time");
return timeinfo;
}
return timeinfo;
}
String printTimerFormated(String format)
{
uint32_t elasped = millis()/1000 - timer[0];
if (elasped > timer[1]) return String("00:00.00");
uint32_t remaining = timer[1] - elasped;
char timeStringBuff[10]; //50 chars should be enough
sprintf(timeStringBuff, format.c_str(), remaining/3600, (remaining/60)%60, remaining%60);
return String(timeStringBuff);
}
boolean timer_fired() {
if (!check_timer_on() && timer_on) {
timer_on = false;
return true;
}
return false;
}
boolean check_timer_on() {
uint32_t elasped = millis()/1000 - timer[0];
if (elasped < timer[1]) {
timer_on = true;
return true;
}
return false;
}
boolean display_off() {
long time_now = getTimeSeconds();
long time_on_1 = PREF_h_m_s_on_1[0] * 3600 + PREF_h_m_s_on_1[1] * 60 + PREF_h_m_s_on_1[2];
long time_off_1 = PREF_h_m_s_off_1[0] * 3600 + PREF_h_m_s_off_1[1] * 60 + PREF_h_m_s_off_1[2];
long time_on_2 = PREF_h_m_s_on_2[0] * 3600 + PREF_h_m_s_on_2[1] * 60 + PREF_h_m_s_on_2[2];
long time_off_2 = PREF_h_m_s_off_2[0] * 3600 + PREF_h_m_s_off_2[1] * 60 + PREF_h_m_s_off_2[2];
return !((time_now > time_on_1 && time_now < time_off_1) || (time_now > time_on_2 && time_now < time_off_2));
}
/*WETHER*/
#include <ArduinoJson.h> //https://github.com/bblanchon/ArduinoJson
void getWeatherData() //client function to send/receive GET request data.
{
String result = "";
WiFiClient client;
const int httpPort = 80;
if (!client.connect(servername, httpPort)) {
return;
}
// We now create a URI for the request
String url = "/data/2.5/forecast?q=" + String(City[CityInd]) + "&lang=" + lang + "&units=metric&cnt=5&APPID=" + APIKEY;
// This will send the request to the server
client.print(String("GET ") + url + " HTTP/1.1\r\n" +
"Host: " + servername + "\r\n" +
"Connection: close\r\n\r\n");
unsigned long timeout = millis();
while (client.available() == 0) {
if (millis() - timeout > TIMEOUT_WEB) {
client.stop();
return;
}
}
// Read all the lines of the reply from server
while (client.available()) {
result = client.readStringUntil('\r');
}
char jsonArray [result.length() + 1];
result.toCharArray(jsonArray, sizeof(jsonArray));
jsonArray[result.length() + 1] = '\0';
/*
StaticJsonBuffer<4096> json_buf;
JsonObject &root = json_buf.parseObject(jsonArray);*/
DEBUG_PRINTLN(jsonArray);
StaticJsonDocument<4096> doc;
// Deserialize the JSON document
DeserializationError error = deserializeJson(doc, jsonArray);
// Test if parsing succeeds.
if (error) {
Serial.print("deserializeJson() failed: ");
DEBUG_PRINTLN(error.c_str());
return;
}
// Get the root object in the document
JsonObject root = doc.as<JsonObject>();
if (root.isNull())
{
DEBUG_PRINTLN("parseObject() failed");
}
String location = root["city"]["name"];
String t0 = root["list"][1]["main"]["temp"];
String t2 = root["list"][2]["main"]["temp"];
String t4 = root["list"][4]["main"]["temp"];
String temperature = "+3h: "+ t0 + "@ +6h: " + t2 + "@ +12h: " + t4 + "@ ";
String weather = root["list"][0]["weather"]["main"];
String d0 = root["list"][1]["weather"][0]["description"];
String d4 = root["list"][4]["weather"][0]["description"];
String description = "+3h: " + d0 + " +12h: " + d4;
String idString = root["list"][0]["weather"][0]["id"];
String timeS = root["list"][0]["dt_txt"];
//DEBUG_PRINTLN(location + " - " + temperature + " - " + weather + " - " + description + " - " + timeS);
meteo = "" + location + " " + temperature + " - " + description;
DEBUG_PRINTLN(meteo);
}
/*WETHER*/
#if USE_WEB
void use_web(){
DEBUG_PRINTLN("Starting server");
server.on("/", HTTP_GET, [](AsyncWebServerRequest * request) {
//request->send(200, "text/plain", "Hello World");
web(request);
});
server.begin();
}
void style(AsyncResponseStream *response) {
response->print("<style>");
response->print(" .heading {");
response->print(" position: static;");
response->print(" display: block;");
response->print(" margin-right: 1px;");
response->print(" margin-left: 1px;");
response->print(" float: none;");
response->print(" text-align: center;");
response->print("}");
response->print(".button {");
//response->print(" display: inline;");
//response->print(" float: right;");
response->print(" border: 1px solid #000;");
response->print(" border-radius: 10px;");
response->print(" background-color: #4CAF50;"); /* Green */
response->print(" border: none;");
response->print(" color: white;");
response->print(" padding: 15px 32px;");
response->print(" text-align: center;");
response->print(" text-decoration: none;");
response->print(" font-size: 16px;");
response->print("}");
response->print(".text-block {");
response->print(" -moz-appearance: textfield;");
response->print(" -webkit-appearance: textfield;");
response->print(" position: relative;");
response->print(" display: block;");
response->print(" overflow: visible;");
response->print(" min-height: 40px;");
response->print(" min-width: 150px;");
response->print(" clear: both;");
response->print(" border: 5px solid #1b0e81;");
response->print(" border-radius: 10px;");
response->print(" background-image: -webkit-linear-gradient(219deg, #71b4fd, #fff);");
response->print(" background-image: linear-gradient(231deg, #71b4fd, #fff);");
response->print(" box-shadow: 0 0 6px 0 #fff;");
response->print(" font-weight: 700;");
response->print(" letter-spacing: 0px;");
response->print(" text-transform: none;");
response->print("}");
response->print(".text-block2 {");
response->print(" position: relative;");
response->print(" display: block;");
response->print(" overflow: visible;");
response->print(" min-height: 40px;");
response->print(" min-width: 150px;");
response->print(" clear: both;");
response->print(" border: 5px solid #1b0e81;");
response->print(" border-radius: 10px;");
response->print(" background-image: -webkit-linear-gradient(219deg, #31a1fd, #fff);");
response->print(" background-image: linear-gradient(231deg, #31a1fd, #fff);");
response->print(" box-shadow: 0 0 6px 0 #fff;");
response->print(" font-weight: 700;");
response->print(" letter-spacing: 0px;");
response->print(" text-transform: none;");
response->print("}");
response->print(".body {");
response->print(" border: 10 px solid #000;");
response->print(" background-color: #000;");
response->print("}");
response->print(".section {");
response->print(" max-height: 30px;");
response->print(" min-height: 30px;");
response->print(" border-style: none;");
response->print(" opacity: 0;");
response->print(" -webkit-perspective: 751px;");
response->print("}");
response->print("</style>");
}
void web(AsyncWebServerRequest *request) {
int params = request->params();
for (int i = 0; i < params; i++) {
AsyncWebParameter* p = request->getParam(i);
{
DEBUG_PRINTLN("GET[" + p->name() + "]: " + p->value());
if (strncmp(p->name().c_str(), "time", 4) == 0) {
set_time(p->value().c_str(), 0);
} else if (strncmp(p->name().c_str(), "message", 7) == 0) {
set_message(p->value().c_str(), 0);
} else if (strncmp(p->name().c_str(), "rotate", 6) == 0) {
PREF_rotate = !PREF_rotate;
save("ROTATE",PREF_rotate);
setOrientation(PREF_rotate);
} else if (strncmp(p->name().c_str(), "icon", 4) == 0) {
set_icon(p->value().c_str(), 0);
} else if (strncmp(p->name().c_str(), "uicon", 5) == 0) {
unset_icon();
} else if (strncmp(p->name().c_str(), "intensity", 9) == 0) {
set_intensity(p->value().c_str(), 0);
} else if (strncmp(p->name().c_str(), "reset", 5) == 0) {
reset();
} else if (strncmp(p->name().c_str(), "speed", 5) == 0) {
set_speed(p->value().c_str(), 0);
} else if (strncmp(p->name().c_str(), "invert", 6) == 0) {
invert();
} else if (strncmp(p->name().c_str(), "ntp", 3) == 0) {
#if USE_NTP
ntp();
#endif
} else if (strncmp(p->name().c_str(), "wifi", 4) == 0) {
set_wifi(p->value().c_str(), 0);
} else if (strncmp(p->name().c_str(), "on", 2) == 0) {
on();
} else if (strncmp(p->name().c_str(), "det_time_out", 12) == 0) {
//setDetTimeOut(p->value().c_str(), 0);
PREF_detection_time_out = atoi(p->value().c_str());
save("DETECTION",PREF_detection_time_out);
} else if (strncmp(p->name().c_str(), "detection_on", 12) == 0) {
PREF_detection_on = true;
save("DETECTION",PREF_detection_on);
} else if (strncmp(p->name().c_str(), "detection_off", 13) == 0) {
PREF_detection_on = false;
save("DETECTION",PREF_detection_on);
} else if (strncmp(p->name().c_str(), "off", 3) == 0) {
off();
} else if (strncmp(p->name().c_str(), "disreset", 8) == 0) {
display_reset();
} else if (strncmp(p->name().c_str(), "displayon_1", 11) == 0) {
displayon_1(p->value().c_str(), 0);
} else if (strncmp(p->name().c_str(), "displayoff_1", 12) == 0) {
displayoff_1(p->value().c_str(), 0);
} else if (strncmp(p->name().c_str(), "displayon_2", 11) == 0) {
displayon_2(p->value().c_str(), 0);
} else if (strncmp(p->name().c_str(), "displayoff_2", 12) == 0) {
displayoff_2(p->value().c_str(), 0);
} else if (strncmp(p->name().c_str(), "allert", 6) == 0) {
set_allert(p->value().c_str(), 0);
} else if (strncmp(p->name().c_str(), "uallert", 7) == 0) {
unset_allert();
} else if (strncmp(p->name().c_str(), "autostdbyon", 11) == 0) {
active_autostdby();
} else if (strncmp(p->name().c_str(), "autostdbyoff", 12) == 0) {
deactive_autostdby();
} else if (strncmp(p->name().c_str(), "refresh_news", 12) == 0) {
refresh_news();
} else if (strncmp(p->name().c_str(), "set_timer", 9) == 0) {
set_timer(p->value().c_str(), 0);
}
}
}
AsyncResponseStream *response = request->beginResponseStream("text/html");
response->addHeader("Server", "ESP Async Web Server");
response->printf("<!DOCTYPE html><html><head><title>Webpage at %s</title>", request->url().c_str());
style(response);
response->printf("</head><body>");
char z[2];
itoa(intensity , z , 0);
String str = String(z);
response->print("<h1 class=\"heading\">" +APP_NAME+" "+ APP_VERSION + "</h1>");
response->print("<h1 class=\"heading\">ESP32 MAX7219 KEMET-SS-430</h1>");
response->print("<div class=\"section\"></div>");
response->print("<div class=\"text-block2\" id=\"demo\"></div>");
response->print("<div class=\"section\"></div>");
response->printf("<div contenteditable=\"true\" class=\"text-block\" type=\"text\" id=\"intensity\">%d</div>", intensity);
response->print("<div class=\"button\" onclick=\"setIntensity();\">SET INTENSITY</div>");
response->print("<div class=\"section\"></div>");
response->print("<div contenteditable=\"true\" class=\"text-block\" type=\"text\" id=\"message\">" + message + "</div>");
response->print("<div class=\"button\" onclick=\"setMessage();\">SET MESSAGE</div>");
response->print("<div class=\"section\"></div>");
response->print("<div contenteditable=\"true\" class=\"text-block\" type=\"text\" id=\"allert\">" + allert + "</div>");
response->print("<div class=\"button\" onclick=\"setAllert();\">SET ALLERT</div>");
response->print("<div class=\"button\" onclick=\"unsetAllert();\">UNSET ALLERT</div>");
response->print("<div class=\"section\"></div>");
response->printf("<div contenteditable=\"true\" class=\"text-block\" type=\"text\" id=\"speed\">%02d</div>", speed);
response->print("<div class=\"button\" onclick=\"setSpeed();\">SET SPEED</div>");
response->print("<div class=\"section\"></div>");
response->printf("<div contenteditable=\"true\" class=\"text-block\" type=\"text\" id=\"timer\">%02d:%02d.%02d</div>", timer[1]/3600, (timer[1]/60)%60, timer[1]%60);
response->print("<div class=\"button\" onclick=\"set_timer();\">SET TIMER</div>");
response->print("<div class=\"section\"></div>");
response->print("<div class=\"text-block\" type=\"text\" id=\"time\"></div>");
response->print("<div class=\"button\" onclick=\"setTime();\">SET TIME</div>");
response->print("<div class=\"section\"></div>");
response->printf("<div contenteditable=\"true\" class=\"text-block\" type=\"text\" id=\"displayon_1\">%02d:%02d:%02d</div>", PREF_h_m_s_on_1[0], PREF_h_m_s_on_1[1], PREF_h_m_s_on_1[2]);
response->printf("<div contenteditable=\"true\" class=\"text-block\" type=\"text\" id=\"displayoff_1\">%02d:%02d:%02d</div>", PREF_h_m_s_off_1[0], PREF_h_m_s_off_1[1], PREF_h_m_s_off_1[2]);
response->printf("<div contenteditable=\"true\" class=\"text-block\" type=\"text\" id=\"displayon_2\">%02d:%02d:%02d</div>", PREF_h_m_s_on_2[0], PREF_h_m_s_on_2[1], PREF_h_m_s_on_2[2]);
response->printf("<div contenteditable=\"true\" class=\"text-block\" type=\"text\" id=\"displayoff_2\">%02d:%02d:%02d</div>", PREF_h_m_s_off_2[0], PREF_h_m_s_off_2[1], PREF_h_m_s_off_2[2]);
response->print("<div class=\"button\" onclick=\"setOnOff();\">SAVE DISPLAY ON OFF</div>");
response->print("<div class=\"button\" onclick=\"autostdbyOn();\" id=\"autostdbyon\">ACTIVATE</div>");
response->print("<div class=\"button\" onclick=\"autostdbyOff();\" id=\"autostdbyoff\">DEACTIVATE</div>");
response->print("<div class=\"section\"></div>");
response->print("<div class=\"button\" type=\"button\" onclick=\"inverti();\">INVERTI</div>");
response->print("<div class=\"button\" type=\"button\" onclick=\"rotate();\">ROTATE</div>");
response->print("<div class=\"section\"></div>");
response->print("<div class=\"button\" type=\"button\" onclick=\"reset();\">RESET</div>");
response->print("<div class=\"section\"></div>");
response->print("<div class=\"button\" type=\"button\" onclick=\"ntp();\">FORECE NTP</div>");
response->print("<div class=\"section\"></div>");
response->printf("<div contenteditable=\"true\" class=\"text-block\" type=\"text\" id=\"det_time_out\">%02d</div>", PREF_detection_time_out);
response->print("<div class=\"button\" onclick=\"setDetTimeOut();\">SAVE Detection Time Out</div>");
response->print("<div class=\"button\" type=\"button\" onclick=\"detection_on();\">DETECTION ON</div>");
response->print("<div class=\"button\" type=\"button\" onclick=\"detection_off();\">DETECTIONOFF</div>");
response->print("<div class=\"section\"></div>");
response->print("<div class=\"button\" type=\"button\" onclick=\"on();\">ON</div>");
response->print("<div class=\"button\" type=\"button\" onclick=\"off();\">OFF</div>");
response->print("<div class=\"button\" type=\"button\" onclick=\"disReset();\">DISPLEY RESET</div>");
response->print("<div class=\"section\"></div>");
response->print("<div class=\"button\" type=\"button\" onclick=\"refresh_news();\">REFRESH NEWS</div>");
response->print("<div class=\"section\"></div>");
for (int sc = 0; sc < NEWS_news_salvate; sc++) {
response->printf("<div class=\"text-block\" type=\"text\" id=\"news%02d\">News %02d - ", sc, sc);
response->print(NEWS_news[sc] + "</div>");
}
response->print("<div class=\"section\"></div>");
response->print("<div class=\"section\"></div>");
response->print("<script>(function () {");
response->print("function checkTime(i) { ");
response->print(" return (i < 10) ? \"0\" + i : i;}");
response->print("function startTime() {");
response->print("var today = new Date(); var dd = today.getDate(); var mm = today.getMonth()+1; var yyyy = today.getFullYear();");
response->print("if(dd<10){dd='0'+dd} if(mm<10){mm='0'+mm}");
response->print("var h = checkTime(today.getHours()),m = checkTime(today.getMinutes()),s = checkTime(today.getSeconds());");
//response->print("if(h<10){h='0'+h} if(m<10){m='0'+m} if(s<10){s='0'+s} ");
response->print("document.getElementById('time').innerHTML = yyyy+'-'+mm+'-'+dd + \"-\" + h + \":\" + m + \":\" + s;");
response->print("t = setTimeout(function () {startTime()}, 500);");
response->print("}startTime();");
response->print("})();");
response->print("function setTime() {");
response->print(" var xhttp = new XMLHttpRequest();");
response->print(" xhttp.onreadystatechange = function() {");
response->print(" if (this.readyState == 4 && this.status == 200) {");
response->print(" document.getElementById(\"demo\").innerHTML = \"/?time=\"+document.getElementById('time').innerHTML");
response->print(" }");
response->print(" };");
response->print(" xhttp.open(\"GET\", \"/?time=\"+document.getElementById('time').innerHTML, true);");
response->print(" xhttp.send();");
response->print("}");
response->print("function setMessage() {");
response->print(" var xhttp = new XMLHttpRequest();");
response->print(" xhttp.onreadystatechange = function() {");
response->print(" if (this.readyState == 4 && this.status == 200) {");
response->print(" document.getElementById(\"demo\").innerHTML = \"/?message=\"+encodeURI(document.getElementById('message').innerHTML)");
response->print(" }");
response->print(" };");
response->print(" xhttp.open(\"GET\", \"/?message=\"+encodeURI(document.getElementById('message').innerHTML), true);");
response->print(" xhttp.send();");
response->print("}");
response->print("function setAllert() {");
response->print(" var xhttp = new XMLHttpRequest();");
response->print(" xhttp.onreadystatechange = function() {");
response->print(" if (this.readyState == 4 && this.status == 200) {");
response->print(" document.getElementById(\"demo\").innerHTML = \"/?allert=\"+encodeURI(document.getElementById('allert').innerHTML)");
response->print(" }");
response->print(" };");
response->print(" xhttp.open(\"GET\", \"/?allert=\"+encodeURI(document.getElementById('allert').innerHTML), true);");
response->print(" xhttp.send();");
response->print("}");
response->print("function unsetAllert() {");
response->print(" var xhttp = new XMLHttpRequest();");
response->print(" xhttp.onreadystatechange = function() {");
response->print(" if (this.readyState == 4 && this.status == 200) {");
response->print(" document.getElementById(\"demo\").innerHTML = \"/?uallert\"");
response->print(" }");
response->print(" };");
response->print(" xhttp.open(\"GET\", \"/?uallert\", true);");
response->print(" xhttp.send();");
response->print("}");
response->print("function setIntensity() {");
response->print(" var xhttp = new XMLHttpRequest();");
response->print(" xhttp.onreadystatechange = function() {");
response->print(" if (this.readyState == 4 && this.status == 200) {");
response->print(" document.getElementById(\"demo\").innerHTML = \"/?intensity=\"+encodeURI(document.getElementById('intensity').innerHTML)");
response->print(" }");
response->print(" };");
response->print(" xhttp.open(\"GET\", \"/?intensity=\"+encodeURI(document.getElementById('intensity').innerHTML), true);");
response->print(" xhttp.send();");
response->print("}");
response->print("function setIcon() {");
response->print(" var xhttp = new XMLHttpRequest();");
response->print(" xhttp.onreadystatechange = function() {");
response->print(" if (this.readyState == 4 && this.status == 200) {");
response->print(" document.getElementById(\"demo\").innerHTML = \"/?icon=\"+encodeURI(document.getElementById('icon').innerHTML)");
response->print(" }");
response->print(" };");
response->print(" xhttp.open(\"GET\", \"/?icon=\"+encodeURI(document.getElementById('icon').innerHTML), true);");
response->print(" xhttp.send();");
response->print("}");
response->print("function unsetIcon() {");
response->print(" var xhttp = new XMLHttpRequest();");
response->print(" xhttp.onreadystatechange = function() {");
response->print(" if (this.readyState == 4 && this.status == 200) {");
response->print(" document.getElementById(\"demo\").innerHTML = \"/?uicon\"");
response->print(" }");
response->print(" };");
response->print(" xhttp.open(\"GET\", \"/?uicon\", true);");
response->print(" xhttp.send();");
response->print("}");
response->print("function setSpeed() {");
response->print(" var xhttp = new XMLHttpRequest();");
response->print(" xhttp.onreadystatechange = function() {");
response->print(" if (this.readyState == 4 && this.status == 200) {");
response->print(" document.getElementById(\"demo\").innerHTML = \"/?speed=\"+encodeURI(document.getElementById('speed').innerHTML)");
response->print(" }");
response->print(" };");
response->print(" xhttp.open(\"GET\", \"/?speed=\"+encodeURI(document.getElementById('speed').innerHTML), true);");
response->print(" xhttp.send();");
response->print("}");
response->print("function setOnOff() {");
response->print(" var xhttp = new XMLHttpRequest();");
response->print(" xhttp.onreadystatechange = function() {");
response->print(" if (this.readyState == 4 && this.status == 200) {");
response->print(" document.getElementById(\"demo\").innerHTML = \"/?displayon_1=\"+encodeURI(document.getElementById('displayon_1').innerHTML)+\"&displayoff_1=\"+encodeURI(document.getElementById('displayoff_1').innerHTML)+\"&displayon_2=\"+encodeURI(document.getElementById('displayon_2').innerHTML)+\"&displayoff_2=\"+encodeURI(document.getElementById('displayoff_2').innerHTML)");
response->print(" }");
response->print(" };");
response->print(" xhttp.open(\"GET\", \"/?displayon_1=\"+encodeURI(document.getElementById('displayon_1').innerHTML)+\"&displayoff_1=\"+encodeURI(document.getElementById('displayoff_1').innerHTML)+\"&displayon_2=\"+encodeURI(document.getElementById('displayon_2').innerHTML)+\"&displayoff_2=\"+encodeURI(document.getElementById('displayoff_2').innerHTML), true);");
response->print(" xhttp.send();");
response->print("}");
response->print("function autostdbyOn() {");
response->print(" var xhttp = new XMLHttpRequest();");
response->print(" xhttp.onreadystatechange = function() {");
response->print(" if (this.readyState == 4 && this.status == 200) {");
response->print(" document.getElementById(\"demo\").innerHTML = \"/?autostdbyon\"");
response->print(" }");
response->print(" };");
response->print(" xhttp.open(\"GET\", \"/?autostdbyon\", true);");
response->print(" xhttp.send();");
response->print("}");
response->print("function autostdbyOff() {");
response->print(" var xhttp = new XMLHttpRequest();");
response->print(" xhttp.onreadystatechange = function() {");
response->print(" if (this.readyState == 4 && this.status == 200) {");
response->print(" document.getElementById(\"demo\").innerHTML = \"/?autostdbyoff\"");
response->print(" }");
response->print(" };");
response->print(" xhttp.open(\"GET\", \"/?autostdbyoff\", true);");
response->print(" xhttp.send();");
response->print("}");
response->print("function inverti() {");
response->print(" var xhttp = new XMLHttpRequest();");
response->print(" xhttp.onreadystatechange = function() {");
response->print(" if (this.readyState == 4 && this.status == 200) {");
response->print(" document.getElementById(\"demo\").innerHTML = \"/?invert\"");
response->print(" }");
response->print(" };");
response->print(" xhttp.open(\"GET\", \"/?invert\", true);");
response->print(" xhttp.send();");
response->print("}");
response->print("function rotate() {");
response->print(" var xhttp = new XMLHttpRequest();");
response->print(" xhttp.onreadystatechange = function() {");
response->print(" if (this.readyState == 4 && this.status == 200) {");
response->print(" document.getElementById(\"demo\").innerHTML = \"/?rotate\"");
response->print(" }");
response->print(" };");
response->print(" xhttp.open(\"GET\", \"/?rotate\", true);");
response->print(" xhttp.send();");
response->print("}");
response->print("function reset() {");
response->print(" var xhttp = new XMLHttpRequest();");
response->print(" xhttp.onreadystatechange = function() {");
response->print(" if (this.readyState == 4 && this.status == 200) {");
response->print(" document.getElementById(\"demo\").innerHTML = \"/?reset\"");
response->print(" }");
response->print(" };");
response->print(" xhttp.open(\"GET\", \"/?reset\", true);");
response->print(" xhttp.send();");
response->print("}");
response->print("function ntp() {");
response->print(" var xhttp = new XMLHttpRequest();");
response->print(" xhttp.onreadystatechange = function() {");
response->print(" if (this.readyState == 4 && this.status == 200) {");
response->print(" document.getElementById(\"demo\").innerHTML = \"/?ntp\"");
response->print(" }");
response->print(" };");
response->print(" xhttp.open(\"GET\", \"/?ntp\", true);");
response->print(" xhttp.send();");
response->print("}");
response->print("function setDetTimeOut() {");
response->print(" var xhttp = new XMLHttpRequest();");
response->print(" xhttp.onreadystatechange = function() {");
response->print(" if (this.readyState == 4 && this.status == 200) {");
response->print(" document.getElementById(\"demo\").innerHTML = \"/?det_time_out=\"+encodeURI(document.getElementById('det_time_out').innerHTML)");
response->print(" }");
response->print(" };");
response->print(" xhttp.open(\"GET\", \"/?det_time_out=\"+encodeURI(document.getElementById('det_time_out').innerHTML), true);");
response->print(" xhttp.send();");
response->print("}");
response->print("function detection_on() {");
response->print(" var xhttp = new XMLHttpRequest();");
response->print(" xhttp.onreadystatechange = function() {");
response->print(" if (this.readyState == 4 && this.status == 200) {");
response->print(" document.getElementById(\"demo\").innerHTML = \"/?detection_on\"");
response->print(" }");
response->print(" };");
response->print(" xhttp.open(\"GET\", \"/?detection_on\", true);");
response->print(" xhttp.send();");
response->print("}");
response->print("function detection_off() {");
response->print(" var xhttp = new XMLHttpRequest();");
response->print(" xhttp.onreadystatechange = function() {");
response->print(" if (this.readyState == 4 && this.status == 200) {");
response->print(" document.getElementById(\"demo\").innerHTML = \"/?detection_off\"");
response->print(" }");
response->print(" };");
response->print(" xhttp.open(\"GET\", \"/?detection_off\", true);");
response->print(" xhttp.send();");
response->print("}");
response->print("function on() {");
response->print(" var xhttp = new XMLHttpRequest();");
response->print(" xhttp.onreadystatechange = function() {");
response->print(" if (this.readyState == 4 && this.status == 200) {");
response->print(" document.getElementById(\"demo\").innerHTML = \"/?on\"");
response->print(" }");
response->print(" };");
response->print(" xhttp.open(\"GET\", \"/?on\", true);");
response->print(" xhttp.send();");
response->print("}");
response->print("function off() {");
response->print(" var xhttp = new XMLHttpRequest();");
response->print(" xhttp.onreadystatechange = function() {");
response->print(" if (this.readyState == 4 && this.status == 200) {");
response->print(" document.getElementById(\"demo\").innerHTML = \"/?off\"");
response->print(" }");
response->print(" };");
response->print(" xhttp.open(\"GET\", \"/?off\", true);");
response->print(" xhttp.send();");
response->print("}");
response->print("function disReset() {");
response->print(" var xhttp = new XMLHttpRequest();");
response->print(" xhttp.onreadystatechange = function() {");
response->print(" if (this.readyState == 4 && this.status == 200) {");
response->print(" document.getElementById(\"demo\").innerHTML = \"/?disreset\"");
response->print(" }");
response->print(" };");
response->print(" xhttp.open(\"GET\", \"/?disreset\", true);");
response->print(" xhttp.send();");
response->print("}");
response->print("function refresh_news() {");
response->print(" var xhttp = new XMLHttpRequest();");
response->print(" xhttp.onreadystatechange = function() {");
response->print(" if (this.readyState == 4 && this.status == 200) {");
response->print(" document.getElementById(\"demo\").innerHTML = \"/?refresh_news\"");
response->print(" }");
response->print(" };");
response->print(" xhttp.open(\"GET\", \"/?refresh_news\", true);");
response->print(" xhttp.send();");
response->print("}");
response->print("function set_timer() {");
response->print(" var xhttp = new XMLHttpRequest();");
response->print(" xhttp.onreadystatechange = function() {");
response->print(" if (this.readyState == 4 && this.status == 200) {");
response->print(" document.getElementById(\"demo\").innerHTML = \"/?set_timer=\"+document.getElementById('timer').innerHTML");
response->print(" }");
response->print(" };");
response->print(" xhttp.open(\"GET\", \"/?set_timer=\"+document.getElementById('timer').innerHTML, true);");
response->print(" xhttp.send();");
response->print("}");
response->print("</script>");
response->print("</body></html>");
//send the response last
request->send(response);
}
#endif
#if USE_WIFI
void setupMDNS() {
char host[16];
snprintf(host, 16, "ESP%012llX", ESP.getEfuseMac());
MDNS.begin(host);
MDNS.addService("http", "tcp", 80);
DEBUG_PRINTF1("Ready! Open http://%s.local in your browser\n", host);
}
void use_wifi() {
DEBUG_PRINTLN("Starting WIFI");
// delete old config
WiFi.disconnect(true);
delay(1000);
// Examples of different ways to register wifi events
WiFi.onEvent(WiFiEvent);
// Remove WiFi event
// Serial.print("WiFi Event ID: ");
// DEBUG_PRINTLN(eventID);
// WiFi.removeEvent(eventID);
WiFi.begin (WIFIs[0].c_str(), WIFIs[1].c_str());
}
void WiFiEvent (WiFiEvent_t event)
{
DEBUG_PRINTF1("[WiFi-event] event: %d\n", event);
switch (event) {
case SYSTEM_EVENT_WIFI_READY:
DEBUG_PRINTLN("WiFi interface ready");
break;
case SYSTEM_EVENT_SCAN_DONE:
DEBUG_PRINTLN("Completed scan for access points");
break;
case SYSTEM_EVENT_STA_START:
DEBUG_PRINTLN("WiFi client started");
break;
case SYSTEM_EVENT_STA_STOP:
DEBUG_PRINTLN("WiFi clients stopped");
break;
case SYSTEM_EVENT_STA_CONNECTED:
DEBUG_PRINTLN("Connected to access point");
break;
case SYSTEM_EVENT_STA_DISCONNECTED:
DEBUG_PRINTLN("Disconnected from WiFi access point");
WiFi.begin (WIFIs[wifi*2].c_str(), WIFIs[wifi*2+1].c_str());
wifi=(wifi+1)%(sizeof(WIFIs)/2);
break;
case SYSTEM_EVENT_STA_AUTHMODE_CHANGE:
DEBUG_PRINTLN("Authentication mode of access point has changed");
break;
case SYSTEM_EVENT_STA_GOT_IP:
DEBUG_PRINT("Obtained IP address: ");
ip = String(WiFi.localIP());
displayIP = true;
#if USE_NTP
DEBUG_PRINTLN("Start NTP");
ntp();
#endif
setupMDNS();
break;
case SYSTEM_EVENT_STA_LOST_IP:
DEBUG_PRINTLN("Lost IP address and IP address is reset to 0");
break;
case SYSTEM_EVENT_STA_WPS_ER_SUCCESS:
DEBUG_PRINTLN("WiFi Protected Setup (WPS): succeeded in enrollee mode");
break;
case SYSTEM_EVENT_STA_WPS_ER_FAILED:
DEBUG_PRINTLN("WiFi Protected Setup (WPS): failed in enrollee mode");
break;
case SYSTEM_EVENT_STA_WPS_ER_TIMEOUT:
DEBUG_PRINTLN("WiFi Protected Setup (WPS): timeout in enrollee mode");
break;
case SYSTEM_EVENT_STA_WPS_ER_PIN:
DEBUG_PRINTLN("WiFi Protected Setup (WPS): pin code in enrollee mode");
break;
case SYSTEM_EVENT_AP_START:
DEBUG_PRINTLN("WiFi access point started");
break;
case SYSTEM_EVENT_AP_STOP:
DEBUG_PRINTLN("WiFi access point stopped");
break;
case SYSTEM_EVENT_AP_STACONNECTED:
DEBUG_PRINTLN("Client connected");
break;
case SYSTEM_EVENT_AP_STADISCONNECTED:
DEBUG_PRINTLN("Client disconnected");
break;
case SYSTEM_EVENT_AP_STAIPASSIGNED:
DEBUG_PRINTLN("Assigned IP address to client");
break;
case SYSTEM_EVENT_AP_PROBEREQRECVED:
DEBUG_PRINTLN("Received probe request");
break;
case SYSTEM_EVENT_GOT_IP6:
DEBUG_PRINTLN("IPv6 is preferred");
break;
case SYSTEM_EVENT_ETH_START:
DEBUG_PRINTLN("Ethernet started");
break;
case SYSTEM_EVENT_ETH_STOP:
DEBUG_PRINTLN("Ethernet stopped");
break;
case SYSTEM_EVENT_ETH_CONNECTED:
DEBUG_PRINTLN("Ethernet connected");
break;
case SYSTEM_EVENT_ETH_DISCONNECTED:
DEBUG_PRINTLN("Ethernet disconnected");
break;
case SYSTEM_EVENT_ETH_GOT_IP:
DEBUG_PRINTLN("Obtained IP address");
break;
default: break;
}
}
#endif
void LOOP() {
if(timer_fired()) set_allert("TIMER FIRED");
if((autostdbyActivate && !kemet_time_out() && !display_off()) || allertOn) {
on();
}
if (parola.displayAnimate())
{
if (!allertOn || STATO_SCORRI_ALLERT > allertDuration)
{
if (millis() - lastTimeMain >= 180000) //ogni tre minuti
{
lastTimeMain = millis();
if (STATO_GET_DISPLAY_ON) {
display_reset();
}
}
if (parola.getZoneStatus(0))
{
if (autostdbyActivate && kemet_time_out()) {
off();
delay(1000);
}
MainSceneNext();
parola.displayReset(0);
}
}
//PACMAN
if ((STATO_SCENA_LOOP_1 != 0) && (millis() - lastTime >= flash_interval))
{
lastTime = millis();
if (!allertOn || STATO_SCORRI_ALLERT > allertDuration) {
PacManNext();
parola.displayReset(1);
} else {
if (parola.getZoneStatus(0)) {
parola.setIntensity(10);
parola.displayClear();
AllertNext();
parola.displayReset(2);
STATO_SCORRI_ALLERT++;
if (STATO_SCORRI_ALLERT > allertDuration) {
parola.setIntensity(intensity);
flash_interval = 200;
} else {
flash_interval = 500;
}
}
}
}
}
}
void MainSceneNext() {
switch (STATO_SCENA_LOOP_1)
{
case 0:
if (STATO_GET_DISPLAY_ON) {
display_reset(); //per pulire lo schermo
}
//delay(3000);
parola.setTextEffect(0, pa_scroll_up(), pa_scroll_left());
STATO_SCENA_LOOP_1++;
SecondaryDisplay();
break;
case 1:
if (!animazioneTime(pa_scroll_up() , pa_scroll_left() , 5))
STATO_SCENA_LOOP_1++;
break;
case 2:
//delay(3000);
parola.setTextEffect(0, pa_scroll_left(), pa_scroll_left());
if (NEWS_news_salvate > 0) {
strcpy(szMesg, NEWS_news[NEWS_news_scorri].c_str());
NEWS_news_scorri = (NEWS_news_scorri + 1) % NEWS_news_salvate;
}
STATO_SCENA_LOOP_1++;
break;
case 3: // day of week
parola.setTextEffect(0, pa_scroll_left(), PA_NO_EFFECT);
STATO_SCENA_LOOP_1++;
getWday(szMesg);
break;
case 4: // Calendar
parola.setTextEffect(0, pa_scroll_left(), pa_scroll_left());
STATO_SCENA_LOOP_1++;
getDate(szMesg);
break;
case 5: // Meteo
parola.setTextEffect(0, pa_scroll_left(), pa_scroll_left());
STATO_SCENA_LOOP_1++;
strcpy(szMesg, meteo.c_str());
break;
case 6: // Animation
parola.setTextEffect(0, PA_PRINT, PA_NO_EFFECT);
if (!animazione())
STATO_SCENA_LOOP_1++;
break;
case 7: // animazioneTime
parola.setTextEffect(0, PA_PRINT, PA_NO_EFFECT);
if (!animazioneTimer(pa_scroll_up(), pa_scroll_left() , 10))
STATO_SCENA_LOOP_1++;
break;
default:
STATO_SCENA_LOOP_1 = 0;
break;
}
}
void SecondaryDisplay() {
switch (STATO_SCENA_LOOP_2) {
case 0:
if (displayIP) {
strcpy(szMesg, ip.c_str());
displayIP = false;
}
strcpy(szMesg, message.c_str());
break;
case 1:
strcpy(szMesg, "VACANCY");
break;
case 2:
strcpy(szMesg, "NO VACANCY");
break;
case 3:
strcpy(szMesg, "NO VACANCY");
break;
case 4:
strcpy(szMesg, "NO VACANCY");
break;
default:
strcpy(szMesg, message.c_str());
break;
}
}
void PacManNext() {
switch (STATO_SCORRI_PACMAN) {
case -2:
sprintf(szSolo, " ");
STATO_SCORRI_PACMAN = -1;
break;
case -1:
sprintf(szSolo, icon.c_str());
STATO_SCORRI_PACMAN = -2;
break;
case 0:
sprintf(szSolo, "%c", 201); //"&");
STATO_SCORRI_PACMAN++;
break;
case 1:
sprintf(szSolo, "%c", 202); //"$");
STATO_SCORRI_PACMAN++;
break;
case 2:
sprintf(szSolo, "%c", 203); //"#");
STATO_SCORRI_PACMAN++;
break;
case 3:
sprintf(szSolo, "%c", 204); //"#");
STATO_SCORRI_PACMAN++;
break;
case 4:
sprintf(szSolo, "%c", 203); //"#");
STATO_SCORRI_PACMAN++;
break;
default: //4
sprintf(szSolo, "%c", 202); //"$");
STATO_SCORRI_PACMAN = 0;
break;
}
}
void PacManNext(int phase) {
sprintf(szSolo, "%c", 201); //"&");
STATO_SCORRI_PACMAN=1;
}
void AllertNext() {
switch (STATO_SCORRI_ALLERT % 2) {
case 0:
sprintf(szMesg, allert.c_str());
break;
default: //1
sprintf(szMesg, " ");
break;
}
}
void updateTask( void * pvParameters ) {
DEBUG_PRINTLN("Task 2 Started");
while (true) {
//DEBUG_PRINTLN(taskMessage);
//delay(500); //any 5 seconds
if (((millis() - lastTimeNews) >= refresh_news_now) && WiFi.status() == WL_CONNECTED)
{
refresh_news_now = PREF_refresh_news_in_minutes * 60000;
lastTimeNews = millis();
getWeatherData();
DEBUG_PRINTLN("---->WEATHER");
getNEWSData();
DEBUG_PRINTLN("---->NEWS");
}
disableCore0WDT();
kemet_loop();
enableCore0WDT();
}
}
// Header file includes
#include <Arduino.h>
#include <WiFi.h>
#include <ESPmDNS.h>
#include <MD_Parola.h>
#include "JF_Font_Data.h"
#include <Regexp.h>
#include <TimeLib.h>
#include <AsyncTCP.h>
#include <ESPAsyncWebServer.h>
#if USE_PREFS
#include <Preferences.h>
#endif
// Data file for user example user defined fonts
#ifndef FONTDATA_H
#define FONTDATA_H
uint8_t jF_Custom[] = {
0, // 0
0, // 1
0, // 2
0, // 3
0, // 4
0, // 5
0, // 6
0, // 7
0, // 8
0, // 9
0, // 10
0, // 11
0, // 12
0, // 13
0, // 14
0, // 15
0, // 16
0, // 17
0, // 18
0, // 19
0, // 20
0, // 21
0, // 22
0, // 23
0, // 24
0, // 25
0, // 26
0, // 27
0, // 28
0, // 29
0, // 30
0, // 31
1, 0, // 32 - 'Space'
1, 95, // 33 - '!'
3, 7, 0, 7, // 34 - '"'
//5, 20, 127, 20, 127, 20, // 35 - '#'
8, 0, 56, 124, 254, 254, 234, 198, 68,
//5, 36, 42, 127, 42, 18, // 36 - '$'
8, 0, 56, 124, 254, 254, 250, 108, 40,
//5, 35, 19, 8, 100, 98, // 37 - '%'
8, 0, 56, 124, 254, 254, 250, 124, 40,
//5, 54, 73, 85, 34, 80, // 38 - '&'
8, 0, 56, 124, 254, 254, 250, 124, 56,
3, 8, 7, 3, // 39 - '''
3, 28, 34, 65, // 40 - '('
3, 65, 34, 28, // 41 - ')'
5, 42, 28, 127, 28, 42, // 42 - '*'
5, 8, 8, 62, 8, 8, // 43 - '+'
3, 128, 112, 48, // 44 - ','
5, 8, 8, 8, 8, 8, // 45 - '-'
1, 64, // 46 - '.'
5, 32, 16, 8, 4, 2, // 47 - '/'
7, 62, 127, 113, 89, 77, 127, 62, // 48 - '0'
6, 64, 66, 127, 127, 64, 64,
6, 98, 115, 89, 73, 111, 102,
6, 34, 99, 73, 73, 127, 54,
7, 24, 28, 22, 83, 127, 127, 80,
6, 39, 103, 69, 69, 125, 57,
6, 60, 126, 75, 73, 121, 48,
6, 3, 3, 113, 121, 15, 7,
6, 54, 127, 73, 73, 127, 54,
6, 6, 79, 73, 105, 63, 30, // 57 - '9'
1, 20, // 58 - ':'
0, // 59 - ';'
//5, 56 ,12 ,7 ,4 ,8, // 60 - '<'
8, 14, 31, 63, 126, 124, 62, 31, 14,
0, // 61 - '='
//5, 14, 24 ,112 ,16 ,8, // 62 - '>'
8, 0, 6, 15, 30, 60, 30, 15, 6,
0, // 63 - '?'
6, 3, 3, 56, 68, 68, 68, // 64 - '@' ----->deg C
5, 127, 9, 9, 9, 127, // 65 - 'A'
5, 127, 73, 73, 73, 54, // 66 - 'B'
5, 127, 65, 65, 65, 65, // 67 - 'C'
5, 127, 65, 65, 65, 62, // 68 - 'D'
5, 127, 73, 73, 73, 73, // 69 - 'E'
5, 127, 9, 9, 9, 9, // 70 - 'F'
5, 62, 65, 65, 81, 115, // 71 - 'G'
5, 127, 8, 8, 8, 127, // 72 - 'H'
3, 65, 127, 65, // 73 - 'I'
5, 32, 64, 65, 63, 1, // 74 - 'J'
5, 127, 8, 20, 34, 65, // 75 - 'K'
5, 127, 64, 64, 64, 64, // 76 - 'L'
5, 127, 2, 28, 2, 127, // 77 - 'M'
5, 127, 4, 8, 16, 127, // 78 - 'N'
5, 62, 65, 65, 65, 62, // 79 - 'O'
5, 127, 9, 9, 9, 6, // 80 - 'P'
5, 62, 65, 81, 33, 94, // 81 - 'Q'
5, 127, 9, 25, 41, 70, // 82 - 'R'
5, 38, 73, 73, 73, 50, // 83 - 'S'
5, 3, 1, 127, 1, 3, // 84 - 'T'
5, 63, 64, 64, 64, 63, // 85 - 'U'
5, 31, 32, 64, 32, 31, // 86 - 'V'
5, 63, 64, 56, 64, 63, // 87 - 'W'
5, 99, 20, 8, 20, 99, // 88 - 'X'
5, 3, 4, 120, 4, 3, // 89 - 'Y'
5, 97, 89, 73, 77, 67, // 90 - 'Z'
0, // 91 - '['
0, // 92 - '\'
0, // 93 - ']'
0, // 94 - '^'
0, // 95 - '_'
0, // 96 - '`'
5, 32, 84, 84, 120, 64, // 97 - 'a'
5, 127, 40, 68, 68, 56, // 98 - 'b'
5, 56, 68, 68, 68, 40, // 99 - 'c'
5, 56, 68, 68, 40, 127, // 100 - 'd'
5, 56, 84, 84, 84, 24, // 101 - 'e'
4, 8, 126, 9, 2, // 102 - 'f'
5, 24, 164, 164, 156, 120, // 103 - 'g'
5, 127, 8, 4, 4, 120, // 104 - 'h'
3, 68, 125, 64, // 105 - 'i'
4, 64, 128, 128, 122, // 106 - 'j'
4, 127, 16, 40, 68, // 107 - 'k'
3, 65, 127, 64, // 108 - 'l'
5, 124, 4, 120, 4, 120, // 109 - 'm'
5, 124, 8, 4, 4, 120, // 110 - 'n'
5, 56, 68, 68, 68, 56, // 111 - 'o'
5, 252, 24, 36, 36, 24, // 112 - 'p'
5, 24, 36, 36, 24, 252, // 113 - 'q'
5, 124, 8, 4, 4, 8, // 114 - 'r'
5, 72, 84, 84, 84, 36, // 115 - 's'
4, 4, 63, 68, 36, // 116 - 't'
5, 60, 64, 64, 32, 124, // 117 - 'u'
5, 28, 32, 64, 32, 28, // 118 - 'v'
5, 60, 64, 48, 64, 60, // 119 - 'w'
5, 68, 40, 16, 40, 68, // 120 - 'x'
5, 76, 144, 144, 144, 124, // 121 - 'y'
5, 68, 100, 84, 76, 68, // 122 - 'z'
0, // 123 - '{'
1, 127, // 124 - '|'
0, // 125
0, // 126
0, // 127
0, // 128
0, // 129
0, // 130
0, // 131
0, // 132
0, // 133
0, // 134
0, // 135
0, // 136
0, // 137
0, // 138
0, // 139
0, // 140
0, // 141
0, // 142
0, // 143
0, // 144
0, // 145
0, // 146
0, // 147
0, // 148
0, // 149
0, // 150
0, // 151
0, // 152
0, // 153
0, // 154
0, // 155
0, // 156
0, // 157
0, // 158
0, // 159
7, 33, 117, 85, 84, 60, 120, 64, // 160 - 'à'
7, 32, 116, 84, 85, 61, 121, 64, // 161 - 'á'
0, // 162
0, // 163
0, // 164
0, // 165
0, // 166
0, // 167
6, 57, 125, 85, 84, 92, 24, // 168 - è
6, 56, 124, 84, 85, 93, 25, // 169 - é
0, // 170
0, // 171
5, 1, 69, 125, 124, 64, // 172 - ì
4, 68, 125, 125, 65, // 173 - í
0, // 174
0, // 175
0, // 176
0, // 177
6, 57, 125, 69, 68, 124, 56, // 178 - ò
6, 56, 124, 68, 69, 125, 57, // 179 - ó
0, // 180
0, // 181
0, // 182
5, 8, 8, 42, 8, 8, // 183 - ÷
0, // 184
7, 61, 125, 65, 64, 60, 124, 64, // 185 - ù
7, 60, 124, 64, 65, 61, 125, 64, // 186 - ú
0, // 187
0, // 188
0, // 189
0, // 190
0, // 191
0, // 192
0, // 193
0, // 194
0, // 195
0, // 196
0, // 197
0, // 198
0, // 199
0, // 200
8, 60, 126, 255, 255, 255, 255, 126, 60, //Pacman
8, 60, 126, 255, 255, 255, 231, 102, 36,
7, 60, 126, 255, 255, 231, 231, 66,
7, 60, 126, 126, 255, 231, 195, 129,
7, 254, 123, 243, 127, 243, 123, 254, //Ghost
7, 254, 115, 251, 127, 243, 123, 254,
7, 254, 123, 243, 127, 251, 115, 254,
7, 254, 115, 251, 127, 243, 123, 254,
4, 24, 60, 60, 24, //Ball
0, // 210
8, 145, 66, 24, 61, 188, 24, 66, 137, // SNOW 211
8, 170, 85, 170, 85, 170, 85, 170, 85, // RAIN 212
8, 30, 33, 33, 45, 38, 34, 34, 28, // CLOUD 213
8, 158, 97, 161, 97, 166, 98, 34, 28, // SHOWERS 214
8, 165, 66, 165, 24, 24, 165, 66, 165, // SNOW 215
8, 14, 145, 81, 177, 22, 18, 18, 12, // STORM 216
8, 28, 34, 98, 34, 44, 100, 36, 24, // LIGHT RAIN 217
8, 145, 66, 24, 61, 188, 38, 34, 28, // VARIABLE 218
8, 148, 0, 33, 8, 128, 36, 1, 72, // FOG 219
0, // 220
0, // 221
0, // 222
0, // 223
0, // 224
0, // 225
0, // 226
0, // 227
0, // 228
0, // 229
0, // 230
0, // 231
0, // 232
0, // 233
0, // 234
0, // 235
0, // 236
0, // 237
0, // 238
0, // 239
0, // 240
0, // 241
0, // 242
0, // 243
0, // 244
0, // 245
0, // 246
0, // 247
0, // 248
0, // 249
0, // 250
0, // 251
0, // 252
0, // 253
0, // 254
0, // 255
};
#endif
#ifndef FONTDATA_H2
#define FONTDATA_H2
uint8_t myChars[] = {
0, // 0
0, // 1
0, // 2
0, // 3
0, // 4
0, // 5
0, // 6
0, // 7
0, // 8
0, // 9
0, // 10
0, // 11
0, // 12
0, // 13
0, // 14
0, // 15
0, // 16
0, // 17
0, // 18
0, // 19
0, // 20
0, // 21
0, // 22
0, // 23
0, // 24
0, // 25
0, // 26
0, // 27
0, // 28
0, // 29
0, // 30
0, // 31
2, 0, 0, // 32 - 'Space'
1, 95, // 33 - '!'
3, 7, 0, 7, // 34 - '"'
5, 20, 127, 20, 127, 20, // 35 - '#'
5, 36, 42, 127, 42, 18, // 36 - '$'
5, 35, 19, 8, 100, 98, // 37 - '%'
5, 54, 73, 85, 34, 80, // 38 - '&'
3, 8, 7, 3, // 39 - '''
3, 28, 34, 65, // 40 - '('
3, 65, 34, 28, // 41 - ')'
5, 42, 28, 127, 28, 42, // 42 - '*'
5, 8, 8, 62, 8, 8, // 43 - '+'
3, 128, 112, 48, // 44 - ','
5, 8, 8, 8, 8, 8, // 45 - '-'
1, 64, // 46 - '.'
5, 32, 16, 8, 4, 2, // 47 - '/'
7, 62, 127, 113, 89, 77, 127, 62, // 48 - '0'
6, 64, 66, 127, 127, 64, 64,
6, 98, 115, 89, 73, 111, 102,
6, 34, 99, 73, 73, 127, 54,
7, 24, 28, 22, 83, 127, 127, 80,
6, 39, 103, 69, 69, 125, 57,
6, 60, 126, 75, 73, 121, 48,
6, 3, 3, 113, 121, 15, 7,
6, 54, 127, 73, 73, 127, 54,
6, 6, 79, 73, 105, 63, 30, // 57 - '9'
1, 20, // 58 - ':'
3, 128, 236, 108, // 59 - ';'
//5, 56 ,12 ,7 ,4 ,8, // 60 - '<'
8, 14, 31, 63, 126, 124, 62, 31, 14,
0, // 61 - '='
//5, 14, 24 ,112 ,16 ,8, // 62 - '>'
8, 0, 6, 15, 30, 60, 30, 15, 6,
0, // 63 - '?'
6, 3, 3, 56, 68, 68, 68, // 64 - '@' ----->deg C
6, 124, 126, 19, 19, 126, 124, //A
7, 65, 127, 127, 73, 73, 127, 54,
7, 28, 62, 99, 65, 65, 99, 34,
7, 65, 127, 127, 65, 99, 62, 28,
7, 65, 127, 127, 73, 93, 65, 99,
7, 65, 127, 127, 73, 29, 1, 3,
7, 28, 62, 99, 65, 81, 115, 114,
6, 127, 127, 8, 8, 127, 127,
5, 0, 65, 127, 127, 65,
7, 48, 112, 64, 65, 127, 63, 1,
7, 65, 127, 127, 8, 28, 119, 99,
7, 65, 127, 127, 65, 64, 96, 112,
7, 127, 127, 14, 28, 14, 127, 127,
7, 127, 127, 6, 12, 24, 127, 127,
7, 28, 62, 99, 65, 99, 62, 28,
7, 65, 127, 127, 73, 9, 15, 6,
6, 30, 63, 33, 113, 127, 94,
7, 65, 127, 127, 9, 25, 127, 102,
6, 38, 111, 77, 89, 115, 50,
6, 3, 65, 127, 127, 65, 3,
6, 127, 127, 64, 64, 127, 127,
6, 31, 63, 96, 96, 63, 31,
7, 127, 127, 48, 24, 48, 127, 127,
7, 67, 103, 60, 24, 60, 103, 67,
6, 7, 79, 120, 120, 79, 7,
7, 71, 99, 113, 89, 77, 103, 115, //Z
0, // 91 - '['
0, // 92 - '\'
0, // 93 - ']'
0, // 94 - '^'
0, // 95 - '_'
0, // 96 - '`'
7, 32, 116, 84, 84, 60, 120, 64, // - 'a'
7, 65, 127, 63, 72, 72, 120, 48,
6, 56, 124, 68, 68, 108, 40,
7, 48, 120, 72, 73, 63, 127, 64,
6, 56, 124, 84, 84, 92, 24,
6, 72, 126, 127, 73, 3, 2,
7, 152, 188, 164, 164, 248, 124, 4,
7, 65, 127, 127, 8, 4, 124, 120,
5, 0, 68, 125, 125, 64,
6, 96, 224, 128, 128, 253, 125,
7, 65, 127, 127, 16, 56, 108, 68,
5, 0, 65, 127, 127, 64,
7, 124, 124, 24, 56, 28, 124, 120,
6, 124, 124, 4, 4, 124, 120,
6, 56, 124, 68, 68, 124, 56,
7, 132, 252, 248, 164, 36, 60, 24,
7, 24, 60, 36, 164, 248, 252, 132,
7, 68, 124, 120, 76, 4, 28, 24,
6, 72, 92, 84, 84, 116, 36,
6, 0, 4, 62, 127, 68, 36,
7, 60, 124, 64, 64, 60, 124, 64,
6, 28, 60, 96, 96, 60, 28,
7, 60, 124, 112, 56, 112, 124, 60,
7, 68, 108, 56, 16, 56, 108, 68,
6, 156, 188, 160, 160, 252, 124,
6, 76, 100, 116, 92, 76, 100, // 122 - 'z'
0, // 123 - '{'
1, 127, // 124 - '|'
0, // 125
0, // 126
0, // 127
0, // 128
0, // 129
0, // 130
0, // 131
0, // 132
0, // 133
0, // 134
0, // 135
0, // 136
0, // 137
0, // 138
0, // 139
0, // 140
0, // 141
0, // 142
0, // 143
0, // 144
0, // 145
0, // 146
0, // 147
0, // 148
0, // 149
0, // 150
0, // 151
0, // 152
0, // 153
0, // 154
0, // 155
0, // 156
0, // 157
0, // 158
0, // 159
7, 33, 117, 85, 84, 60, 120, 64, // 160 - 'à'
7, 32, 116, 84, 85, 61, 121, 64, // 161 - 'á'
0, // 162
0, // 163
0, // 164
0, // 165
0, // 166
0, // 167
6, 57, 125, 85, 84, 92, 24, // 168 - è
6, 56, 124, 84, 85, 93, 25, // 169 - é
0, // 170
0, // 171
5, 1, 69, 125, 124, 64, // 172 - ì
4, 68, 125, 125, 65, // 173 - í
0, // 174
0, // 175
0, // 176
0, // 177
6, 57, 125, 69, 68, 124, 56, // 178 - ò
6, 56, 124, 68, 69, 125, 57, // 179 - ó
0, // 180
0, // 181
0, // 182
5, 8, 8, 42, 8, 8, // 183 - ÷
0, // 184
7, 61, 125, 65, 64, 60, 124, 64, // 185 - ù
7, 60, 124, 64, 65, 61, 125, 64, // 186 - ú
0, // 187
0, // 188
0, // 189
0, // 190
0, // 191
0, // 192
0, // 193
0, // 194
0, // 195
0, // 196
0, // 197
0, // 198
8, 60, 126, 255, 255, 255, 255, 126, 60, //Pacman
8, 60, 126, 255, 255, 255, 231, 102, 36,
8, 60, 126, 255, 255, 231, 231, 66, 0,
8, 60, 126, 126, 255, 231, 195, 129, 0,
8, 60, 126, 255, 255, 231, 231, 66, 0,
8, 60, 126, 255, 255, 255, 231, 102, 36,
8, 254, 123, 243, 127, 243, 123, 254, 0, //Ghost
8, 254, 115, 251, 127, 243, 123, 254, 0,
8, 254, 123, 243, 127, 251, 115, 254, 0,
8, 254, 115, 251, 127, 243, 123, 254, 0,
4, 24, 60, 60, 24, 0, 0, //Ball
0, // 210
0, // 211
0, // 212
0, // 213
0, // 214
0, // 215
0, // 216
0, // 217
0, // 218
0, // 219
0, // 220
0, // 221
0, // 222
0, // 223
0, // 224
0, // 225
0, // 226
0, // 227
0, // 228
0, // 229
0, // 230
0, // 231
0, // 232
0, // 233
0, // 234
0, // 235
0, // 236
0, // 237
0, // 238
0, // 239
0, // 240
0, // 241
0, // 242
0, // 243
0, // 244
0, // 245
0, // 246
0, // 247
0, // 248
0, // 249
0, // 250
0, // 251
0, // 252
0, // 253
0, // 254
0, // 255
};
#endif
//animazione = 250 * 20 = 4 secondi
uint8_t ghost_scene = 0;
uint32_t lastTimeAnimation = 0;
bool animazione() {
if (millis() - lastTimeAnimation >= 250) //ogni 1 secondi
{
lastTimeAnimation = millis();
if (ghost_scene < 20) {
parola.setTextAlignment(0, PA_LEFT);
switch (ghost_scene) {
case 0:
sprintf(szMesg, "%c %c %c %c %c %c %c %c %c %c %c", 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, 209);
break;
case 1:
sprintf(szMesg, "%c %c %c %c %c %c %c %c %c %c %c", 209, 209, 209, 209, 209, 209, 209, 209, 209, 209, (205 + ghost_scene % 4));
break;
case 2:
sprintf(szMesg, "%c %c %c %c %c %c %c %c %c %c %c", 209, 209, 209, 209, 209, 209, 209, 209, 209, (205 + ghost_scene % 4), 209);
break;
case 3:
sprintf(szMesg, "%c %c %c %c %c %c %c %c %c %c %c", 209, 209, 209, 209, 209, 209, 209, 209, (205 + ghost_scene % 4), 209, 209);
break;
case 4:
sprintf(szMesg, "%c %c %c %c %c %c %c %c %c %c %c", 209, 209, 209, 209, 209, 209, 209, (205 + ghost_scene % 4), 209, 209, 209);
break;
case 5:
sprintf(szMesg, "%c %c %c %c %c %c %c %c %c %c %c", 209, 209, 209, 209, 209, 209, 209, (205 + ghost_scene % 4), 209, 209, 209);
break;
case 6:
sprintf(szMesg, "%c %c %c %c %c %c %c %c %c %c %c", 209, 209, 209, 209, 209, 209, (205 + ghost_scene % 4), 209, 209, 209, 209);
break;
case 7:
sprintf(szMesg, "%c %c %c %c %c %c %c %c %c %c %c", 209, 209, 209, 209, (205 + ghost_scene % 4), 209, 209, 209, 209, 209, 209);
break;
case 8:
sprintf(szMesg, "%c %c %c %c %c %c %c %c %c %c %c", 209, 209, 209, (205 + ghost_scene % 4), 209, 209, 209, 209, 209, 209, 209);
break;
case 9:
sprintf(szMesg, "%c %c %c %c %c %c %c %c %c %c %c", 209, 209, (205 + ghost_scene % 4), 209, 209, 209, 209, 209, 209, 209, 209);
break;
case 10:
sprintf(szMesg, "%c %c %c %c %c %c %c %c %c %c %c", 209, 209, (205 + ghost_scene % 4), 209, 209, 209, 209, 209, 209, 209, 209);
break;
case 11:
sprintf(szMesg, "%c %c %c %c %c %c %c %c %c %c %c", 209, 209, 209, (205 + ghost_scene % 4), 209, 209, 209, 209, 209, 209, 209);
break;
case 12:
sprintf(szMesg, "%c %c %c %c %c %c %c %c %c %c %c", 209, 209, 209, 209, (205 + ghost_scene % 4), 209, 209, 209, 209, 209, 209);
break;
case 13:
sprintf(szMesg, "%c %c %c %c %c %c %c %c %c %c %c", 209, 209, 209, (205 + ghost_scene % 4), 209, 209, 209, 209, 209, 209, 209);
break;
case 14:
sprintf(szMesg, "%c %c %c %c %c %c %c %c %c %c %c", 209, 209, 209, (205 + ghost_scene % 4), 209, 209, 209, 209, 209, 209, 209);
break;
case 15:
sprintf(szMesg, "%c %c %c %c %c %c %c %c %c %c %c", 209, 209, 209, 209, (205 + ghost_scene % 4), 209, 209, 209, 209, 209, 209);
break;
case 16:
sprintf(szMesg, "%c %c %c %c %c %c %c %c %c %c %c", 209, 209, 209, (205 + ghost_scene % 4), 209, 209, 209, 209, 209, 209, 209);
break;
case 17:
sprintf(szMesg, "%c %c %c %c %c %c %c %c %c %c %c", 209, 209, (205 + ghost_scene % 4), 209, 209, 209, 209, 209, 209, 209, 209);
break;
case 18:
sprintf(szMesg, "%c %c %c %c %c %c %c %c %c %c %c", 209, (205 + ghost_scene % 4), 209, 209, 209, 209, 209, 209, 209, 209, 209);
break;
case 19:
sprintf(szMesg, "%c %c %c %c %c %c %c %c %c %c %c", (205 + ghost_scene % 4), 209, 209, 209, 209, 209, 209, 209, 209, 209, 209);
break;
default:
break;
}
ghost_scene++;
} else {
ghost_scene = 0;
parola.setTextAlignment(0, PA_CENTER);
return false;
}
}
return true;
}
uint8_t flashing = 0;
bool animazioneTime(enum textEffect_t entra , enum textEffect_t esce , int tempo_display_timer) {
if (millis() - lastTimeAnimation >= 500) //ogni 1 secondo
{
if (flashing == 0) {
//entra
parola.setTextAlignment(0, PA_CENTER);
parola.setTextEffect(0, entra, PA_NO_EFFECT);
getTime(szMesg);
flashing++;
} else if (flashing < tempo_display_time) {
//flashing
parola.setTextEffect(0, PA_PRINT, PA_NO_EFFECT);
parola.setTextAlignment(0, PA_CENTER);
lastTimeAnimation = millis();
getTime(szMesg, flashing % 2==0);
flashing++;
} else if (flashing == tempo_display_time) {
//esce
parola.setTextEffect(0, PA_NO_EFFECT, esce);
getTime(szMesg);
flashing++;
} else {
parola.setTextAlignment(0, PA_LEFT);
flashing = 0;
return false;
}
}
return true;
}
bool animazioneTimer(enum textEffect_t entra , enum textEffect_t esce , int tempo_display_timer) {
if (millis() - lastTimeAnimation >= 500) //every second
{
if (flashing == 0) {
//entra
parola.setTextAlignment(0, PA_CENTER);
parola.setTextEffect(0, entra, PA_NO_EFFECT);
getTimer(szMesg, flashing % 2==0);
flashing++;
} else if (flashing < tempo_display_timer) {
//flashing
parola.setTextEffect(0, PA_PRINT, PA_NO_EFFECT);
parola.setTextAlignment(0, PA_CENTER);
lastTimeAnimation = millis();
getTimer(szMesg, flashing % 2==0);
flashing++;
} else if (flashing == tempo_display_timer) {
//esce
parola.setTextEffect(0, PA_NO_EFFECT, esce);
getTimer(szMesg, flashing % 2==0);
flashing++;
} else {
parola.setTextAlignment(0, PA_LEFT);
flashing = 0;
return false;
}
}
return check_timer_on();
}
void set_message(const char* cmd, int off) {
//DEBUG_PRINTLN(cmd);
String str(cmd);
message = str.substring(off);
}
void set_allert(const char* cmd, int off) {
allertOn = true;
String str(cmd);
allert = str.substring(off);
}
void set_allert(const char* my_allert) {
set_allert(my_allert,0);
}
void unset_allert() {
allertOn = false;
parola.setIntensity(intensity);
}
void set_time(const char* cmd, int off) {
tmElements_t tmSet;
time_t tSet;
tmSet.Year = 1000 * (cmd[off] - '0') + 100 * (cmd[off + 1] - '0') + 10 * (cmd[off + 2] - '0') + cmd[off + 3] - '0' - 1970;
tmSet.Month = 10 * (cmd[off + 5] - '0') + cmd[off + 6] - '0';
tmSet.Day = 10 * (cmd[off + 8] - '0') + cmd[off + 9] - '0';
tmSet.Hour = 10 * (cmd[off + 11] - '0') + cmd[off + 12] - '0';
tmSet.Minute = 10 * (cmd[off + 14] - '0') + cmd[off + 15] - '0';
tmSet.Second = 10 * (cmd[off + 17] - '0') + cmd[off + 18] - '0';
tSet = makeTime(tmSet); //convert to time_t
setTime(tSet); //set the local time
breakTime(now(), tmSet); //convert the current local time back to tmElements_t (to ensure weekday is calculated)
}
void set_timer(const char* cmd, int off) {
timer[0] = millis()/1000;
uint32_t timer_hour = 10 * (cmd[off] - '0') + cmd[off + 1] - '0';
uint32_t timer_min = 10 * (cmd[off + 3] - '0') + cmd[off + 4] - '0';
uint32_t timer_sec = 10 * (cmd[off + 6] - '0') + cmd[off + 7] - '0';
timer[1] = timer_sec + timer_min * 60 + timer_hour * 3600;
}
void displayon_1(const char* cmd, int off) {
PREF_h_m_s_on_1[0] = 10 * (cmd[off] - '0') + cmd[off + 1] - '0' ;
PREF_h_m_s_on_1[1] = 10 * (cmd[off + 3] - '0') + cmd[off + 4] - '0';
PREF_h_m_s_on_1[2] = 10 * (cmd[off + 6] - '0') + cmd[off + 7] - '0';
save("h_on_1",PREF_h_m_s_on_1[0]);
save("m_on_1",PREF_h_m_s_on_1[1]);
save("s_on_1",PREF_h_m_s_on_1[2]);
DEBUG_PRINTLN(cmd);
}
void displayoff_1(const char* cmd, int off) {
PREF_h_m_s_off_1[0] = 10 * (cmd[off] - '0') + cmd[off + 1] - '0' ;
PREF_h_m_s_off_1[1] = 10 * (cmd[off + 3] - '0') + cmd[off + 4] - '0';
PREF_h_m_s_off_1[2] = 10 * (cmd[off + 6] - '0') + cmd[off + 7] - '0';
save("h_off_1",PREF_h_m_s_off_1[0]);
save("m_off_1",PREF_h_m_s_off_1[1]);
save("s_off_1",PREF_h_m_s_off_1[2]);
DEBUG_PRINTLN(cmd);
}
void displayon_2(const char* cmd, int off) {
PREF_h_m_s_on_2[0] = 10 * (cmd[off] - '0') + cmd[off + 1] - '0' ;
PREF_h_m_s_on_2[1] = 10 * (cmd[off + 3] - '0') + cmd[off + 4] - '0';
PREF_h_m_s_on_2[2] = 10 * (cmd[off + 6] - '0') + cmd[off + 7] - '0';
save("h_on_2",PREF_h_m_s_on_2[0]);
save("m_on_2",PREF_h_m_s_on_2[1]);
save("s_on_2",PREF_h_m_s_on_2[2]);
DEBUG_PRINTLN(cmd);
}
void displayoff_2(const char* cmd, int off) {
PREF_h_m_s_off_2[0] = 10 * (cmd[off] - '0') + cmd[off + 1] - '0' ;
PREF_h_m_s_off_2[1] = 10 * (cmd[off + 3] - '0') + cmd[off + 4] - '0';
PREF_h_m_s_off_2[2] = 10 * (cmd[off + 6] - '0') + cmd[off + 7] - '0';
save("h_off_2",PREF_h_m_s_off_2[0]);
save("m_off_2",PREF_h_m_s_off_2[1]);
save("s_off_2",PREF_h_m_s_off_2[2]);
DEBUG_PRINTLN(cmd);
}
void active_autostdby() {
autostdbyActivate = true;
}
void deactive_autostdby() {
autostdbyActivate = false;
}
void set_icon(const char* cmd, int off) {
STATO_SCORRI_PACMAN = -1;
String str(cmd);
icon = str.substring(off);
}
void unset_icon() {
STATO_SCORRI_PACMAN = 0;
}
void set_intensity(const char* cmd, int off) {
int i = atoi(cmd);
intensity = i % 16;
parola.setIntensity(intensity);
}
void set_speed(const char* cmd, int off) {
speed = atoi(cmd);
parola.setSpeed(speed);
}
void set_wifi(const char* cmd, int off) {
int i = atoi(cmd);
}
void reset() {
ESP.restart();
}
void invert() {
parola.setInvert(!parola.getInvert());
}
void on() {
parola.displayShutdown(false);
STATO_GET_DISPLAY_ON = true;
}
void off() {
parola.displayShutdown(true);
STATO_GET_DISPLAY_ON = false;
}
void display_reset() {
off();
//delay(1000);
on();
//P.displayReset();
}
void initParola(boolean conn_left) {
parola.begin(3);
parola.setInvert(false);
parola.setFont(0, myChars);
parola.setFont(1, jF_Custom);
parola.setFont(2, myChars);
setOrientation(conn_left);
parola.setIntensity(intensity);
parola.addChar('^', colonT);
}
void setOrientation(boolean conn_left) {
if(conn_left) {
parola.setZone(0, 1, MAX_DEVICES - 1);
parola.setZone(1, 0 , 0 );
parola.setZone(2, 0, MAX_DEVICES - 1);
parola.setZoneEffect(0, true, PA_FLIP_UD);
parola.setZoneEffect(1, true, PA_FLIP_UD);
parola.setZoneEffect(2, true, PA_FLIP_UD);
parola.setZoneEffect(0, true, PA_FLIP_LR);
parola.setZoneEffect(1, true, PA_FLIP_LR);
parola.setZoneEffect(2, true, PA_FLIP_LR);
setZone();
} else {
parola.setZone(0, 0, MAX_DEVICES - 2);
parola.setZone(1, MAX_DEVICES - 1 , MAX_DEVICES - 1 );
parola.setZone(2, 0, MAX_DEVICES - 1);
parola.setZoneEffect(0, false, PA_FLIP_UD);
parola.setZoneEffect(1, false, PA_FLIP_UD);
parola.setZoneEffect(2, false, PA_FLIP_UD);
parola.setZoneEffect(0, false, PA_FLIP_LR);
parola.setZoneEffect(1, false, PA_FLIP_LR);
parola.setZoneEffect(2, false, PA_FLIP_LR);
setZone();
}
}
void setZone() {
parola.displayZoneText(0, szMesg, PA_CENTER, speed, 0, PA_NO_EFFECT, PA_NO_EFFECT);
parola.displayZoneText(1, szSolo, !flipped()?PA_LEFT:PA_RIGHT, speed, PAUSE_TIME, PA_PRINT, PA_NO_EFFECT);
parola.displayZoneText(2, szMesg, PA_CENTER, speed, PAUSE_TIME, PA_PRINT, PA_NO_EFFECT);
}
boolean flipped() {
return parola.getZoneEffect(0, PA_FLIP_LR);
}
enum textEffect_t pa_scroll_left () {
if(flipped()) return PA_SCROLL_RIGHT;
return PA_SCROLL_LEFT;
}
enum textEffect_t pa_scroll_right () {
if(flipped()) return PA_SCROLL_LEFT;
return PA_SCROLL_RIGHT;
}
enum textEffect_t pa_scroll_up () {
if(flipped()) return PA_SCROLL_DOWN;
return PA_SCROLL_UP;
}
enum textEffect_t pa_scroll_down () {
if(flipped()) return PA_SCROLL_UP;
return PA_SCROLL_DOWN;
}
void disegna_barra(int number_of_lines) {
char line = '|';
if(number_of_lines > CONST_DISPLAY_MAX_LINES) number_of_lines = CONST_DISPLAY_MAX_LINES;
VAR_BARRA_STRING[0] = number_of_lines;
}
Comments