kang xu
Published © MIT

Weather Reminder

This device can show you the weather forecast info.

IntermediateShowcase (no instructions)10 hours766
Weather Reminder

Things used in this project

Hardware components

ESP8266 ESP-01
Espressif ESP8266 ESP-01
×1
uart lcd
×1
1s li-po battery
×1
li-po battear charge board
×1

Software apps and online services

Arduino IDE
Arduino IDE
seniverse weather info server

Hand tools and fabrication machines

Soldering iron (generic)
Soldering iron (generic)
usb to uart module

Story

Read more

Schematics

wiring pic

Code

getweather

C/C++
myDevices Cayenne function included,
/*

*/
#define CAYENNE_PRINT Serial
#include <CayenneMQTTESP8266.h>

#include <ESP8266WiFi.h>
#include <EEPROM.h>
#include <DNSServer.h>
#include <ESP8266WebServer.h>
#include <WiFiManager.h>          //https://github.com/tzapu/WiFiManager

#include <aJSON.h>
#include <SoftwareSerial.h>

#define pcr(x) {if(DEBUG) Serial.print(x);}
#define pln(x) {if(DEBUG) Serial.println(x);}
#define pr(x) {if(DEBUG) Serial.println("");}
#define px(x,v){pr();pcr(x);pln(v);}
#define pf(x,v,f){if(f) px(x,v);}
#define pa(x,v){ Serial.print(x); Serial.println(v);} //print anyway
#define MAXCOLUMN 90

#define CAYENNE_PRINT Serial  // Comment this out to disable prints and save space
#include <CayenneESP8266WiFi.h>


char username[] = "44018410-7bd5-11e7-afeb-31ee1d0dc225";
char password[] = "f13c3789fc76a9de7c72c62a5755cefea7e639a9";
char clientID[] = "c0377050-7be7-11e7-b8f9-111f8d0a5e91";

int DEBUG = 1;

//define your default values here.
char thinkpage_host[25] = "api.thinkpage.cn";
char thinkpage_port[6] = "80";
char thinkpage_key[30] = "";
char thinkpage_city[30] = "";
char thinkpage_unity[5] = "c";   //celsus
//eeprom max sector length
#define seclength 32
//flag for saving data
bool shouldSaveConfig = false;

