#define BLINKER_WIFI
#include <Blinker.h>
#include <OneWire.h>
#include <DallasTemperature.h>
#include <DHT.h>
#include <DHT_U.h>
#include <Adafruit_Sensor.h>
#include <SoftwareSerial.h>
#include <ESP8266WiFi.h>
#include <ESP8266HTTPClient.h>
WiFiClient wificlient;
//#include <ArduinoJson.h>
char auth[] = "f71c23621ed1";
char ssid[] = "webserver";
char pswd[] = "www.360xyz.cn";
//几个全局变量
//DynamicJsonDocument jsonBuffer(100);
//JsonObject root;
// 新建组件对象
BlinkerButton Button1("btn-z2f");  //上升
BlinkerButton Button2("btn-biu");  //停止
BlinkerButton Button3("btn-3l9");  //下降
BlinkerButton Button4("btn-wmf");  //刷新温度湿度
BlinkerButton Button5("btn-u8w");  //广告开关


BlinkerNumber Number1("num-du7");  //温度
BlinkerNumber Number2("num-0j1");  //湿度

BlinkerText Text1("tex-je9");
BlinkerText Text2("tex-08u");  //广告牌状态
#define DHTPIN 13              // 数字引脚连接DHT传感器
// Feather HUZZAH ESP8266 note: use pins 3, 4, 5, 12, 13 or 14 --
#define DHTTYPE DHT11  // DHT 11
DHT_Unified dht(DHTPIN, DHTTYPE);
// 温度输入脚接开发板数字引脚13
#define d7 13
OneWire oneWire(d7);
DallasTemperature sensors(&oneWire);
int open = 5;
int close = 4;

int d0 = 16;
int d5 = 14;
int d6 = 12;
//广告牌定时开关输出电平脚 D4脚 2 不能使用 使为低电平时WIFI芯片灯会一直亮
int d8 = 15;

//开关状态 10为上升上限  0为下降上限 5为可以上升可降
int state1 = 5;
//此时执行中的状态  0关门  1开门  2停止 9什么也不代表
int exec_status = 9;
int humidity = 0;
float temperature = 0;
String hus;
String tes;
//最近操作物联用户相关信息


//ggb为false代表没有开灯箱 true为已开启灯箱
bool ggb = false;
// 按下按键即会执行该函数
//上升
void button1_callback(const String& state) {
  BLINKER_LOG("get button state: ", state);
  //限位开关导通为低电平 表明还没有达到限位,并且没有达到上升最大限制 能正常上升,断开为高电平表明达到限位了
  if (digitalRead(d5) == LOW && state1 != 10) {
    //主电源接通
    digitalWrite(d0, HIGH);

    delay(200);
    //开 上升
    digitalWrite(close, LOW);

    delay(200);
    digitalWrite(open, HIGH);
    exec_status = 1;
    Text1.print("正在上升");
  } else {
    Text1.print("上升限制");
  }
}
//停止
void button2_callback(const String& state) {
  BLINKER_LOG("get button state: ", state);
  //如果已经在上限或下限时只更新响应时间
  Text1.print("停止");
  if (digitalRead(d5) == LOW && digitalRead(d6) == LOW) {
    state1 = 5;
  }
  CloseAll();
}
//下降
void button3_callback(const String& state) {
  BLINKER_LOG("get button state: ", state);
  //限位开关导通时为低电平表明还没有达到限位,并且没到达到下降最大限制  能正常下降,断开为高电平表明达到限位了
  if (digitalRead(d6) == LOW && state1 != 0) {
    //主电源接通
    digitalWrite(d0, HIGH);
    delay(200);
    //关 下降

    digitalWrite(open, LOW);
    delay(200);
    digitalWrite(close, HIGH);
    Text1.print("正在下降");
    exec_status = 0;
  } else {
    Text1.print("下降限制");
  }
}
void button4_callback(const String& state) {
  BLINKER_LOG("get button state: ", state);
  // 获取温度事件并打印其值.
  sensors_event_t event;
  dht.temperature().getEvent(&event);
  if (isnan(event.temperature)) {
    Serial.println(F("Error reading temperature!"));
  } else {
    temperature = event.temperature;
    if (temperature < -10) {
      tes = "防冻";
    }
    if (temperature >= -10 && temperature < 18) {
      tes = "寒冷";
    }
    if (temperature >= 18 && temperature <= 25) {
      tes = "舒适";
    }
    if (temperature > 25 && temperature <= 36) {
      tes = "炎热";
    }
    if (temperature > 36) {
      tes = "防暑";
    }
  }
  delay(500);
  // Get humidity event and print its value.
  dht.humidity().getEvent(&event);
  if (isnan(event.relative_humidity)) {
    Serial.println(F("Error reading humidity!"));
  } else {
    humidity = event.relative_humidity;
    if (humidity < 40) {
      hus = "干燥";
    }
    if (humidity >= 40 && humidity <= 70) {
      hus = "舒适";
    }
    if (humidity > 70) {
      hus = "潮湿";
    }
  }
  Number1.print(temperature);
  Number2.print(humidity);
}
// 如果未绑定的组件被触发，则会执行其中内容

