Skip to content

Instantly share code, notes, and snippets.

@Sennevds
Created September 4, 2019 16:20
Show Gist options
  • Save Sennevds/b2ab91e434d57a576bb9d40b4f67a40c to your computer and use it in GitHub Desktop.
Save Sennevds/b2ab91e434d57a576bb9d40b4f67a40c to your computer and use it in GitHub Desktop.
Temperature readings
#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