/* 
Control de la intensitat de un led.
Comunicació servidor-client per WebSocket
NodeMCU com a servidor en mode AccessPoint i el navegador com client
*/

//llibreries
#include <ESP8266WiFi.h>
//llibreria WebSockets by Marcus Sattler
#include <WebSocketsServer.h>
#include <ESP8266WebServer.h>

#define pinLed  D1          

const char* ssid = "NodeMcuAp";
const char* password = "12345678";
//guardem la pagina web en la memoria flash del ESP8266
static const char PROGMEM INDEX[] = R"( 
<!DOCTYPE html>
<html>
  <head>
      <meta charset=utf-8>
      <title> WebSocket ESP8266-REGULACIÓ DE INTENSITAT DE LED </title>
  </head>
  <body>
    <h1> WebSocket ESP8266-REGULACIÓ DE INTENSITAT DE LED </h1> 
    <p> Servidor (ESP8266)<--WebSocket -->Client (navegador)</p>
    <input type='range' min='0' max='255' value='127' id='entrada' oninput='getEntrada()'>
    <p id='sortida'></p>
    <script>
       var x; 
       var connection = new WebSocket('ws://'+location.hostname+':81/', ['arduino']);
       connection.onopen = function () {
         connection.send('Connectat  -  ' + new Date()); 
         getEntrada();
       }
       connection.onmessage = function (event) {
         console.log('Servidor (rep): ', event.data);
       }
       connection.onerror = function (error) {
         console.log('WebSocket Error!!!', error);
       }
       function getEntrada() {
         x = document.getElementById('entrada').value;
         document.getElementById('sortida').innerHTML = 'Intensitat (0-255): ' + x;
         enviarValor();
       }
       function enviarValor(){
         console.log('Client (envia): ' + x);
         connection.send(x);
       }
    </script>
  </body>
</html>
)";
//inicialitzem el servidor WiFi
ESP8266WebServer server (80);
//inicialitzel el webSocket per el servidor, port 81
WebSocketsServer webSocket = WebSocketsServer(81);

///// métode que tracte el diferents evens en el socket/////////
///// conectar, desconnectar, intercamvi de missatges///////  
void webSocketEvent(uint8_t num, WStype_t type, uint8_t * payload, size_t length) {
  switch(type) {
    case WStype_CONNECTED: {
      IPAddress ip = webSocket.remoteIP(num);
      Serial.printf("[%u] Connectat a la URL: %d.%d.%d.%d - %s\n", num, ip[0], ip[1], ip[2], ip[3], payload);
      }
      break;

    case WStype_DISCONNECTED:
      Serial.printf("[%u] Desconnectat!\n", num);
      break;

    case WStype_TEXT:
      Serial.printf("Número conexió: %u -Caràcters rebuts: %s\n  ", num, payload);
      //Retorna al client el missatge rebut. 
      webSocket.sendTXT(num, payload);
      //Conversió dels caràcters rebuts a cadena de texte     
      String strCadena = (char*)payload;
      //Conversió de String a enter
      int intensitat = strCadena.toInt();                            
      analogWrite(pinLed, intensitat);
      break;
  }
}

void setup() {
  Serial.begin(115200);
  Serial.println();

  //configurem el AccessPoint
  WiFi.softAP(ssid, password);
  IPAddress myIP = WiFi.softAPIP(); 
  //per defecte la IP del servidor AP es 192.168.4.1
  Serial.print("IP del AccessPoint: ");
  Serial.println(myIP);
  
   // inici del servidor WebSocket
  webSocket.begin();
  webSocket.onEvent(webSocketEvent);

  // gestiona la web, el index
  server.on("/", []() {
      server.send_P(200, "text/html", INDEX);
  });

  server.begin();
  Serial.println("WebServer iniciat...");

  pinMode(pinLed, OUTPUT); 
  digitalWrite(pinLed, 0); 

  analogWriteRange(255);
}

void loop() {
    webSocket.loop();
    server.handleClient();
}