void button5_callback(const String& state) {
  BLINKER_LOG("get button state: ", state);
  if (ggb == false) {
    digitalWrite(d8, HIGH);
    ggb = true;
    Text2.print("开");
  } else {
    digitalWrite(d8, LOW);
    ggb = false;
    Text2.print("关");
  }
  //限位开关导通时为低电平表明还没有达到限位,并且没到达到下降最大限制  能正常下降,断开为高电平表明达到限位了
}


void setup() {
  // 初始化串口
  Serial.begin(115200);
  BLINKER_DEBUG.stream(Serial);
  BLINKER_DEBUG.debugAll();

  pinMode(open, OUTPUT);
  pinMode(close, OUTPUT);
  pinMode(d0, OUTPUT);
  pinMode(d8, OUTPUT);
  //pinMode(stop, OUTPUT);
  pinMode(d5, INPUT_PULLUP);
  pinMode(d6, INPUT_PULLUP);

  digitalWrite(open, LOW);
  digitalWrite(close, LOW);
  digitalWrite(d0, LOW);
  digitalWrite(d8, LOW);

  // 初始化blinker
  Blinker.begin(auth, ssid, pswd);

  //Blinker.attachData(dataRead);

  Button1.attach(button1_callback);
  Button2.attach(button2_callback);
  Button3.attach(button3_callback);
  Button4.attach(button4_callback);
  Button5.attach(button5_callback);
  if (ggb == false) {
    Text2.print("关");
  } else {
    Text2.print("开");
  }

  //防止 电源重启,门达到上限了,没有把状态改正,在这进行验证一下
  if (digitalRead(d5) == HIGH) {
    state1 = 10;
  }
  if (digitalRead(d6) == HIGH) {
    state1 = 0;
  }
  String tmpDate = myHttpGet("http://jyan.360xyz.cn/api/Hour");
  int dateL = tmpDate.toInt();
  if (dateL > 6 && dateL < 18) {
    ggb = true;
    digitalWrite(d8, HIGH);
    Text2.print("开");
  }
}

void loop() {
  Blinker.run();
  //操作运行时 上升达到限位了,并且上次状态不是上升上限, 并且执行状态是上升 限位开关断开
  if (digitalRead(d5) == HIGH && state1 != 10 && exec_status == 1) {
    //关闭所有开关
    digitalWrite(open, LOW);
    digitalWrite(close, LOW);
    delay(200);
    //断开电源接通
    digitalWrite(d0, LOW);
    Text1.print("开门达到上限");
    state1 = 10;

    //执行状态为空
    exec_status = 9;

    String tmpDate = myHttpGet("http://jyan.360xyz.cn/api/Hour");
    int dateL = tmpDate.toInt();
    if (dateL > 6 && dateL < 18) {
      ggb = true;
      digitalWrite(d8, HIGH);
      Text2.print("开");
    }
  }
  //操作运行时 下降达到限位了,并且上次状态不是下降上限 并且执行状态是下降  限位开关开路
  if (digitalRead(d6) == HIGH && state1 != 0 && exec_status == 0) {
    digitalWrite(open, LOW);
    digitalWrite(close, LOW);
    delay(200);
    //断开电源接通
    digitalWrite(d0, LOW);
    Text1.print("关门达到上限");
    state1 = 0;

    //执行状态为空
    exec_status = 9;

    //关门就把广告灯箱关了
    digitalWrite(d8, LOW);
    //告诉服务器让其知道灯箱现在是关闭状态

    delay(500);
  }
  //即没有上限也没有下限状态
  if (digitalRead(d5) == LOW && digitalRead(d6) == LOW && state1 != 5) {
    state1 = 5;
  }
}
String myHttpGet(String string) {
  HTTPClient http;
  String response;
  http.begin(wificlient, string);
  http.setTimeout(3000);
  int httpCode = http.GET();
  if (httpCode == 200) {
    response = http.getString();
    return response;
  } else {
    return "";
  }
  http.end();
}
//关闭上升,下降,变压器主电源
void CloseAll() {
  digitalWrite(open, LOW);
  digitalWrite(close, LOW);
  delay(200);
  //断开电源接通
  digitalWrite(d0, LOW);
}
