-
-
Save Sennevds/b2ab91e434d57a576bb9d40b4f67a40c to your computer and use it in GitHub Desktop.
Temperature readings
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <ESP8266WiFi.h> | |
#include <OneWire.h> | |
#include <DallasTemperature.h> | |
#include <PubSubClient.h> | |
extern "C" | |
{ | |
#include "user_interface.h" | |
} | |
#include "wifi.h" // #defines SSID and PASSWD | |
char ssid[] = SSID; // your network SSID (name) | |
char *pass = PASSWD; // "password" | |
const char *mqtt_server = MQTTHOST; | |
const char *mqttUser = MQTTUSER; | |
const char *mqttPassword = MQTTPASS; | |
WiFiClient espClient; | |
PubSubClient client(espClient); | |
// #define TEMP_SIZE 7 | |
#define ONE_WIRE_BUS 14 | |
OneWire oneWire(ONE_WIRE_BUS); | |
DallasTemperature sensors(&oneWire); | |
// ADC_MODE(ADC_VCC); // vcc uitlezen. | |
IPAddress staticIp = IPAddress(192, 168, 0, 240); | |
IPAddress gateway = IPAddress(192, 168, 0, 1); | |
IPAddress mask = IPAddress(255, 255, 255, 0); | |
uint8_t OutsideTemp[8] = {0x28, 0x8E, 0x7F, 0x98, 0x0A, 0x00, 0x00, 0x72}; | |
uint8_t PoolTemp[8] = {0x28, 0x47, 0xF9, 0xEE, 0x0A, 0x00, 0x00, 0x8D}; | |
const int sleepTimeS = 300; //5min | |
char chbuf[512]; | |
#define DEBUG true | |
struct | |
{ | |
uint32_t crc32; // 4 bytes | |
uint8_t channel; // 1 byte, 5 in total | |
uint8_t bssid[6]; // 6 bytes, 11 in total | |
uint8_t padding; // 1 byte, 12 in total | |
float previousPoolTemp; // 4 byte 16 | |
float previousOutsideTemp; // 4 byte 20 | |
} rtcData; | |
uint32_t calculateCRC32(const uint8_t *data, size_t length) | |
{ | |
uint32_t crc = 0xffffffff; | |
while (length--) | |
{ | |
uint8_t c = *data++; | |
for (uint32_t i = 0x80; i > 0; i >>= 1) | |
{ | |
bool bit = crc & 0x80000000; | |
if (c & i) | |
{ | |
bit = !bit; | |
} | |
crc <<= 1; | |
if (bit) | |
{ | |
crc ^= 0x04c11db7; | |
} | |
} | |
} | |
return crc; | |
} | |
// returns 0=got saved info, 1=data reset | |
bool readcfg(void) | |
{ | |
#ifdef DEBUG | |
printf("\nreadcfg\n"); | |
#endif | |
bool rtcValid = false; | |
if (ESP.rtcUserMemoryRead(65, (uint32_t *)&rtcData, sizeof(rtcData))) | |
{ | |
// Calculate the CRC of what we just read from RTC memory, but skip the first 4 bytes as that's the checksum itself. | |
#ifdef DEBUG | |
printf("memory"); | |
#endif | |
uint32_t crc = calculateCRC32(((uint8_t *)&rtcData) + 4, sizeof(rtcData) - 4); | |
if (crc == rtcData.crc32) | |
{ | |
#ifdef DEBUG | |
printf("rtcValid\n"); | |
#endif | |
rtcValid = true; | |
} | |
} | |
return rtcValid; | |
} | |
void writecfg(void) | |
{ | |
#ifdef DEBUG | |
printf("writecfg\n"); | |
#endif | |
static struct station_config conf; | |
wifi_station_get_config(&conf); | |
// save new info | |
memcpy(rtcData.bssid, WiFi.BSSID(), 6); // Copy 6 bytes of BSSID (AP's MAC address) | |
rtcData.crc32 = calculateCRC32(((uint8_t *)&rtcData) + 4, sizeof(rtcData) - 4); | |
rtcData.channel = WiFi.channel(); | |
rtcData.padding = true; | |
ESP.rtcUserMemoryWrite(65, (uint32_t *)&rtcData, sizeof(rtcData)); | |
#ifdef DEBUG | |
printf("writecfg: succes"); | |
#endif | |
} | |
float getTemperature(DeviceAddress deviceAddress) | |
{ | |
float temp = sensors.getTempC(deviceAddress); | |
#ifdef DEBUG | |
Serial.println(temp); | |
#endif | |
return temp; | |
} | |
void readSensors() | |
{ | |
sensors.requestTemperatures(); | |
float poolTemp = getTemperature(PoolTemp); | |
// char poolTemperatureCString[TEMP_SIZE]; | |
// dtostrf(poolTemp, 3, 1, poolTemperatureCString); | |
// String tempAsString = poolTemperatureCString; | |
float outsideTemp = getTemperature(OutsideTemp); | |
// char outsideTemperatureCString[TEMP_SIZE]; | |
// dtostrf(outsideTemp, 3, 1, outsideTemperatureCString); | |
// String outsidetempAsString = outsideTemperatureCString; | |
if (outsideTemp != rtcData.previousOutsideTemp || poolTemp != rtcData.previousPoolTemp) | |
{ | |
char buffer[56]; | |
sprintf(buffer, "{\"pool_temperature\": %f, \"outside_temperature\": %f }", poolTemp, outsideTemp); | |
// String totalLine = "{\"pool_temperature\":" + tempAsString + ", \"outside_temperature\":" + outsidetempAsString + " }"; | |
client.publish("custom/thing/state", buffer); | |
delay(100); | |
} | |
} | |
void setup() | |
{ | |
#ifdef DEBUG | |
Serial.begin(115200); | |
printf("\n===== Deep sleep test starting =====\n"); | |
#endif | |
bool rtcValid = readcfg(); | |
if (WiFi.getMode() != WIFI_OFF) | |
{ | |
WiFi.persistent(true); | |
WiFi.mode(WIFI_OFF); | |
} | |
delay(1); | |
WiFi.persistent(false); | |
WiFi.mode(WIFI_STA); | |
WiFi.config(IPAddress(192, 168, 0, 240), IPAddress(192, 168, 0, 1), IPAddress(255, 255, 255, 0), IPAddress(192, 168, 0, 1)); | |
if (rtcValid) | |
{ | |
WiFi.begin(ssid, pass, rtcData.channel, rtcData.bssid); | |
} | |
else | |
{ | |
WiFi.begin(ssid, pass); | |
} | |
while (WiFi.status() != WL_CONNECTED) | |
delay(1); | |
#ifdef DEBUG | |
sprintf(chbuf, "SSID %s, config is already send %i\n", ssid, rtcData.padding); | |
printf("\n%s", chbuf); | |
#endif | |
client.setServer(mqtt_server, 1883); | |
if (!client.connect("temperature_readings", mqttUser, mqttPassword)) | |
{ | |
#ifdef DEBUG | |
printf("*** mqtt.connect failed err:%d\n", client.state()); | |
#endif | |
ESP.deepSleepInstant(sleepTimeS * 1000000, WAKE_NO_RFCAL); // Sleep 60 seconds | |
} | |
char buf[512]; | |
#ifdef DEBUG | |
sprintf(buf, "rtcvalid: %i, config is already send: %i\n", rtcValid, rtcData.padding); | |
printf(buf); | |
#endif | |
if (!rtcData.padding) | |
{ | |
#ifdef DEBUG | |
printf("send config"); | |
#endif | |
String payload = "{\"device_class\": \"temperature\", \"name\": \"Pool Temperature\", \"state_topic\": \"custom/thing/state\", \"unit_of_measurement\": \"°C\", \"value_template\": \"{{ value_json.pool_temperature}}\", \"unique_id\": \"pool_sensors_pooltemp\", \"device\": { \"identifiers\": [\"pool_sensors\"], \"name\": \"Thing\", \"model\": \"Sparkfun Thing\", \"manufacturer\": \"Sparkfun\"} }"; | |
String payload2 = "{\"device_class\": \"temperature\", \"name\": \"Outside Temperature\", \"state_topic\": \"custom/thing/state\", \"unit_of_measurement\": \"°C\", \"value_template\": \"{{ value_json.outside_temperature}}\", \"unique_id\": \"pool_sensors_outsidetemp\", \"device\": { \"identifiers\": [\"pool_sensors\"], \"name\": \"Thing\", \"model\": \"Sparkfun Thing\", \"manufacturer\": \"Sparkfun\"} }"; | |
//String payload3 = "{\"device_class\": \"battery\", \"name\": \"Battery percentage\", \"state_topic\": \"homeassistant/sensor/thing/state\", \"unit_of_measurement\": \"%\", \"value_template\": \"{{ value_json.battery_percentage}}\" }"; | |
client.publish("homeassistant/sensor/poolTempSensor/config", payload.c_str(), true); | |
client.publish("homeassistant/sensor/outsideTempSensor/config", payload2.c_str(), true); | |
} | |
sensors.begin(); | |
//client.publish("homeassistant/sensor/batter_percentage/config", payload3.c_str()); | |
} | |
void loop() | |
{ | |
client.loop(); | |
writecfg(); | |
readSensors(); | |
writecfg(); | |
#ifdef DEBUG | |
printf("deepsleep\n"); | |
#endif | |
delay(100); | |
ESP.deepSleepInstant(sleepTimeS * 1000000, WAKE_NO_RFCAL); // Sleep 60 seconds | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment