#include "../library/common.h"
#include "../library/station.h"
#define ThermMemorySpaceSector 0x50
#define ThermMemorySpace 0x50000
#define DHT_MAXCOUNT 32000
#define DHT_NO_PIN -1
#define DHT_PACKET_SIZE 5
///NOTE: The call back points to a Global Structure named GlobalReading, This structure can / may change by the time user code executes. It may be best to copy the variable staticly.
typedef void (*DHTFunctionCallback)(struct sensor_GlobalReading * MyReading);
DHTFunctionCallback DHTCallBack;
int DHT_PIN = 0;
LOCAL struct espconn TCPOutGoingespconn; //This sends outgoing get request
static volatile os_timer_t CheckIPAndSend_timer;
enum sensor_type MySensor;
enum sensor_type
{
MySensor_DHT11,MySensor_DHT22
};
struct __attribute__((__packed__)) ThermostatStruct{
int programmed;
enum sensor_type ThermostatType;
int GPIO;
int PowerMethod;
BOOL PollingEnabled;
int Polling;
BOOL SendOnInit;
BOOL SendOnInitOnlyIf;
int tempatureDegrees;
BOOL classification;
BOOL DeepSleepAfterSend;
int DeepSleepTime;
BOOL Enabled;
char Reserved[14]; //This fixes the 4 Byte Allignment in SPI Flash Read, 44bytes
};
struct ThermostatStruct ThermostatConfig;
struct sensor_GlobalReading{
float temperature;
float humidity;
const char* source;
uint8_t sensor_id[16];
BOOL success;
};
void ICACHE_FLASH_ATTR DHT(void);
//struct sensor_GlobalReading * ICACHE_FLASH_ATTR readDHT(int force);
void DHTInit(enum sensor_type LMySensor, uint32_t GPIOPin, bool enablepolling, uint32_t polltime);
static inline float scale_humidity(int *data) {
if (MySensor == MySensor_DHT11) {
return data[0];
} else {
float humidity = data[0] * 256 + data[1];
return humidity /= 10;
}
}
static inline float scale_temperature(int *data)
{
if (MySensor == MySensor_DHT11)
{
os_printf("MySensor DHT11");
return data[2];
}
else
{
os_printf("MySensor DHT22");
float temperature = data[2] & 0x7f;
temperature *= 256;
temperature += data[3];
temperature /= 10;
if (data[2] & 0x80)
temperature *= -1;
return temperature;
}
}
struct sensor_GlobalReading GlobalReading = {
.source = "DHT11", .success = 0
};
void ICACHE_FLASH_ATTR renderHTTPThermostatrequest(char * Request)
{
decodeHTML(Request);
if (os_strlen(Request) > 127)
{
os_printf("Returning - GET VAR IS TOO BIG: %s\r\n", Request);
return;
}
char HTTPGETSPLIT[128];
os_memset(HTTPGETSPLIT, 0, 128);
os_memcpy(&HTTPGETSPLIT, Request, os_strlen(Request));
os_printf("Before Split: %s\r\n", HTTPGETSPLIT);
char * Key = strstr(HTTPGETSPLIT, "=");
if(Key == NULL)
{
os_printf("Returning - Not a valid Split: %s\r\n", HTTPGETSPLIT);
return;
}
*Key = 0x0;
char * Value = Key + 1;
Key = HTTPGETSPLIT;
os_printf("Key: %s\r\nValue: %s\r\n", Key, Value);
os_printf("renderHTTPThermostatrequest Key: %s\r\nValue: %s\r\n", Key, Value);
if (strcmp(Key, "Thermostat") == 0)
{
//os_strcpy(newconfig.ssid, Value);
if (strcmp(Value, "DHT11") == 0)
{
os_printf("Setting to DHT11");
ThermostatConfig.ThermostatType = MySensor_DHT11;
}
else
{
os_printf("Setting to DHT22");
ThermostatConfig.ThermostatType = MySensor_DHT22;
}
os_printf("Thermastat Set to: ", Value);
return;
}
else if (strcmp(Key, "GPIO") == 0)
{
ThermostatConfig.GPIO = atoi(Value);
os_printf("GPIO set to %s - %d", Value, atoi(Value));
}
else if (strcmp(Key, "PowerMethod") == 0)
{
ThermostatConfig.PowerMethod = atoi(Value);
}
else if (strcmp(Key, "pollingEnabled") == 0)
{
if (strcmp(Value, "true") == 0)
{
ThermostatConfig.PollingEnabled = true;
}
else
{
ThermostatConfig.PollingEnabled = false;
}
}
else if (strcmp(Key, "POLLING") == 0)
{
ThermostatConfig.Polling = atoi(Value);
os_printf("Polling set to %s - %d", Value, atoi(Value));
}
else if (strcmp(Key, "SendOnInit") == 0)
{
if (strcmp(Value, "true") == 0)
{
ThermostatConfig.SendOnInit = true;
}
else
{
ThermostatConfig.SendOnInit = false;
}
}
else if (strcmp(Key, "SendOnInitOnlyIf") == 0)
{
if (strcmp(Value, "true") == 0)
{
ThermostatConfig.SendOnInitOnlyIf = true;
}
else
{
ThermostatConfig.SendOnInitOnlyIf = false;
}
}
else if (strcmp(Key, "tempatureDegrees") == 0)
{
ThermostatConfig.tempatureDegrees = atoi(Value);
}
else if (strcmp(Key, "classification") == 0)
{
if (strcmp(Value, "warmer") == 0)
{
ThermostatConfig.classification = true;
}
else if (strcmp(Value, "colder") == 0)
{
ThermostatConfig.classification = false;
}
}
else if (strcmp(Key, "DeepSleepAfterPoll") == 0)
{
if (strcmp(Value, "true") == 0)
{
ThermostatConfig.DeepSleepAfterSend = true;
}
else if (strcmp(Value, "false") == 0)
{
ThermostatConfig.DeepSleepAfterSend = false;
}
}
else if (strcmp(Key, "DeepSleepTime") == 0)
{
ThermostatConfig.DeepSleepTime = atoi(Value);
}
else if (strcmp(Key, "enabled") == 0)
{
if (strcmp(Value, "true") == 0)
{
ThermostatConfig.Enabled = true;
}
else
{
ThermostatConfig.Enabled = false;
}
//os_printf("ssid: \"%s\"\npw: \"%s\"\nProgrammed: %d\r\n",newconfig.ssid,newconfig.password,newconfig.programmed);
ThermostatConfig.programmed = 1;
//os_printf("Writing ThermConfig at %02x\r\n", (WifiMemorySpace+sizeof(APFlashStationConf)+sizeof(newconfig)));
spi_flash_erase_sector(ThermMemorySpaceSector);
SpiFlashOpResult writeResult = spi_flash_write(ThermMemorySpace, (uint32 *)&ThermostatConfig, sizeof(ThermostatConfig));
if (writeResult == SPI_FLASH_RESULT_OK)
{
/*
ThermostatConfig.programmed = 0;
SpiFlashOpResult ReadResult = spi_flash_read(0x50000,(uint32 *)&ThermostatConfig,sizeof(ThermostatConfig));
if (ReadResult == SPI_FLASH_RESULT_OK)
{
os_printf("Therm SPI Read SPI_FLASH_RESULT_OK\r\n");
if(ThermostatConfig.programmed == 1)
{
os_printf("\r\nSaved ThermostatConfig Information Found!!\r\nThermostatType: \"%d\"\nGPIO: \"%d\"\r\n", ThermostatConfig.ThermostatType, ThermostatConfig.GPIO);
if(ThermostatConfig.Enabled == true)
{
os_printf("Thermostat Enabled - Starting Polling at %d\r\n", ThermostatConfig.Polling);
DHTInit(MySensor_DHT11, ThermostatConfig.PollingEnabled, ThermostatConfig.Polling * 1000); //1000 = 1 Sec
}
}
}
*/
os_printf("ThermSettings SavedSystem is rebooting...");
//os_delay_us(100000);
os_printf("now...");
system_restart();
}
else if(writeResult == SPI_FLASH_RESULT_ERR)
{
os_printf("ThermSettings SPI_FLASH_RESULT_ERR...");
}
else if(writeResult == SPI_FLASH_RESULT_TIMEOUT)
{
os_printf("ThermSettings SPI_FLASH_RESULT_TIMEOUT...");
}
return;
}
else /* default: */
{
os_printf("No valid request Handler for - %s\r\n", Request); //Output last variable
/*
int i;
for(i = 0; i < 10; i++) {
os_printf("0x%02X ", Request[i]);
}
*/
}
}
LOCAL bool ICACHE_FLASH_ATTR pollDHTCb()
{
//Something is going on with Powermethod on GPIO15?
os_printf("pollDHTCb()");
if (ThermostatConfig.PowerMethod > 0)
{
os_printf("Turning on power to the DHT - Pin%d\r\n", ThermostatConfig.PowerMethod);
PIN_FUNC_SELECT(g_pin_muxes[ThermostatConfig.PowerMethod], g_pin_funcs[ThermostatConfig.PowerMethod]);
gpio_output_set((1 << ThermostatConfig.PowerMethod), 0, 0, 0); //Turn on power to the DHT
}
if(ThermostatConfig.programmed != 1)
{
os_printf("pollDHTCb, not programmed\r\n");
return false;
}
int counter = 0;
int laststate = 1;
int i = 0;
int bits_in = 0;
int data[100];
data[0] = data[1] = data[2] = data[3] = data[4] = 0;
//disable interrupts, start of critical section
//os_intr_lock();
wdt_feed();
// Wake up device, 250ms of high
GPIO_OUTPUT_SET(DHT_PIN, 1);
delay_ms(250);
// Hold low for 20ms
GPIO_OUTPUT_SET(DHT_PIN, 0);
delay_ms(20);
// High for 40us
GPIO_OUTPUT_SET(DHT_PIN, 1);
os_delay_us(40);
GPIO_DIS_OUTPUT(DHT_PIN);
i=0;
while (GPIO_INPUT_GET(DHT_PIN) == 1)
{
os_delay_us(3);
if (i >= DHT_MAXCOUNT)
{
goto fail;
}
i++;
}
i=0;
while (GPIO_INPUT_GET(DHT_PIN) == 0)
{
os_delay_us(3);
if (i >= DHT_MAXCOUNT)
{
goto fail;
}
i++;
}
counter = 0;
while (counter < 40)
{
i=0;
while (GPIO_INPUT_GET(DHT_PIN) == 1)
{
os_delay_us(3);
if (i >= DHT_MAXCOUNT)
{
goto fail;
}
i++;
}
i=0;
while (GPIO_INPUT_GET(DHT_PIN) == 0)
{
os_delay_us(3);
if (i >= DHT_MAXCOUNT)
{
goto fail;
}
i++;
}
os_delay_us(47);
data[bits_in / 8] <<= 1;
if (GPIO_INPUT_GET(DHT_PIN) == 1)
{
data[bits_in / 8] |= 1;
//os_printf("\r\nONE %d", counter);
}
else
{
//os_printf("\r\nZERO %d", counter);
}
bits_in++;
counter++;
}
//Re-enable interrupts, end of critical section
//os_intr_unlock();
if (ThermostatConfig.PowerMethod > 0)
{
os_printf("Turning off power to DHT\r\n");
gpio_output_set(0, (1 << ThermostatConfig.PowerMethod), 0, 0); //Turn off power to the DHT
}
if (bits_in < 40) {
os_printf("Got too few bits: %d should be at least 40\r\n", bits_in);
goto fail;
}
int checksum = (data[0] + data[1] + data[2] + data[3]) & 0xFF;
//os_printf("DHT: %02x %02x %02x %02x [%02x] CS: %02x", data[0], data[1],data[2],data[3],data[4],checksum);
if (data[4] != checksum)
{
os_printf("Checksum was incorrect after %d bits. Expected %d but got %d\r\n", bits_in, data[4], checksum);
goto fail;
}
GlobalReading.temperature = scale_temperature(data);
GlobalReading.humidity = scale_humidity(data);
os_printf("Temp = %d *F, Hum = %d %%\n", (int)(GlobalReading.temperature * 1.8 + 32), (int)(GlobalReading.humidity));
GlobalReading.success = 1;
DHTCallBack(&GlobalReading); //Invoke Callback
return true;
fail:
os_printf("Failed to get GlobalReading, dying\n");
GlobalReading.success = 0;
if (ThermostatConfig.PowerMethod > 0)
{
os_printf("Turning off power to DHT\r\n");
gpio_output_set(0, (1 << ThermostatConfig.PowerMethod), 0, 0); //Turn off power to the DHT
}
return false;
}
LOCAL bool ICACHE_FLASH_ATTR pollDHT()
{
if(ThermostatConfig.programmed != 1)
{
os_printf("Polling DHT, not programmed\r\n");
return false;
}
os_printf("Polling DHT\r\n");
if (pollDHTCb()) //Get Tempature from DHT
{
int TempInF = (int)(GlobalReading.temperature * 1.8 + 32);
if (ThermostatConfig.SendOnInitOnlyIf)
{
if(ThermostatConfig.classification)
{
if (TempInF > ThermostatConfig.tempatureDegrees) //Warmer
{
os_printf("Warmer: TempInF > ThermostatConfig.tempatureDegrees\r\n");
//Turn On LED
DHTCallBack(&GlobalReading);
PIN_FUNC_SELECT(PERIPHS_IO_MUX_GPIO2_U, FUNC_GPIO2);
gpio_output_set(0, (1 << 2), 0, 0);
}
else
{
//Turn OFF LED
PIN_FUNC_SELECT(PERIPHS_IO_MUX_GPIO2_U, FUNC_GPIO2);
gpio_output_set((1 << 2), 0, 0, 0);
}
}
else if(ThermostatConfig.classification) //Colder
{
if (TempInF < ThermostatConfig.tempatureDegrees)
{
os_printf("Colder: TempInF < ThermostatConfig.tempatureDegrees\r\n");
//Turn On LED
DHTCallBack(&GlobalReading);
PIN_FUNC_SELECT(PERIPHS_IO_MUX_GPIO2_U, FUNC_GPIO2);
gpio_output_set(0, (1 << 2), 0, 0);
}
else
{
//Turn OFF LED
PIN_FUNC_SELECT(PERIPHS_IO_MUX_GPIO2_U, FUNC_GPIO2);
gpio_output_set((1 << 2), 0, 0, 0);
}
}
}
else
{
os_printf("Sending on Poll\r\n");
}
}
}
void DHTInit(enum sensor_type LMySensor, uint32_t GPIOPin, bool enablepolling, uint32_t polltime)
{
os_printf("[%s]\r\n", __func__);
MySensor = LMySensor;
//PIN_FUNC_SELECT(PERIPHS_IO_MUX_GPIO0_U, FUNC_GPIO0);
//PIN_PULLUP_EN(PERIPHS_IO_MUX_GPIO0_U);
PIN_FUNC_SELECT(g_pin_muxes[GPIOPin], g_pin_funcs[GPIOPin]);
PIN_PULLUP_EN(g_pin_muxes[GPIOPin]);
DHT_PIN = GPIOPin;
if (enablepolling)
{
os_printf("DHT Setup for type %d, poll interval of %d using GPIO %d, Starting Timer...\r\n", LMySensor, (int)polltime, GPIOPin);
static ETSTimer dhtTimer;
os_timer_setfn(&dhtTimer, pollDHT, NULL);
os_timer_arm(&dhtTimer, polltime, 1);
}
else
{
os_printf("DHT Setup for type %d using GPIO %d\n", LMySensor, GPIOPin);
}
}
char * DOMAIN = "controllingTheInter.net";
bool sentAlert=false;
//char requestText[128];
// int TempInF = (int)(GlobalReading.temperature * 1.8 + 32);
// int humidity = (int)GlobalReading.humidity;
// os_sprintf(requestText,"GET /esp8266.php?ssid=myssid&IP=MyIp&ID=MyId /HTTP/1.1\r\nUser-Agent: F%dH%d\r\nHost: %s\r\nAccept: */*\r\n\r\n", TempInF, humidity, DOMAIN);
// os_printf("Sending: %s", requestText);
// espconn_send(conn,requestText,128);
// sentAlert=true;
//Add code to support new sockets sending data.
void ICACHE_FLASH_ATTR LoadStationAndSendData(struct sensor_GlobalReading MyReading)
{
init_station(NULL, NULL, NULL);
//LoadAccessPoint();
//os_timer_setfn(&CheckIPAndSend_timer, (os_timer_func_t *)network_check_ip_send_therm, (void *)&MyReading);
//os_timer_arm(&CheckIPAndSend_timer, 1000, 1);
}
SpiFlashOpResult ICACHE_FLASH_ATTR Set_ThermostatSettings(enum sensor_type LThermostatType, int LGPIO, int LPowerMethod, bool LPollingEnabled, int LPolling, bool LSendOnInit, bool LSendOnInitOnlyIf, int LtempatureDegrees, char * LClassification, bool LDeepSleepAfterSend, int LDeepSleepTime, int LEnabled, char * LReserved)
{
os_printf("[%s]\r\n", __func__);
ThermostatConfig.ThermostatType = LThermostatType;
DHT_PIN = LGPIO;
ThermostatConfig.GPIO = LGPIO;
ThermostatConfig.PowerMethod = LPowerMethod;
ThermostatConfig.PollingEnabled = LPollingEnabled;
ThermostatConfig.Polling = LPolling;
ThermostatConfig.SendOnInit = LSendOnInit;
ThermostatConfig.SendOnInitOnlyIf = LSendOnInitOnlyIf;
ThermostatConfig.tempatureDegrees = LtempatureDegrees;
if (LClassification != NULL)
{
if (strcmp(LClassification, "warmer") == 0)
{
ThermostatConfig.classification = true;
}
else if (strcmp(LClassification, "colder") == 0)
{
ThermostatConfig.classification = false;
}
}
ThermostatConfig.DeepSleepAfterSend = LDeepSleepAfterSend;
ThermostatConfig.DeepSleepTime = LDeepSleepTime;
ThermostatConfig.Enabled = LEnabled;
ThermostatConfig.programmed = 1;
//os_printf("Writing ThermConfig at %02x\r\n", (WifiMemorySpace+sizeof(APFlashStationConf)+sizeof(newconfig)));
spi_flash_erase_sector(ThermMemorySpaceSector);
SpiFlashOpResult writeResult = spi_flash_write(ThermMemorySpace, (uint32 *)&ThermostatConfig, sizeof(ThermostatConfig));
if (writeResult == SPI_FLASH_RESULT_OK)
{
//os_printf("ThermSettings SavedSystem is rebooting...");
//os_delay_us(100000);
//os_printf("now...");
//system_restart();
}
else if(writeResult == SPI_FLASH_RESULT_ERR)
{
os_printf("ThermSettings SPI_FLASH_RESULT_ERR...");
}
else if(writeResult == SPI_FLASH_RESULT_TIMEOUT)
{
os_printf("ThermSettings SPI_FLASH_RESULT_TIMEOUT...");
}
return writeResult;
}
void ICACHE_FLASH_ATTR init_ThermostatSettings(void * LDHTCallBack(struct sensor_GlobalReading MyReading))
{
os_printf("[%s]\r\n", __func__);
//os_printf("GlobalReading ThermConfig at %02x\r\n", (WifiMemorySpace+sizeof(FlashStationConf)+sizeof(APFlashStationConf)));
//SpiFlashOpResult ReadResult = spi_flash_read(WifiMemorySpace+sizeof(FlashStationConf)+sizeof(APFlashStationConf),(uint32 *)&ThermostatConfig,sizeof(ThermostatConfig));
SpiFlashOpResult ReadResult = spi_flash_read(ThermMemorySpace,(uint32 *)&ThermostatConfig,sizeof(ThermostatConfig));
if (ReadResult == SPI_FLASH_RESULT_OK)
{
os_printf("Therm SPI Read SPI_FLASH_RESULT_OK\r\n");
if(ThermostatConfig.programmed == 1)
{
os_printf("Saved ThermostatConfig Information Found!!\r\nThermostatType: \"%d\"\nGPIO: \"%d\"\r\nTempature: \"%d\"\r\n", ThermostatConfig.ThermostatType, ThermostatConfig.GPIO, ThermostatConfig.tempatureDegrees);
if(ThermostatConfig.Enabled == true)
{
if (LDHTCallBack != NULL)
{
DHTCallBack = LDHTCallBack;
}
os_printf("Thermostat Enabled - Starting Polling at %d\r\n", ThermostatConfig.Polling);
DHTInit(ThermostatConfig.ThermostatType, ThermostatConfig.GPIO, ThermostatConfig.PollingEnabled, ThermostatConfig.Polling * 1000 * 60); //1000 = 1 Sec
if (ThermostatConfig.SendOnInit)
{
if (pollDHTCb()) //This gets the raw value
{//This part may be able to be turned into a function
int TempInF = (int)(GlobalReading.temperature * 1.8 + 32);
if (ThermostatConfig.SendOnInitOnlyIf)
{
if(ThermostatConfig.classification)
{
if (TempInF > ThermostatConfig.tempatureDegrees) //Warmer
{
os_printf("Warmer: TempInF > ThermostatConfig.tempatureDegrees\r\n");
//wifi_set_opmode(STATION_MODE);
//LoadStation();
DHTCallBack(&GlobalReading);
//Turn On LED
PIN_FUNC_SELECT(PERIPHS_IO_MUX_GPIO2_U, FUNC_GPIO2);
gpio_output_set(0, (1 << 2), 0, 0);
}
}
else if(ThermostatConfig.classification) //Colder
{
if (TempInF < ThermostatConfig.tempatureDegrees)
{
os_printf("Colder: TempInF < ThermostatConfig.tempatureDegrees\r\n");
DHTCallBack(&GlobalReading);
//Turn On LED
PIN_FUNC_SELECT(PERIPHS_IO_MUX_GPIO2_U, FUNC_GPIO2);
gpio_output_set(0, (1 << 2), 0, 0);
//wifi_set_opmode(STATION_MODE);
//LoadStation();
}
}
}
else
{
//wifi_set_opmode(STATION_MODE);
//LoadStation();
}
if(ThermostatConfig.DeepSleepAfterSend && false)
{
//SET_PERI_REG_MASK(UART_CONF0(0), UART_TXFIFO_RST);//RESET FIFO
//CLEAR_PERI_REG_MASK(UART_CONF0(0), UART_TXFIFO_RST);
os_printf("Going to sleep for %d\r\n", ThermostatConfig.DeepSleepTime);
deep_sleep_set_option(2);
system_deep_sleep(ThermostatConfig.DeepSleepTime * 60000 * 1000); //UC to Minutes
}
}
}
}
}
else
{
os_printf("\r\nNo ThermostatConfig Information Found!!\r\n");
}
}
else if(ReadResult == SPI_FLASH_RESULT_ERR)
{
os_printf("SPI_FLASH_RESULT_ERR");
}
else if(ReadResult == SPI_FLASH_RESULT_TIMEOUT)
{
os_printf("SPI_FLASH_RESULT_TIMEOUT");
}
//os_printf("SizeOf(ThermostatConfig) = %d\r\n", sizeof(ThermostatConfig));
}
#endif