#include <string>
#include <Wire.h>
#include "SSD1306.h"
#include "DHTesp.h"
#include "BLEDevice.h"
#include "GeneralUtils.h"
static BLEUUID thermo_service_uuid("11111111-2222-3333-4444-000000000000");
static BLEUUID thermo_temp_uuid("11111111-2222-3333-4444-000000000001");
static BLEUUID thermo_time_uuid("11111111-2222-3333-4444-000000000002");
#define DEFAULT_SLEEP_TIME 60
#define uS_TO_S_FACTOR 1000000
SSD1306 display(0x3c, 5, 4);
DHTesp dht;
void show(String x) {
display.clear();
display.drawString(0,0,x);
display.display();
}
class MyAdvertisedDeviceCallbacks: public BLEAdvertisedDeviceCallbacks {
public:
BLEAddress* pServerAddress;
MyAdvertisedDeviceCallbacks() :
BLEAdvertisedDeviceCallbacks(),
pServerAddress(0)
{}
void onResult(BLEAdvertisedDevice advertisedDevice) {
String results = "Found: \n";
results += String(advertisedDevice.getAddress().toString().c_str());
show(results);
if (advertisedDevice.haveName() && advertisedDevice.getName() == "termostore") {
advertisedDevice.getScan()->stop();
pServerAddress = new BLEAddress(advertisedDevice.getAddress());
}
}
};
bool read_sensor(float* humidity, float* temperature) {
dht.setup(13,DHTesp::DHT11);
int tries=0;
while (++tries<10) {
delay(dht.getMinimumSamplingPeriod());
*humidity = dht.getHumidity();
*temperature = dht.getTemperature();
String data = "";
data += *humidity;
data += " ";
data += *temperature;
data += " ";
data += dht.getStatusString();
show(data);
if (dht.getStatus() != DHTesp::ERROR_TIMEOUT) return true;
}
return false;
}
uint32_t send_data_and_get_time(BLEAddress* pAddress,String* data) {
BLEClient* pClient = BLEDevice::createClient();
show("Sc");
esp_err_t err;
bool ok = pClient->connect(*pAddress,&err);
if (!ok) {
String status="";
status += GeneralUtils::errorToString(err);
show(status);
return 10;
}
String status = "SC";
status += pClient->getPeerAddress().toString().c_str();
show(status);
try {
BLERemoteService* pThermoService = pClient->getService(thermo_service_uuid);
if (!pThermoService) {
show("NO SERVICE");
return 60;
}
BLERemoteCharacteristic* pTemp = pThermoService->getCharacteristic(thermo_temp_uuid);
if (!pTemp) {
show("NO TEMP CHAR");
return 60;
}
show("SCw");
pTemp->writeValue(data->c_str(),data->length());
show("SCWr");
BLERemoteCharacteristic* pTime = pThermoService->getCharacteristic(thermo_time_uuid);
if (!pTime) {
show("NO TIME CHAR");
return 60;
}
std::string next_time = pTime->readValue();
show("SCWRd");
pClient->disconnect();
show("SCWRD");
return String(next_time.c_str()).toInt();
}
catch (...) {
show("Fail");
pClient->disconnect();
return 10;
}
}
void setup() {
display.init();
display.connect();
BLEDevice::init("");
}
void loop() {
display.displayOn();
display.clear();
BLEScan* pBLEScan = BLEDevice::getScan();
MyAdvertisedDeviceCallbacks* cb = new MyAdvertisedDeviceCallbacks();
pBLEScan->setAdvertisedDeviceCallbacks(cb);
pBLEScan->setActiveScan(true);
show("s");
BLEScanResults foundDevices = pBLEScan->start(30);
if (cb->pServerAddress) {
show("S");
float humidity, temperature;
bool ok = read_sensor(&humidity,&temperature);
int next_time;
if (ok) {
String data = String(BLEDevice::getAddress().toString().c_str()) + " " + String(humidity) + " " + String(temperature) + "\n";
show(data);
next_time = send_data_and_get_time(cb->pServerAddress,&data);
}
else {
show("no thermo");
next_time=10;
}
String nt = "Next time:";nt+=next_time;
display.drawString(0,20,nt);display.display();
delay(2000);
esp_sleep_enable_timer_wakeup(next_time * uS_TO_S_FACTOR);
}
else {
display.drawString(0,0,"s!");display.display();
String nt = "Next time:";nt+=DEFAULT_SLEEP_TIME;
display.drawString(0,20,nt);display.display();
delay(2000);
esp_sleep_enable_timer_wakeup(DEFAULT_SLEEP_TIME * uS_TO_S_FACTOR);
}
esp_deep_sleep_start();
}