Lab_interaccio/2022/Jardi_Mecanic/Jardi_Mecanic.ino
2025-02-25 21:29:42 +01:00

503 lines
16 KiB
C++

#include "ArduinoJson.h"
#include <WiFi.h>
#include <WiFiClient.h>
#include <WebServer.h>
#include <ESPmDNS.h>
#include <EEPROM.h>
#include <HTTPUpdateServer.h>
#include <HTTPClient.h>
#include <Wire.h>
#include "PCA9634.h"
IPAddress staticIP(192, 168, 8, 109);
IPAddress gateway(192, 168, 8, 1);
IPAddress subnet(255, 255, 255, 0);
IPAddress dns(192, 168, 8, 1);
const int id_temp = 10; //ID del dispositivo si no lo tiene en memoria
int id = 0;
#define version 1.06
#define TIME 60*1
//#define TIME 1
#define json_decrypt true
#define debug true
#define NUM_FLORS 5
const char * host = "esp32";
//const char * ssid = "HANGAR_naus";
//const char * password = "nDfEXDwRr4Py4fvRdfMU";
const char * ssid = "Jardi_Mecanic";
const char * password = "f3RR0LU4R";
//const char * ssid = "Hello_pepe";
//const char * password = "labinteractius";
byte gamma_led[] = {
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2,
2, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 5, 5, 5,
5, 6, 6, 6, 6, 7, 7, 7, 7, 8, 8, 8, 9, 9, 9, 10,
10, 10, 11, 11, 11, 12, 12, 13, 13, 13, 14, 14, 15, 15, 16, 16,
17, 17, 18, 18, 19, 19, 20, 20, 21, 21, 22, 22, 23, 24, 24, 25,
25, 26, 27, 27, 28, 29, 29, 30, 31, 32, 32, 33, 34, 35, 35, 36,
37, 38, 39, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 50,
51, 52, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 66, 67, 68,
69, 70, 72, 73, 74, 75, 77, 78, 79, 81, 82, 83, 85, 86, 87, 89,
90, 92, 93, 95, 96, 98, 99,101,102,104,105,107,109,110,112,114,
115,117,119,120,122,124,126,127,129,131,133,135,137,138,140,142,
144,146,148,150,152,154,156,158,160,162,164,167,169,171,173,175,
177,180,182,184,186,189,191,193,196,198,200,203,205,208,210,213,
215,218,220,223,225,228,231,233,236,239,241,244,247,249,252,255
};
WebServer httpServer(80);
HTTPUpdateServer httpUpdater;
class Color
{
public:
uint8_t animation=0;
uint8_t red=0;
uint8_t green=0;
uint8_t blue=0;
uint8_t warm=0;
uint8_t cold=0;
uint32_t all=0;
void separa(String value) // Constructor
{
all =(uint32_t) strtol( &value[7], NULL, 16);
warm = all>>8;
cold = all;
value[7] = 0x00;
all =(uint32_t) strtol( &value[1], NULL, 16);
red = all>>16;
green = all>>8;
blue = all;
}
} ;
Color color[8];
#define BLUE 3
#define COLD 4
#define WARM 5
#define GREEN 7
#define RED 6
//A6 A5 A4 A3 A2 A1 A0
// 1 1 0 1 0 0 0
// 6 8
PCA9634 foco1( 0x68 );//0x68
PCA9634 foco2( 0x69 );//0x6A
PCA9634 foco3( 0x6A );//0x6B
PCA9634 foco4( 0x6B );//0x69
PCA9634 foco5( 0x6C );
PCA9634 foco6( 0x6D );
PCA9634 foco7( 0x6E );
PCA9634 foco8( 0x6F );
void test_foco()
{
for(int i=3; i<8; i++)
{
foco1.set_brightness(i, 255);
delay(10);
foco2.set_brightness(i, 255);
delay(10);
foco3.set_brightness(i, 255);
delay(10);
foco4.set_brightness(i, 255);
delay(1000);
foco1.set_brightness(i, 0);
delay(10);
foco2.set_brightness(i, 0);
delay(10);
foco3.set_brightness(i, 0);
delay(10);
foco4.set_brightness(i, 0);
delay(10);
}
}
TaskHandle_t TaskRESET;
unsigned long time_protection = millis();
void setup() {
xTaskCreatePinnedToCore(Task_RESET,"TaskRESET",10000,NULL,0,&TaskRESET,1);
time_protection = millis();
EEPROM.begin(10);
Serial.begin(115200);
Wire.begin();
Wire.setClock(100000);
foco1.begin( );
foco2.begin( );
foco3.begin( );
foco4.begin( );
foco5.begin( );
foco6.begin( );
foco7.begin( );
foco8.begin( );
all_off();
delay(100);
// if (EEPROM.read(0)>100)
// {
// EEPROM.write(0, id_temp);
// EEPROM.commit();
// }
id = EEPROM.read(0);
Serial.print("id:");
Serial.println(id);
for(int i=0; i<NUM_FLORS; i++) lamp_color(i, 0, 0, 255, 0, 0);
WiFi.config(staticIP, gateway, subnet, dns, dns);
WiFi.mode(WIFI_AP_STA);
WiFi.begin(ssid, password);
while (WiFi.waitForConnectResult() != WL_CONNECTED) {
WiFi.begin(ssid, password);
Serial.println("WiFi failed, retrying.");
for(int i=0; i<NUM_FLORS; i++) lamp_color(i, 255, 0, 0, 0, 0);
}
MDNS.begin(host);
if (MDNS.begin("esp32")) {
Serial.println("mDNS responder started");
}
httpUpdater.setup(&httpServer);
httpServer.begin();
MDNS.addService("http", "tcp", 80);
Serial.printf("HTTPUpdateServer ready! Open http://%s.local/update in your browser\n", host);
Serial.println("");
Serial.print("Connected to ");
Serial.println(ssid);
Serial.print("IP address: ");
Serial.println(WiFi.localIP());
for(int i=0; i<NUM_FLORS; i++) lamp_color(i, 0, 255, 0, 0, 0);
vTaskDelete( TaskRESET );
}
void Task_RESET( void * pvParameters ){
for(;;)
{
if ((millis()-time_protection)>=(30*1000))
{
Serial.println("Tiempo de espera superado, dispositivo reseteado.");
ESP.restart();
}
}
vTaskDelete( TaskRESET );
}
unsigned long time_json = millis();
bool retry_json = true;
void request_json()
{
xTaskCreatePinnedToCore(Task_RESET,"TaskRESET",10000,NULL,0,&TaskRESET,1);
time_protection = millis();
retry_json = true;
while(retry_json){
if ((WiFi.waitForConnectResult() == WL_CONNECTED)) { //Check the current connection status
HTTPClient http;
http.begin("http://www.rem.jardinmecanico.com/api/modules/" +(String)id + "/?format=json");
int httpCode = http.GET(); //Make the request
if (httpCode > 0) { //Check for the returning code
if (httpCode==200)
{
String payload = http.getString();
DynamicJsonDocument root(700);
// Parse JSON object
DeserializationError error = deserializeJson(root, payload);
if (error) { //Check for errors in parsing
Serial.print(F("deserializeJson() failed: "));
Serial.println(error.c_str());
}
else
{
// Extract values
int id = root["idmod"];
String name = root["title"];
String time = root["time_zone"];
String time_ini = root["event"][0]["pub_date"];
String title = root["scene"][0]["title"];
for(int i=0; i<8; i++)
{
color[i].animation = root["scene"][0]["animation"];
color[i].separa(root["scene"][0]["color" +(String)(i+1)]);
}
#if debug
Serial.print("id:");
Serial.println(id);
Serial.print("title:");
Serial.println(name);
Serial.print("tiempo_actual:");
Serial.println(time);
Serial.print("tiempo_inico:");
Serial.println(time_ini);
Serial.print("title:");
Serial.println(title);
for(int i=0; i<8; i++)
{
Serial.print("animation" + (String)i + ":");
Serial.println(color[i].animation);
Serial.print("color" + (String)i + ":");
Serial.print(color[i].red, HEX);
Serial.print(",");
Serial.print(color[i].green, HEX);
Serial.print(",");
Serial.print(color[i].blue, HEX);
Serial.print(",");
Serial.print(color[i].warm, HEX);
Serial.print(",");
Serial.println(color[i].cold, HEX);
}
#endif
retry_json = false;
time_json = millis();
}
}
#if !json_decrypt
Serial.println(httpCode);
Serial.println(payload);
#endif
}
else {
Serial.println("Error on HTTP request");
retry_json = true;
}
http.end(); //Free the resources
}
else
{
WiFi.begin(ssid, password);
while (WiFi.waitForConnectResult() != WL_CONNECTED) {
WiFi.begin(ssid, password);
Serial.println("WiFi failed, retrying.");
}
retry_json = true;
}
}
vTaskDelete( TaskRESET );
}
void loop() {
httpServer.handleClient(); //Servidor para programar inalambricamente
if (((millis()-time_json)>(TIME*1000))||(retry_json)) request_json();
switch (color[0].animation) {
case 0:
all_off();
break;
case 1:
static_mode();
break;
case 2:
snake_mode_in();
break;
case 3:
snake_mode_out();
break;
case 4:
random_mode();
break;
case 5:
snake_mode_in_out();
break;
case 6:
beat();
break;
default:
//all_off();
break;
}
delay(1000);
}
void lamp_color(int lamp, byte red, byte green, byte blue, byte cold, byte warm)
{
switch (lamp) {
case 0:
foco1.set_all_brightness(0, 0, 0, gamma_led[blue], gamma_led[cold], gamma_led[warm], gamma_led[red], gamma_led[green]);
break;
case 1:
foco2.set_all_brightness(0, 0, 0, gamma_led[blue], gamma_led[cold], gamma_led[warm], gamma_led[red], gamma_led[green]);
break;
case 2:
foco3.set_all_brightness(0, 0, 0, gamma_led[blue], gamma_led[cold], gamma_led[warm], gamma_led[red], gamma_led[green]);
break;
case 3:
foco4.set_all_brightness(0, 0, 0, gamma_led[blue], gamma_led[cold], gamma_led[warm], gamma_led[red], gamma_led[green]);
break;
case 4:
foco5.set_all_brightness(0, 0, 0, gamma_led[blue], gamma_led[cold], gamma_led[warm], gamma_led[red], gamma_led[green]);
break;
case 5:
foco6.set_all_brightness(0, 0, 0, gamma_led[blue], gamma_led[cold], gamma_led[warm], gamma_led[red], gamma_led[green]);
break;
case 6:
foco7.set_all_brightness(0, 0, 0, gamma_led[blue], gamma_led[cold], gamma_led[warm], gamma_led[red], gamma_led[green]);
break;
case 7:
foco8.set_all_brightness(0, 0, 0, gamma_led[blue], gamma_led[cold], gamma_led[warm], gamma_led[red], gamma_led[green]);
break;
default:
// statements
break;
}
delay(1);
}
int animation = 0;
void all_off()
{
Serial.println("all off");
for(int i=0; i<NUM_FLORS; i++) lamp_color(i, 0, 0, 0, 0, 0);
animation = 0;
}
unsigned long time_refresh = millis();
void static_mode()
{
Serial.println("Static mode ON");
if ((millis()-time_refresh)>1000)
{
for(int i=0; i<NUM_FLORS; i++) lamp_color(i, color[i].red, color[i].green, color[i].blue, color[i].cold, color[i].warm);
time_refresh = millis();
}
animation = 1;
}
void snake_mode_in()
{
Serial.println("Snake mode in");
for(int i=0; i<NUM_FLORS; i++) lamp_color(i, color[i].red/2, color[i].green/2, color[i].blue/2, color[i].cold/2, color[i].warm/2);
for(int i=0; i<NUM_FLORS; i++)
{
lamp_color(i, color[i].red, color[i].green, color[i].blue, color[i].cold, color[i].warm);
delay(5000);
}
animation = 2;
}
void snake_mode_out()
{
Serial.println("Snake mode Out");
for(int i=0; i<NUM_FLORS; i++) lamp_color(i, color[i].red/2, color[i].green/2, color[i].blue/2, color[i].cold/2, color[i].warm/2);
for(int i=(NUM_FLORS-1); i>=0; i--)
{
lamp_color(i, color[i].red, color[i].green, color[i].blue, color[i].cold, color[i].warm);
delay(5000);
}
animation = 3;
}
void random_mode()
{
Serial.print("Random mode ON ");
if (animation!=4) for(int i=0; i<NUM_FLORS; i++) lamp_color(i, color[i].red/2, color[i].green/2, color[i].blue/2, color[i].cold/2, color[i].warm/2);
int i = random(0,(NUM_FLORS-1));
Serial.print(i);
lamp_color(i, color[i].red, color[i].green, color[i].blue, color[i].cold, color[i].warm);
delay(5000);
i = random(0,(NUM_FLORS-1));
Serial.println(" " + (String)i);
lamp_color(i, color[i].red/2, color[i].green/2, color[i].blue/2, color[i].cold/2, color[i].warm/2);
animation = 4;
}
void snake_mode_in_out()
{
Serial.println("Snake mode in-out");
for(int i=0; i<NUM_FLORS; i++) lamp_color(i, color[i].red/2, color[i].green/2, color[i].blue/2, color[i].cold/2, color[i].warm/2);
for(int i=0; i<NUM_FLORS; i++)
{
lamp_color(i, color[i].red, color[i].green, color[i].blue, color[i].cold, color[i].warm);
delay(5000);
}
for(int i=(NUM_FLORS-1); i>=0; i--)
{
lamp_color(i, color[i].red/2, color[i].green/2, color[i].blue/2, color[i].cold/2, color[i].warm/2);
delay(5000);
}
animation = 5;
}
void beat()
{
uint8_t colors[5] = {color[0].red, color[0].green, color[0].blue, color[0].cold, color[0].warm};
float MAX = (float)getMax(colors);
float inc_colors[5] = {(float)color[0].red/MAX, (float)color[0].green/MAX, (float)color[0].blue/MAX, (float)color[0].cold/MAX, (float)color[0].warm/MAX};
float colors_act[5] = {0, 0, 0, 0, 0};
Serial.println("Beat mode");
for(int k=0; k<MAX; k++)
{
Serial.println(k);
for(int i=0; i<5; i++) colors_act[i]+=inc_colors[i];
for(int i=0; i<NUM_FLORS; i++)
{
// for(int j=0; j<5; j++) {
// Serial.print((uint8_t)colors_act[j], HEX);
// Serial.print(" ");
// }
// Serial.println();
lamp_color(i, (uint8_t)colors_act[0], (uint8_t)colors_act[1], (uint8_t)colors_act[2], (uint8_t)colors_act[3], (uint8_t)colors_act[4]);
}
//delay(1);
}
for(int k=MAX; k>0; k--)
{
Serial.println(k);
for(int i=0; i<5; i++) colors_act[i]-=inc_colors[i];
for(int i=0; i<NUM_FLORS; i++)
{
// for(int j=0; j<5; j++) {
// Serial.print((uint8_t)colors_act[j], HEX);
// Serial.print(" ");
// }
// Serial.println();
lamp_color(i, (uint8_t)colors_act[0], (uint8_t)colors_act[1], (uint8_t)colors_act[2], (uint8_t)colors_act[3], (uint8_t)colors_act[4]);
}
//delay(1);
}
animation = 6;
}
uint8_t getMax(uint8_t *myMeasurements)
{
byte maxIndex = 0;
uint8_t maxMeasurements = sizeof(myMeasurements);
int maxValue = myMeasurements[maxIndex];
for(byte i = 1; i < maxMeasurements; i++)
{
if(myMeasurements[i] > maxValue) {
maxValue = myMeasurements[i];
maxIndex = i;
}
}
return maxValue;
}
void doConcat(const char *a, const char *b, char *out) {
strcpy(out, a);
strcat(out, b);
}