mirror of https://github.com/sqfmi/Watchy.git
Added getAmbientTemp() and made weather dynamically initialised.
parent
da93d3c5c4
commit
4150bc625a
|
@ -9,7 +9,6 @@ RTC_DATA_ATTR BMA423 sensor;
|
|||
RTC_DATA_ATTR bool WIFI_CONFIGURED;
|
||||
RTC_DATA_ATTR bool BLE_CONFIGURED;
|
||||
RTC_DATA_ATTR weatherData currentWeather;
|
||||
RTC_DATA_ATTR int weatherIntervalCounter = WEATHER_UPDATE_INTERVAL;
|
||||
RTC_DATA_ATTR bool displayFullInit = true;
|
||||
|
||||
Watchy::Watchy(){} //constructor
|
||||
|
@ -45,6 +44,43 @@ void Watchy::init(String datetime){
|
|||
deepSleep();
|
||||
}
|
||||
|
||||
//! Initialise the weather subsystem with city, refresh rate, language, units, API Key
|
||||
/*!
|
||||
City is an integer, which you can get by looking up your city on openweathermap.org. You'll
|
||||
get a URL like this https://openweathermap.org/city/5128581 (which is New York City). The number
|
||||
you want is the city number (NYC is 5128581).
|
||||
|
||||
Celsius is a boolean. True means use Celsius temperature. False means use Fahrenheit.
|
||||
|
||||
updateInterval is how often, in minutes, the weather should update. Minimum 5, max 65536 (about 45 days)
|
||||
Note: Weather and NTP clock sync are done in the same function, so this also controls how frequently
|
||||
the Watchy attempts to synchronise its clock with NTP.
|
||||
|
||||
lang is a 2-letter string (e.g., "en" or "de" or "nl"). Weather text will be returned in
|
||||
the selected language. See here: https://openweathermap.org/current#multi Defaults to "en"
|
||||
|
||||
API Key is an openweathermap API key. Find out more about it here: https://openweathermap.org/api
|
||||
|
||||
*/
|
||||
void Watchy::setupWeather( uint32_t city,
|
||||
bool celsius,
|
||||
uint16_t updateInterval,
|
||||
String lang,
|
||||
String apikey ) {
|
||||
|
||||
if( updateInterval < 5 ) {
|
||||
updateInterval = 5;
|
||||
}
|
||||
weatherInterval = updateInterval;
|
||||
weatherCity = city;
|
||||
weatherCelsius = celsius;
|
||||
weatherAPIKey = apikey;
|
||||
weatherLang = lang;
|
||||
weatherInit = true; // record the fact that we initialised
|
||||
// indicates that weather needs to be fetched
|
||||
weatherIntervalCounter = weatherInterval;
|
||||
}
|
||||
|
||||
void Watchy::displayBusyCallback(const void*){
|
||||
gpio_wakeup_enable((gpio_num_t)BUSY, GPIO_INTR_LOW_LEVEL);
|
||||
esp_sleep_enable_gpio_wakeup();
|
||||
|
@ -554,34 +590,57 @@ void Watchy::drawWatchFace(){
|
|||
display.println(currentTime.Minute);
|
||||
}
|
||||
|
||||
|
||||
#define OPENWEATHERMAP_URL "http://api.openweathermap.org/data/2.5/weather?id="
|
||||
//! return a weatherData structure with current weather, if available.
|
||||
/*!
|
||||
uses weatherInterval, weatherAPIKey, weatherCity, and weatherCelsius
|
||||
*/
|
||||
weatherData Watchy::getWeatherData(){
|
||||
if(weatherIntervalCounter >= WEATHER_UPDATE_INTERVAL){ //only update if WEATHER_UPDATE_INTERVAL has elapsed i.e. 30 minutes
|
||||
String units = String("metric");
|
||||
if( weatherInit == false ) {
|
||||
// Change this to use your own API key!
|
||||
String APIkey = String("f058fe1cad2afe8e2ddc5d063a64cecb");
|
||||
// Initialise to defaults (NYC, metric, 30 minutes, SQFMI's API key)
|
||||
setupWeather( 5128581, true, 30, String("en"), APIkey );
|
||||
}
|
||||
|
||||
if(weatherIntervalCounter >= weatherInterval){ //only update if weatherInterval has elapsed i.e. 30 minutes
|
||||
if(connectWiFi()){
|
||||
RTC.syncNtpTime(); //Sync NTP
|
||||
HTTPClient http; //Use Weather API for live data if WiFi is connected
|
||||
http.setConnectTimeout(3000);//3 second max timeout
|
||||
String weatherQueryURL = String(OPENWEATHERMAP_URL) + String(CITY_NAME) + String(",") + String(COUNTRY_CODE) + String("&units=") + String(TEMP_UNIT) + String("&appid=") + String(OPENWEATHERMAP_APIKEY);
|
||||
|
||||
if( weatherCelsius == false ) {
|
||||
units = String("imperial");
|
||||
}
|
||||
String weatherQueryURL =
|
||||
String(OPENWEATHERMAP_URL) + String(weatherCity) +
|
||||
String("&units=") + String(units) +
|
||||
String("&lang=") + String(weatherLang) +
|
||||
String("&appid=") + weatherAPIKey;
|
||||
http.begin(weatherQueryURL.c_str());
|
||||
int httpResponseCode = http.GET();
|
||||
if(httpResponseCode == 200) {
|
||||
String payload = http.getString();
|
||||
JSONVar responseObject = JSON.parse(payload);
|
||||
currentWeather.temperature = int(responseObject["main"]["temp"]);
|
||||
currentWeather.weatherConditionCode = int(responseObject["weather"][0]["id"]);
|
||||
currentWeather.weatherConditionCode = int(responseObject["weather"][0]["id"]);
|
||||
currentWeather.weatherDescription = responseObject["weather"][0]["main"];
|
||||
}else{
|
||||
//http error
|
||||
// http error, so use sensor temperature
|
||||
currentWeather.temperature = getAmbientTemp();
|
||||
currentWeather.weatherConditionCode = 100;
|
||||
currentWeather.weatherDescription = String("Ambient");
|
||||
}
|
||||
http.end();
|
||||
//turn off radios
|
||||
WiFi.mode(WIFI_OFF);
|
||||
btStop();
|
||||
}else{//No WiFi, use internal temperature sensor
|
||||
uint8_t temperature = sensor.readTemperature(); //celsius
|
||||
if(strcmp(TEMP_UNIT, "imperial") == 0){
|
||||
temperature = temperature * 9. / 5. + 32.; //fahrenheit
|
||||
}
|
||||
currentWeather.temperature = temperature;
|
||||
currentWeather.weatherConditionCode = 800;
|
||||
}else{// No WiFi, so use internal temperature sensor
|
||||
currentWeather.temperature = getAmbientTemp();
|
||||
currentWeather.weatherConditionCode = 100;
|
||||
currentWeather.weatherDescription = String("Ambient");
|
||||
}
|
||||
weatherIntervalCounter = 0;
|
||||
}else{
|
||||
|
@ -590,6 +649,15 @@ weatherData Watchy::getWeatherData(){
|
|||
return currentWeather;
|
||||
}
|
||||
|
||||
//! Returns ambient temperature from sensors
|
||||
uint8_t Watchy::getAmbientTemp() {
|
||||
uint8_t temperature = sensor.readTemperature() / 4; //celsius
|
||||
if(weatherCelsius == false ){
|
||||
temperature = temperature * 9. / 5. + 32.; //fahrenheit
|
||||
}
|
||||
return temperature;
|
||||
}
|
||||
|
||||
float Watchy::getBatteryVoltage(){
|
||||
if(RTC.rtcType == DS3231){
|
||||
return analogReadMilliVolts(V10_ADC_PIN) / 1000.0f * 2.0f; // Battery voltage goes through a 1/2 divider.
|
||||
|
|
Loading…
Reference in New Issue