HobbyElectro

Petrescu Cristian . Un produs Blogger.

sâmbătă, 20 februarie 2016

Triplu stecher controlat prin internet (Partea I)

11 comentarii | Read more...

Pentru inceput...

     In articolul trecut am prezentat o modalitate simpla de a controla 4 leduri cu ajutorul unei interfete web, folosind numai html si css. 
In cele urmeaza voi ridica un pic stacheta si voi adauga proiectului cateva elemente grafice, precum si posibilitatea de a trimite clientului, in  functie de calitatea  acestuia (admin sau guest),  pagini html diferite. 

     Proiectul propus va controla 3 prize alimentate la 220V. Fiecare din cele trei prize va primi un nume si nu va putea fi controlata decat de clientul "logat" ca  administrator al sistemului. Oaspetii vor avea dreaptul de a vizualiza  starea sistemului, fara insa de a putea interactiona in vreun fel cu acesta.

     Asadar sa incepem... Ce a iesit se poate vedea in filmuletul de mai jos:



Elemente grafice...

     Am gasit ca unic mod de a trimite clientului, in interiorul paginii html fisiere cu imagini, stocarea acestora pe un server extern, asa ca am inregistrat un domeniu (gratuit) pe "www.hostinger.ro". Dupa inregistrare am beneficiat de spatiu de stocare dar... si de un server html complet. Ideea mea a fost ca toate resursele:
  • cod JavaScript;
  • stiluri de formatare CSS;
  • imagini (.png, .jpg)
sa fie accesate dintr-un mediu extern. Acest fapt aduce cu sine nenumarate avantaje din care voi enumera doar cateva:
  • NodeMcu trimite numai cod html, din acest motiv viteza de transfer a datelor catre client este mult mai mare;
  • in cazul in care codul JavaScript necesita ajustari, acestea pot fi facute rapid nefiind necesara reincarcrea intregii pagini in memoria controller-ului (timp foarte mare de incarcare);
  • la fel in cazul stilurilor de formatare;
  • se pot trimite imagini clientului.
  • ORICINE POATE FOLOSI RESURSELE AFLATE PE SERVERUL WEB.
Functionare...

     In NodeMcu sunt incarcate trei pagini - fiecare cu fiserul JavaScript aferent (incarcat pe serverul extern) :
  • index.html - pagina de start;
  • guest.html - pagina ce va fi afisata doar "oaspetilor";
  • admin.thml - pagina ce va fi afisata administratorului;
Index.html:




     Dupa ce a fost introdusa in browser adresa IP a controller-ului va fi afisata pagina de mai sus. Daca utilizatorul cunoaste codul de acces (stocat in memoria NodeMcu) se poate "loga" ca admin. In continuare vor fi afisate campurile prin care se cer numele aparatelor conectate la prize. Apsand butonul "Submit"...

Admin.html:


     Browser-ul va afisa pagina de mai sus. Dupa cum se observa fiecare priza a capatat o reprezentare grafica (nu am talente artistice... am facut si eu cum m-am priceput). In cazul de fata nefiind cunoscuta starea sistemului poza care descrie starea sistemului este reprezentata cu un semn de intrebare. Apasand butonul "GET STATUS" va fi afista pagina urmatoare:


     Asadar, in cazul de fata toate prizele sunt oprite. In caseta text "LOG CONSOLE"  sunt afisate datele sistemului: comenzile date, numele dispozitivelor conectate etc. Daca dorim sa comandam o priza nu trebuie decat sa face un simplu click pe switch-ul aferent acesteia:


     Se observa ca imaginea care descrie starea prizei se schimba, iar consola inregistreaza activitatea.

   Sa vedem acum ce se intampla daca un oaspete doreste sa utilizeze sistemul. 


Guest.html:




Apasand butonul "Login as guest" va fi afisata o pagina identica cu cea a admin-ului. Dupa apasarea butonului "GET STATUS":


     Daca "oaspetele" doreste sa porneasca/opreasca una din cele 3 prize, consola va afisa urmatorul mesaj:




Programarea...

      NodeMcu

     Codul scris pentru NodeMcu este prezentat in caseta de mai jos. Fata de programul din articolul anterior au aparut cateva modificari, insa consider ca nu este nevoie sa fie explicate in detaliu. Schita, si fisierele html  pot fi descarcate de aici.

Dupa descarcare fisierul .zip va fi dezarhivat  in folderul "Sketchbook". Pentru a incarca fisierele html in memoria controller-ului se va utiliza metoda descrisa in articolul precedent.

Codul JavaScript, si imaginile sunt preluate automat de pe domeniul inregistrat de catre mine.


/////////////////////////////////////////////////////////////////////////////
//LOCAL NETWORK  SERVER WITH NODEMCU                                      //
//PETRESCU CRISTIAN                                                      //
//////////////////////////////////////////////////////////////////////////
//file system reference:
//http://arduino.esp8266.com/versions/1.6.5-1160-gef26c5f/doc/reference.html#file-system-object-spiffs
//html and java sript reference:
//http://www.w3schools.com/
//check my blog :www.hobbyelectro.blogspot.ro