//
const char dayofweekCs[][8] = {"---", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"};
const char daysTextCs[][8] = {"Today", "Tomoow", "AfTomo", "C", "M", "D", "Y", "to"};
const char currentWeatherTextCs[] = {"N o w"};
typedef struct {
  String ssid = "";
  String pass = "";
  String city = "";
  String thinkpage_key = "";
} EEPROMDataS_t;
typedef struct {
  uint8_t templow = 0;
  uint8_t temphigh = 0;
  uint8_t WeatherCode = 0;
  String  High = "";
  String  Low = "";
  String  WeatherText = "";
  boolean valid = false;
} Wea_t;
Wea_t WeatherNow;
Wea_t WeatherToday;
Wea_t WeatherTomorrow;
Wea_t WeatherTheDayAfterTomorrow;
Wea_t WeatherForecaResultStstructure[] = {
  WeatherNow, WeatherToday, WeatherTomorrow,
  WeatherTheDayAfterTomorrow
};
typedef struct {
  String year = "";
  String hour = "";
  String mint = "";
  String month = "";
  String days = "";
  String second = "";
  boolean valid = false;
  uint8_t week = 0;
} Tim_t;
Tim_t TimNow;
typedef struct {
  String UserId = "";
  String NotebookId = "";
  String Token = "";
  String NotebookId1 = "";
  String NotebookId2 = "";
  String NotebookId3 = "";
  uint8_t number = 0;
} NotebookStructure_t;
typedef struct {
  String note = "";
  String title = "";
  String date = ""; //to do
  boolean ok = false;
  uint8_t number = 0;
} note_t;

//
SoftwareSerial swSer(14, 12, false, 256);
//
WiFiClient client;
//
//const char* ssid     = "your-ssid";
//const char* password = "your-pass";
//thinkpage
const char* host = "api.thinkpage.cn";
const char* key = "gluukolgujxkvutp";
//buf
String line = "";
char jsonbuf[512] = {0};
//
/********************************************
   name:
   para:
 *********************************************/
void setup() {
  //
  Serial.begin(115200);
  usartGpuInit();
  delay(10);
  // We start by connecting to a WiFi network
  pr(); pr();
  EEPROM.begin(500);

  swSer.println("SPG(2);");//show wifi connect status ...
  //  AutoConnectWifi();

  for (int i = 0; i < 3; i++)
  {
    delay(1000); getWeatherForecastInDayof(i + 1) ;
  }
  /*
    printWeather(WeatherToday);
    printWeather(WeatherTomorrow);
    printWeather(WeatherTheDayAfterTomorrow);
  */
  Cayenne.begin(username, password, clientID);
}
//
void usartGpuInit() {
  //softwa serial
  swSer.begin(115200);
  delay(100);
  swSer.println("SPG(1);");  //show logo
  delay(1000);
}
/*
    usartGpuWinInit
*/
void usartGpuShowWinBox() {
  const char* str1 = "W8BF(0,0,80,80,2);";
  const char* str2 = "W8BF(85,0,219,80,3);";
  const char* str3 = "W8BF(75,85,145,175,1);";
  const char* str4 = "W8BF(0,85,70,175,6);";
  const char* str5 = "W8BF(150,85,219,175,7);";
  const char* str6 = "SBC(52);";
  const char* initstr[] = {str1, str2, str3, str4, str5, str6};
  //usart gou init
  for (int i = 0 ; i < 2; i++) {
    swSer.println("CLS(7);");
  }
  for (int i = 0 ; i < 6; i++) {
    swSer.println(initstr[i]); delay(50);
  }
}
//callback notifying us of the need to save config
void saveConfigCallback () {
  Serial.println("Should save config");
  shouldSaveConfig = true;
}
void AutoConnectWifi() {
  // The extra parameters to be configured (can be either global or just in the setup)
  // After connecting, parameter.getValue() will get you the configured value
  // id/name placeholder/prompt default length

  EEPROMDataS_t eepromdata = eepromgetall();
  eepromdata.thinkpage_key.toCharArray(thinkpage_key, eepromdata.thinkpage_key.length() + 1);
  eepromdata.city.toCharArray(thinkpage_city, eepromdata.city.length() + 1);
  px("[debug]:key is:", thinkpage_key); px("length:",  sizeof(thinkpage_key));
  px("[debug]:city is:", thinkpage_city); px("length:", sizeof(thinkpage_city));

  WiFiManagerParameter custon_thinkpage_key("key", "thinkpage key", thinkpage_key, sizeof(thinkpage_key));//id placeholder defaultvalue length
  WiFiManagerParameter custon_thinkpage_city("city", "thinkpage city", thinkpage_city, sizeof(thinkpage_city)); //id placeholder defaultvalue length

  //  WiFiManagerParameter custon_thinkpage_unity("unity", "thinkpage unity", thinkpage_unity, 5);//id placeholder defaultvalue length
  //Local intialization. Once its business is done, there is no need to keep it around
  WiFiManager wifiManager;
  //set config save notify callback
  wifiManager.setSaveConfigCallback(saveConfigCallback);
  //set static ip
  //wifiManager.setSTAStaticIPConfig(IPAddress(10, 0, 1, 99), IPAddress(10, 0, 1, 1), IPAddress(255, 255, 255, 0));
  //add all your parameters here
  wifiManager.addParameter(&custon_thinkpage_key);
  wifiManager.addParameter(&custon_thinkpage_city);
  //  wifiManager.addParameter(&custon_thinkpage_unity);
  if (!wifiManager.autoConnect("AutoConnectAP", "12345678")) {
    Serial.println("failed to connect and hit timeout");
    delay(3000);
    //reset and try again, or maybe put it to deep sleep
    ESP.reset();
    delay(5000);
  }
  //if you get here you have connected to the WiFi
  Serial.println("connected...yeey :)");
  //read updated parameters
  const char *val1 = custon_thinkpage_key.getValue();
  const char *val2 = custon_thinkpage_city.getValue();
  strcpy(thinkpage_key, val1);
  strcpy(thinkpage_city, val2);
  //  strcpy(thinkpage_unity, custon_thinkpage_unity.getValue());
  if (shouldSaveConfig) {
    Serial.println("saving config");
    eepromflush(2); eepromflush(3);
    eepromsave(2, thinkpage_city);
    eepromsave(3, thinkpage_key);
    px("[debug]:tp_city:", thinkpage_city); px("length is:", sizeof(thinkpage_city));
    px("[debug]:tp_key:", thinkpage_key); px("length is:", sizeof(thinkpage_key));
    //end save
    Serial.printf("para1 is:%s ...para2 is :%s\r\n", thinkpage_key, thinkpage_city);
  }

  Serial.println("local ip");
  Serial.println(WiFi.localIP());
  // thinkpage_key = eepromget(2);
  // thinkpage_city = eepromget(3);

}
void printWeather(Wea_t Wea) {
  px("WeatherText:", Wea.WeatherText);
  px("WeatherCode:", Wea.WeatherCode);
  px("Temp low   :", Wea.Low);
  px("Temp high  :", Wea.High);
}
/********************************************
   name:
   para:
   outp:-1-->not find / >0-->find
 *********************************************/
int StringFind(const char *pSrc, const char *pDst) {
  int i, j;
  for (i = 0; pSrc[i] != '\0'; i++)
  {
    if (pSrc[i] != pDst[0])
      continue;
    j = 0;
    while (pDst[j] != '\0' && pSrc[i + j] != '\0')
    {
      j++;
      if (pDst[j] != pSrc[i + j])
        break;
    }
    if (pDst[j] == '\0')
      return i;
  }
  return -1;
}
/********************************************
   name:current weather
   para:
 *********************************************/
boolean getCurrentWeather() {
  //
  boolean succeed = false;
  memset(jsonbuf, 0, sizeof(jsonbuf));
  delay(5000);
  px("[Net]:Connecting to ", host);
  const int httpPort = 80;
  char retryTimes = 5;
  if (!client.connect(host, httpPort) && retryTimes--) {
    delay(500);
    px("[NetServer]:client connect failed,and is retrying for ", retryTimes);
  }
  if (retryTimes == 0)return succeed;
  String url1 = "/v3/weather/now.json?key=";
  url1 += thinkpage_key;
  url1 += "&location=";
  url1 += thinkpage_city;
  url1 += "&language=en&=";

  px("[Net]:Request url ", url1);
  ////This will send the request to the server
  client.print(String("GET ") + url1 + " HTTP/1.1\r\n" +
               "Host: " + host + "\r\n" +
               "Connection: close\r\n\r\n");
  uint32_t timeout = millis();
  while (client.available() == 0) {
    if (millis() - timeout > 5000) {
      px("[Net]:Client timeout!", " ");
      client.stop();
      return succeed;
    }
  }

  char c = 0;
  boolean isOver = false;
  uint16_t bufferPos = 0;
  uint8_t status_ = 0, innerstatus = 0, innercnt = 0;
  uint8_t tempstatus = 0; char temp[5] = "Date";
  uint8_t  cnt = 0, i = 0;
  //char *str=0;
  String Timestamp = "";
  while (client.available()) {
    c = client.read();
    //    pcr(c);
    //    split the time string  Date: Tue, 11 Apr 2017 04:35:12 GMT
    switch (tempstatus) {
      case 0: {
          if (c == ':') {
            tempstatus = 1;
            pf("[Debug]:time:got ", c, 0);
          }
        } break;
      case 1: {
          if (c == ' ' | c == ':') {
            c = ',';
            cnt++;
            pf("[Debug]:time:got ' ' or ':' and cnt=", cnt, 0);
          }
          Timestamp += c;
          if (cnt == 8) {
            tempstatus = 3;
            pf("[Debug]:time:cnt = 8 and tempstatus =", tempstatus, 0);
          }
        } break;
      case 3: {
          tempstatus = 4;
          pcr("[Debug]:Time stamp:"); pln(Timestamp);
        } break;
    }
    switch (status_) {
      case 0: {
          if (c == '{')
            innercnt++;
          if (innercnt == 4)
            status_ = 1;
        } break;
      case 1: {
          if (c != '}') {
            jsonbuf[bufferPos] = c;
            bufferPos ++;
          }
          else
            status_ = 2;
        } break;
      case 2: {  //rec "text":"Cloudy","code":"4","temperature":"20"
          isOver = true;
        } break;
    } //switch case
  }
  pr();
  px("[Local]:Jsonbuf-length:", bufferPos);
  px("[Local]:Jsonbuf :", jsonbuf);

  parsetimestamp(Timestamp); //

  if (isOver) {
    //add '{' '}' to jsonbuf
    char tep = jsonbuf[bufferPos - 1];
    //    pln(tep);
    for (int i = 0; i < bufferPos; i++) {
      jsonbuf[bufferPos - i] = jsonbuf[bufferPos - 1 - i];
    }
    jsonbuf[0] = '{';
    jsonbuf[bufferPos++] = tep;
    jsonbuf[bufferPos++] = '}';
    pf("[Local]:Jsonbuf-length:", bufferPos, 0);
    pf("[Local]:Jsonbuf :", jsonbuf, 0);
    aJsonObject *noww  = aJson.parse(jsonbuf);
    if (noww) {
      succeed = true;
      bufferPos = 0;
      aJsonObject *WeatherText = aJson.getObjectItem(noww, "text");
      aJsonObject *tmp  = aJson.getObjectItem(noww, "temperature");
      aJsonObject *WeatherCode  = aJson.getObjectItem(noww, "code");
      px("[Debug]:temperature:", tmp->valuestring);
      px("[Debug]:weathercode:", WeatherCode->valuestring);
      px("[Debug]:weathertext:", WeatherText->valuestring);
      String str = WeatherCode->valuestring;
      WeatherNow.valid = true;
      WeatherNow.Low = tmp->valuestring;
      WeatherNow.WeatherText = WeatherText->valuestring;
      if (str.toInt() == 99)WeatherNow.WeatherCode = 40;
      else  if (str.toInt() == 0)WeatherNow.WeatherCode = 39;
      else WeatherNow.WeatherCode = str.toInt(); //int
      //char *str
    }//if noww
  }//isOver //
  px("[Net]:", "Closing conncetion!")
  return succeed;
}

void parsetimestamp(String timestamp) {
  //parse Timestamp
  const char months[][4] = {"Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"};
  const char weeks[][5] = {"---", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"};
  int debug = 0;
  //  String Timestamp = ",Tue,,11,Apr,2017,04,35,12,";
  String Timestamp = timestamp;
  //sample:,Tue,,11,Apr,2017,04,35,12,
  pf("[Debug]:start to parse time stamp ", 0, 1);
  uint8_t index, index1;
  uint8_t strlength = Timestamp.length();

  index = Timestamp.indexOf(',');
  px("[Debug]:the fitst index of , is ", index);
  //cut the 1th ,
  String substr = Timestamp.substring(index + 1, strlength);
  pf("[Debug]:the sub string is:", substr, debug);

  index = substr.indexOf(',');
  String week = substr.substring(0, index);
  px("[Debug]:the week is:", week);
  debug = 0;
  char temp[5];
  strcpy(temp, week.c_str()); //!!!
  pf("[Debug]:convert week to char* ,and its length is ", sizeof(temp), debug);
  for (int i = 0; i < 8; i++) {
    if (StringFind(temp, weeks[i]) >= 0) {
      pf("[Debug]:the weeks[i] is ", weeks[i], debug);
      TimNow.week = i;
      pf("[Debug]:the week in number is:", i, debug);
    }
  }
  //skip 2 ','s
  substr = substr.substring(index + 2, strlength);
  pf("[Debug]:the sub string is:", substr, debug);
  index = substr.indexOf(',');
  String days = substr.substring(0, index);
  px("[Debug]:the days is : ", days);
  TimNow.days = days;

  substr = substr.substring(index + 1, strlength);
  pf("[Debug]:the sub string is:", substr, debug);
  index = substr.indexOf(',');
  String month = substr.substring(0, index);
  px("[Debug]:the month is : ", month);
  //  char temp[4];
  debug = 0;
  strcpy(temp, month.c_str()); //!!!
  pf("[Debug]:convert week to char* ,and its length is ", sizeof(temp), debug);
  for (int i = 0; i < 12; i++) {
    if (StringFind(temp, months[i]) >= 0) {
      pf("[Debug]:the months[i] is ", months[i], debug);
      TimNow.month = i + 1;
      pf("[Debug]:the months in number is ", i, debug);
    }
  }
  substr = substr.substring(index + 1, strlength);
  pf("[Debug]:the sub string is ", substr, debug);
  index = substr.indexOf(',');
  String year = substr.substring(0, index);
  px("[Debug]:the year is ", year);
  TimNow.year = year;

  substr = substr.substring(index + 1, strlength);
  pf("[Debug]:the sub string is ", substr, debug);
  index = substr.indexOf(',');
  String value = substr.substring(0, index);
  px("[Debug]:the hour is ", value);
  TimNow.hour = (String)(value.toInt() + 8);

  substr = substr.substring(index + 1, strlength);
  pf("[Debug]:the sub string is:", substr, debug);
  index = substr.indexOf(',');
  value = substr.substring(0, index);
  px("[Debug]:the mint is ", value);
  TimNow.mint = value;

  substr = substr.substring(index + 1, strlength);
  pf("[Debug]:the sub string is:", substr, debug);
  index = substr.indexOf(',');
  value = substr.substring(0, index);
  px("[Debug]:the second is ", value);
  TimNow.second = value;
}
/*

*/
void printTime() {
  String tim, mint, second, hour;
  //  if (TimNow.mint.toInt() < 10&&TimNow.mint.toInt() >0)mint = '0' + TimNow.mint;
  //  else
  mint = TimNow.mint;
  //  if (TimNow.second.toInt() < 10)second = '0' + TimNow.second;
  //  else
  second = TimNow.second;
  //  if (TimNow.hour.toInt() < 10&&TimNow.hour.toInt() > 0)hour = '0' + TimNow.hour;
  //  else
  hour = TimNow.hour;
  tim = "Date:" + TimNow.year + '/' + TimNow.month + '/' + TimNow.days + "\r\n" +
        "Time:" + hour + ':' + mint + ':' + second + " " + TimNow.week ;
  pr(); pln(tim);
}
//must run in the main loop
void updateTime() {
  //
  uint32_t allsecond = 0;
  allsecond = (TimNow.hour.toInt()) * 3600 + (TimNow.mint.toInt()) * 60 + TimNow.second.toInt();
  static uint32_t pretimeUpdateTime;
  if (millis() - pretimeUpdateTime > 1000) {
    pretimeUpdateTime = millis();
    allsecond ++;
    pf("the whole second is ", allsecond, 0);
    TimNow.second = (String)(allsecond % 60); pf("second:", TimNow.second, 0);
    TimNow.mint = (String)(allsecond % 3600 / 60); pf("mint:", TimNow.mint, 0);
    TimNow.hour = (String)(allsecond / 3600); pf("hour:", TimNow.hour, 0);

  }
}
/*
   day=1--->today's forecast
   day=2--->tomorrow's forecast
   day=3--->the day after tomorrow's forecast
*/
boolean getWeatherForecastInDayof(uint8_t day) {
  //
  char c = 0;//
  boolean isBody = false;
  uint16_t bufferPos = 0;
  //qm = quotation mark
  //sm = semicolon
  boolean isHead = false, isStart = false;
  //
  uint8_t cnt = 0;
  boolean isQmS  = false;
  boolean isSearching = true;
  //
  boolean succeed = false;
  char buf[6] = {0};
  memset(jsonbuf, 0, sizeof(jsonbuf));
  memset(buf, 0, 5);
  //
  //  WiFiClient client;
  const int httpPort = 80;
  uint8_t retryTimes = 5;
  if (!client.connect(host, httpPort) && retryTimes--) {
    delay(500);
    px("[NetServer]:client connect failed,and is retrying for ", retryTimes);
  }
  if (retryTimes == 0)return false;
  String city = thinkpage_city;
  String unit = "c";
  String url1 = "/v3/weather/daily.json?key=";
  uint8_t startday = 0;
  uint8_t forecastdays = 1;
  if (day == 2)startday = 1;
  if (day == 3)startday = 2;
  url1 +=  thinkpage_key;
  url1 += "&location=";
  url1 += thinkpage_city;
  url1 += "&language=en&uint=";
  url1 += unit;
  url1 += "&start=";
  url1 += (String)startday;
  url1 += "&days=";
  url1 += (String)forecastdays;

  px("[Net]:Request url :", url1);

  ////This will send the request to the server
  client.print(String("GET ") + url1 + " HTTP/1.1\r\n" +
               "Host: " + host + "\r\n" +
               "Connection: close\r\n\r\n");
  uint32_t timeout = millis();
  while (client.available() == 0) {
    if (millis() - timeout > 5000) {
      px("[Net]:", "Client timeout!");
      client.stop();
      return false;;
    }
  }
  while (client.available()) {
    c = client.read();
    if (c == '{') {
      isBody = true;
    }
    if (isBody) {
      if ((c == 'd') && isSearching) {
        isQmS = true;
        cnt = 0;
        memset(buf, 0, 5);
        pf("[Debug]:Find 'd' ", cnt, 0);
      }
      if (isQmS) {
        buf[cnt] += c;
        cnt++;
        pf("[Debug]:Receiving and cnt is ", cnt, 0);
      }
      if (cnt == 5) {
        isQmS = false;
        cnt = 0;
        if (!strcmp(buf, "daily")) {  //buf  == daily
          if (DEBUG)Serial.print("find daily");
          pf("[Debug]:Find 'daily' ", 0, 0);
          isStart = true;
          isSearching = false;
        }
      }
      if (isStart) {
        //        if (DEBUG)Serial.print("handle jsonbuf head");
        strcpy(jsonbuf, "{\"dail");
        isStart = false;
        isHead = true;
        bufferPos = 6;
      }
      if (isHead  ) {
        jsonbuf[bufferPos++] = c;
        //if(DEBUG)Serial.print("receive c");
      }
    }
  }
  px("[Local]:Jsonbuf-length:", bufferPos);
  px("[Local]:Jsonbuf :", jsonbuf);
  aJsonObject *wea  = aJson.parse(jsonbuf);
  bufferPos = 0;
  if (wea) {
    aJsonObject *ws = aJson.getObjectItem(wea, "daily");
    if (ws) {
      aJsonObject *res  = aJson.getArrayItem(ws, 0);
      if (res) {
        aJsonObject *text_day =  aJson.getObjectItem(res, "text_day");
        if (text_day ) {
          pf("[Debug]:text_day:", text_day ->valuestring, 1);
        }
        aJsonObject *high =  aJson.getObjectItem(res, "high");
        if (high) {
          pf("[Debug]:high: ", high->valuestring, 1);
        }
        aJsonObject *low =  aJson.getObjectItem(res, "low");
        if (low) {
          pf("[Debug]:Low :", low->valuestring, 1);
        }
        aJsonObject *code_day =  aJson.getObjectItem(res, "code_day");
        if (code_day) {
          pf("[Debug]:Code_day :", code_day->valuestring, 1);
        }
        //
        succeed = true;
        //
        String str = code_day->valuestring; uint8_t code;
        if (str.toInt() == 0)code = 39;
        else  if (str.toInt() == 99)code = 40;
        else code = str.toInt();
        switch (day) {
          case 1: {
              WeatherToday.High = high->valuestring;
              WeatherToday.Low = low->valuestring;
              WeatherToday.WeatherCode = code;
              WeatherToday.WeatherText = text_day ->valuestring;
            } break;
          case 2: {
              WeatherTomorrow.High = high->valuestring;
              WeatherTomorrow.Low = low->valuestring;
              WeatherTomorrow.WeatherCode = code;
              WeatherTomorrow.WeatherText = text_day ->valuestring;

            } break;
          case 3: {
              WeatherTheDayAfterTomorrow.High = high->valuestring;
              WeatherTheDayAfterTomorrow.Low = low->valuestring;
              WeatherTheDayAfterTomorrow.WeatherCode = code;
              WeatherTheDayAfterTomorrow.WeatherText = text_day ->valuestring;
            } break;
        } //switch case
      } //json is valid
    }//ws is valid
  }//root is valid
  return succeed;
}

/************************
      //show current time
************************/
void updateCurrentWeatherDis(Tim_t Time) {
  char buf[60] = {0};
  //varaiable values
  char Texttemp[10] = {0};
  strcpy(Texttemp, (WeatherNow.WeatherText).c_str());
  int  tempLow = (WeatherToday.Low).toInt() , tempHigh = (WeatherNow.Low).toInt();
  int  WeatherPic = WeatherNow.WeatherCode;
  int  wp1 = WeatherToday.WeatherCode,
       wp2 = WeatherTomorrow.WeatherCode,
       wp3 = WeatherTheDayAfterTomorrow.WeatherCode;
  //  uint8_t hour = (Time.hour).toInt();
  //  uint8_t mint = (Time.mint).toInt();
  uint16_t year = (Time.year).toInt();
  uint8_t month = (Time.month).toInt();
  uint8_t days = (Time.days).toInt();
  uint8_t  week = Time.week;
  int  dayofweek1 = Time.week ,
       dayofweek2 = Time.week + 1,
       dayofweek3 = Time.week + 2;
  if (dayofweek3 % 7 == 0 && dayofweek3 / 7 != 0)dayofweek3   = 7;
  else dayofweek3  = dayofweek3 % 7;
  if (dayofweek2 % 7 == 0 && dayofweek2 / 7 != 0)dayofweek2   = 7;
  else dayofweek2  = dayofweek2 % 7;

  sprintf(buf, "DS16(5,5,'%d/%d/%d',15,0);", year, month, days );
  swSer.println(buf);
  memset(buf, 0, sizeof(buf));

  sprintf(buf, "SBC(53);DS16(88,5,'%s',15,0);PIC(157,10,%d);", currentWeatherTextCs, WeatherPic);
  swSer.println(buf);
  memset(buf, 0, sizeof(buf));
  delay(50);
  sprintf(buf, "DS16(86,54,'%d%s%d%s',15,0);DS16(90,30,'%s',15,0);",  tempLow, daysTextCs[7], tempHigh, daysTextCs[3], Texttemp);
  swSer.println(buf);
  memset(buf, 0, sizeof(buf));
  delay(50);
  sprintf(buf, "PIC(5,112,%d);PIC(80,112,%d);PIC(155,112,%d);SBC(56);", wp1, wp2, wp3);
  swSer.println(buf);
  memset(buf, 0, sizeof(buf));
  delay(50);
  sprintf(buf, "DS16(10,90,'%s',15,0);SBC(51);DS16(85,90,'%s',15,0);", dayofweekCs[dayofweek1], dayofweekCs[dayofweek2]);
  swSer.println(buf);
  memset(buf, 0, sizeof(buf));
  delay(50);
  sprintf(buf, "SBC(57);DS16(160,90,'%s',15,0);",  dayofweekCs[dayofweek3]);
  swSer.println(buf);
  memset(buf, 0, sizeof(buf));
  delay(50);
}
void usartGpuUpdateTimeDis(uint8_t blinkCursor, Tim_t TimeStrture) {
  char buf[50] = {0};
  //WeatherToday, WeatherTomorrow, WeatherTheDayAfterTomorrow;
  uint8_t hour = (TimeStrture.hour).toInt();
  if (hour == 24)hour = 0;
  uint8_t mint = (TimeStrture.mint).toInt();
  uint8_t week = TimeStrture.week;
  char Cursor = ':';
  if (!blinkCursor)Cursor = ' ';
  //
  swSer.println("SBC(52);");
  delay(50);
  if (hour < 10)
    sprintf(buf, "DS32(0,40,'0%d%c%d',15);DS16(15,22,'%s',15,0);", hour, Cursor, mint, dayofweekCs[week]);
  else if (mint < 10)
    sprintf(buf, "DS32(0,40,'%d%c0%d',15);DS16(15,22,'%s',15,0);", hour, Cursor, mint, dayofweekCs[week]);
  else
    sprintf(buf, "DS32(0,40,'%d%c%d',15);DS16(15,22,'%s',15,0);", hour, Cursor, mint, dayofweekCs[week]);
  swSer.println(buf);
  memset(buf, 0, sizeof(buf));
  delay(50);
}
//variable values
uint32_t pretimeGetForecast, pretimePrintTime, pretimeUsartGpuUpdateTimeDis;
uint8_t  Cursor  = 1;
uint32_t daysCnt = 0;
uint8_t  status_ = 1;  //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
#define TIMEINTERVAL  1000*60*10;
uint32_t timeInterval = TIMEINTERVAL;
uint32_t lastMillis = 0;
void loop() {
  Cayenne.loop();
  //  uint32_t timeIntervalGetForecast = timeInterval; //10min
  uint32_t timeIntervalPrintTime = 1000;
  //  updateTime();//update timNow struct,retain the time clock  still running ,but it is not precise
  switch (status_) {
    case 1: {
        updateTime();
        status_ = 2;
      } break;
    case 2: {
        status_ = 3;
        if (millis() - pretimeGetForecast > timeInterval) {
          pretimeGetForecast = millis();
          timeInterval = 500;
          getWeatherForecastInDayof(daysCnt + 1) ; daysCnt++;
          if (daysCnt == 3) {
            timeInterval = TIMEINTERVAL;
            updateCurrentWeatherDis(TimNow);
            daysCnt = 0;
          }
          else status_ = 1; //
        }
      } break;
    case 3: {
        status_ = 4;
        if (millis() - pretimeUsartGpuUpdateTimeDis > 1000) { //bind with updateTime();
          pretimeUsartGpuUpdateTimeDis = millis();
          usartGpuUpdateTimeDis(Cursor, TimNow);
          if (Cursor)Cursor = 0;
          else Cursor = 1;
        }
      } break;
    case 4: {
        status_ = 1;
        if (millis() - pretimePrintTime > timeIntervalPrintTime) {
          pretimePrintTime = millis();
          //          printTime();
        }
      } break;
  }//switch
  if (millis() - lastMillis > 10000) {
    lastMillis = millis();
    //Write data to Cayenne here. This example just sends the current uptime in milliseconds.
    Cayenne.virtualWrite(0, millis());
    //Some examples of other functions you can use to send data.
    //    Cayenne.celsiusWrite(1, 22.0);
    uint32_t size = ESP.getFreeHeap();
    Cayenne.virtualWrite(1, size);
    //Cayenne.luxWrite(2, 700);
    //Cayenne.virtualWrite(3, 50, TYPE_PROXIMITY, UNIT_CENTIMETER);
    printf("Millis:%d \tfreeheap:%d!\r\n", lastMillis, size);
  }
}
/*
   key ... 1,2,3
   val ... val1,val2,val3
   sava value with key
*/
void eepromsave(uint8_t  key, char * val) {
  int add = seclength * key;
  while (*val) {
    //    Serial.print(add); Serial.print(*val);
    EEPROM.write(add++, *val);
    val++;
  }
  EEPROM.commit();
}
//Default function for processing actuator commands from the Cayenne Dashboard.
//You can also use functions for specific channels, e.g CAYENNE_IN(1) for channel 1 commands.
CAYENNE_IN_DEFAULT()
{
  CAYENNE_LOG("CAYENNE_IN_DEFAULT(%u) - %s, %s", request.channel, getValue.getId(), getValue.asString());
  //Process message here. If there is an error set an error message using getValue.setError(), e.g getValue.setError("Error message");
}
/*
   key ...
   get value by key
*/
void eepromflush(uint8_t key) {
  uint8_t start = key * seclength;
  for (int i = start ; i < start + seclength; i++) {
    EEPROM.write(i, 0);
  }
  EEPROM.commit();
}
String eepromget(uint8_t key) {
  //EEPROM.begin(500);
  String temp = "";
  uint8_t start = 0;
  start = key * seclength;
  for (int i = start ; i < start + seclength; i++) {
    char c = EEPROM.read(i);
    if (c != 0)
      temp += char(c);
  }
  //EEPROM.end();
  return temp;
}
/*
   get all useful data from eeprom
*/
EEPROMDataS_t  eepromgetall() {
  EEPROMDataS_t eepromdat;
  eepromdat.ssid = eepromget(0);
  eepromdat.pass = eepromget(1);
  eepromdat.city = eepromget(2);
  eepromdat.thinkpage_key = eepromget(3);
  return eepromdat;
}

Credits

kang xu

kang xu

0 projects • 0 followers

Comments