//#include <Sensirion.h>

#include <ESP8266WiFi.h>
#include <WiFiClient.h>
#include <SHT1x.h>
#include <PubSubClient.h>
#include <Wire.h>  // Only needed for Arduino 1.6.5 and earlier
#include "SSD1306.h" // alias for `#include "SSD1306Wire.h"`

// jfs NodeMCU 1.0
// Display

SSD1306  display(0x3c, D6, D5);
// IC
char output = 0;
char IC = 0x20;
byte i = 0;
byte ALTWERT;
byte WERT=0;

// Timing
unsigned long readTime;
unsigned long pubTime;
// Data
float temp_c;
float humidity;
char buffer[10];
String line0;
String line1;
String line2;



// Specify data and clock connections and instantiate SHT1x object
#define dataPin  D3
#define clockPin D4
SHT1x sht1x(dataPin, clockPin);
//#define SLEEP_DELAY_IN_SECONDS  300
const char* host = "192.168.2.71";
const char* ssid = "pipanet";
const char* password = "passatvr6";
WiFiClient net;
PubSubClient mqtt(net);

const int mxSize=4;
String ssids[mxSize] ={"GAST","pipanet","FRITZ!Box Gastzugang","WLAN-DE8245"};
String ssidp[mxSize] = {"passatvr6","passatvr6","praxis123","4955065570896956"};
boolean conok =false;
String netid;
void netfound(int i){
     display.clear();
     display.setColor(BLACK);
     display.fillRect(0, 0, 128, 10);
     display.setColor(WHITE);
     display.drawString(0,0,String(i));
     display.drawString(20,0,"networks found");
     display.display(); 
}
boolean init_wifi(){
    boolean ok = false;
    WiFi.mode(WIFI_STA);
    WiFi.disconnect();
    delay(100);
    int n = WiFi.scanNetworks();
    Serial.println("scan done");
    if (n == 0) {
        Serial.println("no networks found");
        netfound(0);
    } else {
        Serial.print(n);
        Serial.println(" networks found");
        netfound(n);        
        for (int i = 0; i < n; ++i) {
            for (int p=0;p<mxSize;p++){
              if (WiFi.SSID(i).equals(ssids[p])){
                String pp = ssidp[p];
                String ss = WiFi.SSID(i);
                WiFi.begin(ss.c_str(), pp.c_str());
                netid = ss;
                i=n;
                ok = true;
              }
            }
            delay(10);
        }
    }     
    return ok;
}



void connect();

void callback(char* topic, byte* payload, unsigned int length) {
  Serial.print("Message arrived [");
  Serial.print(topic);
  Serial.print("] ");
  line0=topic;
  // welches Realis ist betroffen
  i=0x05;
  if (line0.endsWith("r1")) {
    i=0x00;
  }
  if (line0.endsWith("r2")) {
    i=0x01;
  }  
   if (line0.endsWith("r3")) {
    i=0x02;
  }
   if (line0.endsWith("r4")) {
    i=0x03;
  }
   if (line0.endsWith("r5")) {
    i=0x04;
  }
  // an oder aus
  String s;
  boolean ok =false;
  int inByte1 = payload[0];
  int inByte2 = payload[1];
  if ((inByte1 == 'o') && (inByte2 == 'n'))
  {
     Serial.print(i);
    Serial.println(" on");
    ok = true;
    s = "on";
    bitSet(output,i);
    Wire.beginTransmission(IC);
    Wire.write(~output);
    Wire.endTransmission();
  }
  if ((inByte1 == 'o') && (inByte2 == 'f'))
  {
    Serial.print(i);
    Serial.println(" of");
    ok = true;
    s= "off";
    bitClear(output,i);
    Wire.beginTransmission(IC);
    Wire.write(~output);
    Wire.endTransmission();
  }
  if (ok == false){
    Serial.println("Error");
    s = "Error";
  }
 
  
  line2 = topic;
  line2 = line2 + s;
}

void setup() {
  String s = "Hi There";
  Serial.begin(115200);
  delay(100);
   display.init();
   display.clear();
   display.flipScreenVertically();
   display.setFont(ArialMT_Plain_10);
   display.setTextAlignment(TEXT_ALIGN_LEFT); 
  
  display.drawString(0,0,"Booting...");
  display.display();
  Serial.println();
  Serial.println("Booting...");

  //WiFi.mode(WIFI_AP_STA);
  //WiFi.begin(ssid, password);

   while (!init_wifi()){
    delay(200);  
  }
  display.drawString(0, 10, "Connecting to WiFi...");
  display.display();
  while (WiFi.status() != WL_CONNECTED) {
      delay(500);
      Serial.print(".");
  }
  display.drawString(0, 20, "\nWiFi connected, IP address: "); 
  display.drawString(0, 30, WiFi.localIP().toString());
  display.display();
  
  mqtt.setServer(host,1883);
  mqtt.setCallback(callback);
  connect();
  
  readTime = 0;
  pubTime = 0;
  //strcpy(line1,s.c_str());
  long rssi = WiFi.RSSI();
  line0 = WiFi.localIP().toString();
  line0 = line0 + " "+String(rssi);
  Serial.println(line0);
  //relais
  Wire.begin(D6,D5);
  Wire.beginTransmission(IC);   // Start Übertragung zum PCF8574
  Wire.write(~output);                      // Alle Bits sind Eingänge
  Wire.endTransmission();  
}

void loop() {
  mqtt.loop();
 
  if (!mqtt.connected()) {
    connect();    
  }
  if(millis() > readTime+500){
    readTemp();
  }
  if(millis() > pubTime+1000){
    pub_Temp();
  }
}

void disp_Temp(){
  String s;
  long rssi = WiFi.RSSI();
  line0 = WiFi.localIP().toString();
  line0 = line0 + "  "+String(rssi)+" db";
  display.clear();
  display.setFont(ArialMT_Plain_10);
  display.drawString(0,0,line0);
  line1=String(temp_c)+" C ";
  s = String(humidity);
  s = s + " %";
  line1=line1 +s ;
  display.setFont(ArialMT_Plain_10);
  display.drawString(0,18,line1);
  display.drawString(0,30,line2);
  display.display();
}


void pub_Temp(){
 pubTime = millis(); 
 mqtt.publish("/Handy/temp", buffer);
 dtostrf(humidity, 6, 2, buffer);
 mqtt.publish("/Handy/humidity", buffer);
    Serial.print("Sending... ");
    Serial.print("Temp: ");
    Serial.print(String(temp_c));
    Serial.print(" Humidity: ");
    Serial.print(String(humidity));  
 long rssi = WiFi.RSSI();
 String s = String(rssi);
  Serial.print(" RSSI: ");
    Serial.print(s);   
 s.toCharArray(buffer,10);
 mqtt.publish("/Handy/rssi", buffer);
 netid.toCharArray(buffer,10);
 mqtt.publish("/Handy/ssid", buffer);
}

void readTemp(){
 readTime = millis(); 
 temp_c = sht1x.readTemperatureC();
 humidity = sht1x.readHumidity();
 dtostrf(temp_c, 6, 2, buffer);
 disp_Temp();
}

void connect() {
  while(WiFi.waitForConnectResult() != WL_CONNECTED) {
    WiFi.begin(ssid, password);
    Serial.println("WiFi connection failed. Retry.");
  }
  Serial.print("Wifi connection successful - IP-Address: ");
  Serial.println(WiFi.localIP());
  while (!mqtt.connect("arduinoHandy")) {
    Serial.print(".");
  }
  mqtt.subscribe("/Handy/in/");
  Serial.println("MQTT connected!");
}