#include "FS.h"
#include <ESP8266WiFi.h>
int socketState[3] = {0, 0, 0};
int sk[4] = {D0, D1, D2};
String buff;
String dev = "SK1/SK2/SK3/z";
String pwd="test1234";// the password for logging as administrator
String stateOn = "on/";
String stateOff = "off/";
const char* ssid = "********";//your ssid
const char* password = "*******";//your wifi network password
WiFiServer server(80);


////////////////////////////////////////////////////////////////////////////
//this function builds the string which will be sent to the client       //
//it will transform to a string the array which holds the states of     //
//the plugs.                                                           //
////////////////////////////////////////////////////////////////////////

String responseBuilder() {
  String buff = "";
  for (int i = 0; i < 3; i++) {
    buff.concat(String(socketState[i]));//add state of led to the response string
    buff.concat("/");
  }
  return buff;
}


////////////////////////////////////////////////////////////////////////////
//send the html page to client                                           //
//////////////////////////////////////////////////////////////////////////
void printPage(WiFiClient k, String page) {
  File f = SPIFFS.open(page, "r");//open html page for reading
  if (!f) {
    Serial.println("file open failed");// check if file exists
    return;
  }
  buff = f.readString();// read all file at once
  f.close();// close the file
  // send data to browser in 2 packets of 2KB each
  k.print(buff.substring(0, 2000));//send first 2000chars to browser
  k.print(buff.substring(2000));//send second 2000chars to browser
  //k.print(buff.substring(4000));// send the rest of file to browser
}
////////////////////////////////////////////////////////////////////////////
//check if client wants to read the states of sk or want to change them //
//////////////////////////////////////////////////////////////////////////
void checkRequest(WiFiClient k, String request) {// change the states of the plugs
  //check if request it's a command
  if (request.indexOf("data") != -1) {
    request.remove(0, request.lastIndexOf('/') + 1);
    //Serial.println(request);
    int i = request.toInt();
    if (socketState[i] == 0) {
      socketState[i] = 1;
      digitalWrite(sk[i], socketState[i]);
      //Serial.println(String(responseBuilder()+String(i)+"/on/z"));
      k.println(String(responseBuilder() + String(i) + "/on/z")); // send response to client
      return;
    }
    if (socketState[i] == 1) {
      socketState[i] = 0;
      digitalWrite(sk[i], socketState[i]);
      //Serial.println(String(responseBuilder()+String(i)+"/off/z"));
      k.println(String(responseBuilder() + String(i) + "/off/z")); // send response to client
      return;
    }
  }

  if (request.indexOf("status") != -1) {//check if client wants to read the state of sk
    //Serial.println(String(responseBuilder()+dev));
    k.println(String(responseBuilder() + dev)); // send response to client
    return;
  }
}


void response(WiFiClient k) {
  k.println("HTTP/1.1 200 OK");
  k.println("Content-Type: text/html");
  k.println(""); //  do not forget this one
  String request = k.readStringUntil('H');//read request
  //Serial.println(request);
  //check if request

  if(request.indexOf("guest") != -1){// check if the clinets wants to log in as guest
    printPage(k,"/guest.html");
    return;
    }


  if(request.indexOf("pwd")!=-1){// check if client wants to log in as admin
    request.remove(0, 5);
    int j=request.indexOf("/");
    //Serial.println(request);
    //Serial.println(request.length());
    String str=request.substring(0,j);
    //Serial.println(str);
    if(str==pwd){//check if password sent by client matches the passwor defined
      Serial.println(pwd);
      k.println("ok");
      }
    return;
    }

  if(request.indexOf("ok")!=-1){//the client is logged as admin
    request.remove(0, 5);
    //Serial.println(request);
    dev=request.substring(0,request.lastIndexOf("/"));// read the names of the devices
    //Serial.println(dev);
    if(dev.indexOf("%20")!=-1){//repalce "%20" with space
        dev.replace("%20"," ");
      }
    //Serial.println(dev);
    printPage(k,"/admin.html");// send the admin.html page file
    return;
    }
  if(request.indexOf("status")!=-1||request.indexOf("data")!=-1){//check if client wants to read or change states
    request.remove(0, 5);
    checkRequest(k, request);
    return;
    }
    printPage(k,"/index.html");// send the index.html file
}

void setup() {
  SPIFFS.begin();//start spiffs (spi file system)
  Serial.begin(115200);// start serial session
  Serial.println();
  int i;
  // set led pins as output
  for (i = 0; i < 3; i++) {
    pinMode(sk[i], OUTPUT);
    digitalWrite(sk[i], 0);
  }
  Serial.println();
  Serial.println();
  Serial.print("Connecting to ");
  Serial.println(ssid);
  // Connect to WiFi network
  WiFi.begin(ssid, password);
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }
  Serial.println("");
  Serial.println("WiFi connected");

  // Start the server
  server.begin();
  Serial.println("Server started");

  // Print the IP address
  Serial.print("Use this URL to connect: ");
  Serial.print("http://");
  Serial.print(WiFi.localIP());
  Serial.println("/");
}

void loop() {
  // Check if a client has connected
  WiFiClient client = server.available();
  if (!client) {
    return;
  }
  //analyze data received from client
  response(client);
  client.flush();
  delay(1);
  //Serial.println("Client disonnected");
  //Serial.println("");
}


In articolul urmator voi incerca sa realizez si partea practica.

Sa auzim de bine !`


Totalul afișărilor de pagină

Despre

Blog cu si despre electronica !