summaryrefslogtreecommitdiff
path: root/sensor/thermostat.ino
blob: 20496bc7bdd32b3ab6120ea1f384eb694eacac6d (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
#include <string>
#include <Wire.h>  
#include "DHTesp.h"
#include <esp_bt.h>
#include "BLEDevice.h"
#include "Ticker.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 NO_SERVER_SLEEP_TIME 60
#define ON_ERROR_SLEEP_TIME 30
#define WATCHDOG_SECONDS 30
/* Conversion factor for micro seconds to seconds */
#define uS_TO_S_FACTOR 1000000
 
#define BLE_POWER ESP_PWR_LVL_P7
// #define BLE_POWER ESP_PWR_LVL_N14 
 
DHTesp dht;
 
class MyAdvertisedDeviceCallbackspublic BLEAdvertisedDeviceCallbacks {
 public:
  BLEAddress* pServerAddress;
 
 MyAdvertisedDeviceCallbacks() :
  BLEAdvertisedDeviceCallbacks(),
    pServerAddress(0)
      {}
 
  ~MyAdvertisedDeviceCallbacks() { if (pServerAddress) delete pServerAddress; }
  
  void onResult(BLEAdvertisedDevice advertisedDevice) {
    // We have found a device, let us now see if it contains the service we are looking for. 
    if (advertisedDevice.haveName() && advertisedDevice.getName() == "termostore"{
      advertisedDevice.getScan()->stop();
 
      pServerAddress = new BLEAddress(advertisedDevice.getAddress());
 
    } // Found our server 
  } // onResult 
}// MyAdvertisedDeviceCallbacks 
 
void enable_sensor(bool enable) {
  pinMode(12,OUTPUT);
  digitalWrite(12,enable ? HIGH : LOW);
  delay(500);
}
 
bool read_sensor(float* humidity, float* temperature) {
  dht.setup(13,DHTesp::DHT11);
 
  int tries=0;bool ret=false;
  while (!ret && ++tries<10{
    delay(dht.getMinimumSamplingPeriod());
    *humidity = dht.getHumidity();
    *temperature = dht.getTemperature();
 
    if (dht.getStatus() != DHTesp::ERROR_TIMEOUT) ret = true;
  }
  return ret;
}
 
uint32_t send_data_and_get_time(BLEAddress* pAddress,String* data) {
  BLEClient* pClient  = BLEDevice::createClient();
  bool ok = pClient->connect(*pAddress);
  if (!ok) {
    return ON_ERROR_SLEEP_TIME;
  }
  try {
    BLERemoteService* pThermoService = pClient->getService(thermo_service_uuid);
    if (!pThermoService) {
      return 60;
    }
    BLERemoteCharacteristic* pTemp = pThermoService->getCharacteristic(thermo_temp_uuid);
    if (!pTemp) {
      return 60;
    }
    pTemp->writeValue(data->c_str(),data->length());
    BLERemoteCharacteristic* pTime = pThermoService->getCharacteristic(thermo_time_uuid);
    if (!pTime) {
      return 60;
    }
    std::string next_time = pTime->readValue();
    pClient->disconnect();
    return String(next_time.c_str()).toInt();
  }
  catch (...) {
    pClient->disconnect();
    return ON_ERROR_SLEEP_TIME;
  }
}
 
void setup() {
  BLEDevice::init("");
  esp_ble_tx_power_set(ESP_BLE_PWR_TYPE_ADV, BLE_POWER);
  esp_ble_tx_power_set(ESP_BLE_PWR_TYPE_SCAN, BLE_POWER);
  esp_ble_tx_power_set(ESP_BLE_PWR_TYPE_DEFAULT, BLE_POWER);
  enable_sensor(true);
}
 
void teardown_and_sleep(int next_time) {
  enable_sensor(false);
  BLEDevice::uninit();
  //esp_wifi_stop(); 
  delay(2000);
  esp_sleep_enable_timer_wakeup(next_time * uS_TO_S_FACTOR);
  esp_deep_sleep_start();
}
 
void watchdog_cb() {
  teardown_and_sleep(ON_ERROR_SLEEP_TIME);
}
 
void loop() {
  Ticker watchdog_timer;
  watchdog_timer.attach(WATCHDOG_SECONDS,watchdog_cb);
 
  BLEScan* pBLEScan = BLEDevice::getScan();
  MyAdvertisedDeviceCallbacks* cb = new MyAdvertisedDeviceCallbacks();
  pBLEScan->setAdvertisedDeviceCallbacks(cb);
  pBLEScan->setActiveScan(true);
  BLEScanResults foundDevices = pBLEScan->start(30);
  int next_time;
 
  if (cb->pServerAddress) {
 
    float humidity, temperature;
    bool ok = read_sensor(&humidity,&temperature);
    if (ok) {
      String data = String(BLEDevice::getAddress().toString().c_str()) + " "
        + String(humidity) + " "
        + String(temperature) + " "
        + String(batteryLevel) + "\n";
      next_time = send_data_and_get_time(cb->pServerAddress,&data);
    }
    else {
      next_time=ON_ERROR_SLEEP_TIME;
    }
  }
  else {
    next_time = NO_SERVER_SLEEP_TIME;
  }
 
  delete cb;
 
  teardown_and_sleep(next_time);
 
  delay(2000);
}