Code: Select all
/*
Copyright (C) AC SOFTWARE SP. Z O.O.
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#define STATUS_LED_GPIO 2
#define BUTTON_CFG_RELAY_GPIO 0
#include <sstream>
#include <BLEDevice.h>
#include <BLEScan.h>
#include <BLEAdvertisedDevice.h>
#include <SuplaDevice.h>
#include <supla/network/esp_wifi.h>
#include <supla/control/button.h>
#include <supla/control/action_trigger.h>
#include <supla/device/status_led.h>
#include <supla/storage/littlefs_config.h>
#include <supla/network/esp_web_server.h>
#include <supla/network/html/device_info.h>
#include <supla/network/html/protocol_parameters.h>
#include <supla/network/html/status_led_parameters.h>
#include <supla/network/html/wifi_parameters.h>
#include <supla/device/supla_ca_cert.h>
#include <supla/sensor/therm_hygro_meter.h>
#include <supla/sensor/thermometer.h>
#define SCAN_TIME 5 // seconds
int od1 = 0;
int od2 = 0;
int od3 = 0;
int wilg1 = -1;
float temp1 = -275;
int wilg2 = -1;
float temp2 = -275;
int wilg3 = -1;
float temp3 = -275;
float bat1 = 0;
float bat2 = 0;
float bat3 = 0;
unsigned long czas_pomiedzy_skanowaniem;
unsigned long wifimilis;
unsigned long lastReadTime = 0;
boolean METRIC = true; //Set true for metric system; false for imperial
String text01;
String text02;
String text03;
String text04;
String text05;
String text06;
String text07;
String text08;
String text09;
String text10;
String text11;
String text12;
String text13;
String text14;
String text15;
String zmienna;
String MAC_ADR;
byte BLE_DEVICE;
bool wyswietl = 0;
//#define XIAOMI_BLE_DEVICE_1_MAC "A4:C1:38:0D:AE:08"
//#define XIAOMI_BLE_DEVICE_2_MAC "A4:C1:38:10:3D:44"
//#define XIAOMI_BLE_DEVICE_3_MAC "A4:C1:38:43:6A:FE"
#define XIAOMI_BLE_DEVICE_1_MAC "A4:C1:38:AF:35:85"
#define XIAOMI_BLE_DEVICE_2_MAC "A4:C1:38:FA:F0:FB"
#define XIAOMI_BLE_DEVICE_3_MAC "A4:C1:38:E3:84:F4"
//#include <supla/storage/eeprom.h>
//Supla::Eeprom eeprom;
Supla::ESPWifi wifi;
Supla::LittleFsConfig configSupla;
Supla::Device::StatusLed statusLed(STATUS_LED_GPIO, true); // inverted state
Supla::EspWebServer suplaServer;
//wifi.setSSLEnabled(false);
Supla::Html::DeviceInfo htmlDeviceInfo(&SuplaDevice);
Supla::Html::WifiParameters htmlWifi;
Supla::Html::ProtocolParameters htmlProto;
Supla::Html::StatusLedParameters htmlStatusLed;
int current_humidity;
int current_batt;
word val;
BLEScan *pBLEScan;
void IRAM_ATTR resetModule(){
ets_printf("reboot\n");
esp_restart();
}
float current_temperature;
class MyAdvertisedDeviceCallbacks : public BLEAdvertisedDeviceCallbacks {
void onResult(BLEAdvertisedDevice advertisedDevice)
{
if (advertisedDevice.haveName() && advertisedDevice.haveServiceData() /*&& !advertisedDevice.getName().compare("ATC_9C1E8B")*/) {
int serviceDataCount = advertisedDevice.getServiceDataCount();
std::string strServiceData = advertisedDevice.getServiceData(0);
uint8_t cServiceData[100];
char charServiceData[100];
strServiceData.copy((char *)cServiceData, strServiceData.length(), 0);
for (int i=0;i<strServiceData.length();i++) {
sprintf(&charServiceData[i*2], "%02x", cServiceData[i]);
}
std::stringstream ss;
ss << "fe95" << charServiceData;
text01 = String(charServiceData[0]) + String(charServiceData[1]); //Serial.print(text1); Serial.print(" ");
text02 = String(charServiceData[2]) + String(charServiceData[3]); //Serial.print(text2); Serial.print(" ");
text03 = String(charServiceData[4]) + String(charServiceData[5]); //Serial.print(text3); Serial.print(" ");
text04 = String(charServiceData[6]) + String(charServiceData[7]); //Serial.print(text4); Serial.print(" ");
text05 = String(charServiceData[8]) + String(charServiceData[9]); //Serial.print(text5); Serial.print(" ");
text06 = String(charServiceData[10]) + String(charServiceData[11]); //Serial.print(text6); Serial.print(" ");
text07 = String(charServiceData[12]) + String(charServiceData[13]); //Serial.print(text7); Serial.print(" ");
text08 = String(charServiceData[14]) + String(charServiceData[15]); //Serial.print(text8); Serial.print(" ");
text09 = String(charServiceData[16]) + String(charServiceData[17]); //Serial.print(text9); Serial.print(" ");
text10 = String(charServiceData[18]) + String(charServiceData[19]); //Serial.print(text10); Serial.print(" ");
text11 = String(charServiceData[20]) + String(charServiceData[21]); //Serial.print(text11); Serial.print(" ");
text12 = String(charServiceData[22]) + String(charServiceData[23]); //Serial.print(text12); Serial.print(" ");
//Serial.println();
zmienna = text01; Zamien_litery(); text01 = zmienna;
zmienna = text02; Zamien_litery(); text02 = zmienna;
zmienna = text03; Zamien_litery(); text03 = zmienna;
zmienna = text04; Zamien_litery(); text04 = zmienna;
zmienna = text05; Zamien_litery(); text05 = zmienna;
zmienna = text06; Zamien_litery(); text06 = zmienna;
zmienna = text07; Zamien_litery(); text07 = zmienna;
zmienna = text08; Zamien_litery(); text08 = zmienna;
zmienna = text09; Zamien_litery(); text09 = zmienna;
zmienna = text10; Zamien_litery(); text10 = zmienna;
zmienna = text11; Zamien_litery(); text11 = zmienna;
zmienna = text12; Zamien_litery(); text12 = zmienna;
zmienna = text13; Zamien_litery(); text13 = zmienna;
zmienna = text14; Zamien_litery(); text14 = zmienna;
zmienna = text15; Zamien_litery(); text15 = zmienna;
Konwersja();
}
}
};
class Czujnik1 : public Supla::Sensor::ThermHygroMeter {
public:
explicit Czujnik1()
{
}
double getTemp() {
temperature = temp1;
return temperature;
}
double getHumi() {
humidity = wilg1;
return humidity;
}
private:
void iterateAlways() {
if (millis() - lastReadTime > 10000) {
lastReadTime = millis();
channel.setNewValue(getTemp(), getHumi());
channel.setBatteryLevel(bat1);
}
}
void onInit() {
channel.setNewValue(getTemp(), getHumi());
channel.setBatteryLevel(bat1);
}
protected:
double temperature = - 270;
double humidity = 0;
};
Czujnik1 *czujniczek1 = nullptr;
class Czujnik2 : public Supla::Sensor::ThermHygroMeter {
public:
explicit Czujnik2()
{
}
double getTemp() {
temperature = temp2;
return temperature;
}
double getHumi() {
humidity = wilg2;
return humidity;
}
private:
void iterateAlways() {
if (millis() - lastReadTime > 10000) {
lastReadTime = millis();
channel.setNewValue(getTemp(), getHumi());
channel.setBatteryLevel(bat2);
}
}
void onInit() {
channel.setNewValue(getTemp(), getHumi());
channel.setBatteryLevel(bat2);
}
protected:
double temperature = -270;
double humidity = 0;
};
class Czujnik3 : public Supla::Sensor::ThermHygroMeter {
public:
explicit Czujnik3()
{
}
double getTemp() {
temperature = temp3;
//lastValidTemp = temperature;
return temperature;
}
double getHumi() {
humidity = wilg3;
//lastValidHumi = humidity;
return humidity;
}
private:
void iterateAlways() {
if (millis() - lastReadTime > 10000) {
lastReadTime = millis();
channel.setNewValue(getTemp(), getHumi());
channel.setBatteryLevel(bat3);
}
}
void onInit() {
channel.setNewValue(getTemp(), getHumi());
channel.setBatteryLevel(bat3);
}
protected:
double temperature = - 270;
double humidity = 0;
};
void setup() {
Serial.begin(115200);
initBluetooth();
// Channels configuration
auto buttonCfgRelay = new Supla::Control::Button(BUTTON_CFG_RELAY_GPIO, true, true);
buttonCfgRelay->configureAsConfigButton(&SuplaDevice);
auto czujniczek1 = new Czujnik1();
auto czujniczek2 = new Czujnik2();
auto czujniczek3 = new Czujnik3();
czujniczek1->getChannel()->setFlag(SUPLA_CHANNELSTATE_FIELD_BATTERYPOWERED);
czujniczek1->getChannel()->setFlag(SUPLA_CHANNELSTATE_FIELD_BATTERYLEVEL);
czujniczek2->getChannel()->setFlag(SUPLA_CHANNELSTATE_FIELD_BATTERYPOWERED);
czujniczek2->getChannel()->setFlag(SUPLA_CHANNELSTATE_FIELD_BATTERYLEVEL);
czujniczek3->getChannel()->setFlag(SUPLA_CHANNELSTATE_FIELD_BATTERYPOWERED);
czujniczek3->getChannel()->setFlag(SUPLA_CHANNELSTATE_FIELD_BATTERYLEVEL);
// configure defualt Supla CA certificate
SuplaDevice.setSuplaCACert(suplaCACert);
SuplaDevice.setSupla3rdPartyCACert(supla3rdCACert);
SuplaDevice.setName("Supla Xiaomi");
SuplaDevice.begin();
}
void loop() {
if (millis() - czas_pomiedzy_skanowaniem > 120000) {
czas_pomiedzy_skanowaniem = millis();
BLEScan* pBLEScan = BLEDevice::getScan(); //create new scan
pBLEScan->setAdvertisedDeviceCallbacks(new MyAdvertisedDeviceCallbacks());
pBLEScan->setActiveScan(true); //active scan uses more power, but get results faster
BLEScanResults foundDevices = pBLEScan->start(SCAN_TIME);
int count = foundDevices.getCount();
delay(100);
od1 = od1 +1;
od2 = od2 +1;
od3 = od3 +1;
}
SuplaDevice.iterate();
/* if (millis() - lastReadTime > 5000) {
lastReadTime = millis();
czujniczek1->getChannel()->setBatteryLevel(bat1);
czujniczek2->getChannel()->setBatteryLevel(bat2);
czujniczek3->getChannel()->setBatteryLevel(bat3);
}*/
if (WiFi.status() != WL_CONNECTED) {
if (millis() > wifimilis) {
WiFi.begin();
wifimilis = (millis() + 30000) ;
}
}
if (millis() > 86400000){
ESP.restart();
}
}
void initBluetooth()
{
BLEDevice::init("");
pBLEScan = BLEDevice::getScan(); //create new scan
pBLEScan->setAdvertisedDeviceCallbacks(new MyAdvertisedDeviceCallbacks());
pBLEScan->setActiveScan(false); //active scan uses more power, but get results faster
pBLEScan->setInterval(0x50);
pBLEScan->setWindow(0x30);
}
void Konwersja()
{
int number;
String hexstring;
int t1;
int t2;
hexstring = "#" + text07;
number = (int) strtol( &hexstring[1], NULL, 16);
t1 = number & 0xFF;
hexstring = "#" + text08;
number = (int) strtol( &hexstring[1], NULL, 16);
t2 = number & 0xFF;
current_temperature = t1 * 256;
current_temperature = current_temperature + t2;
current_temperature = current_temperature / 10;
// Konwersja z Faranheitów na Celsjusze
hexstring = "#" + text09;
number = (int) strtol( &hexstring[1], NULL, 16);
current_humidity = number & 0xFF;
hexstring = "#" + text10;
number = (int) strtol( &hexstring[1], NULL, 16);
current_batt = number & 0xFF;
MAC_ADR = "";
MAC_ADR = MAC_ADR + text01 + ":";
MAC_ADR = MAC_ADR + text02 + ":";
MAC_ADR = MAC_ADR + text03 + ":";
MAC_ADR = MAC_ADR + text04 + ":";
MAC_ADR = MAC_ADR + text05 + ":";
MAC_ADR = MAC_ADR + text06;
BLE_DEVICE = 0;
if(MAC_ADR == XIAOMI_BLE_DEVICE_1_MAC){BLE_DEVICE = 1; wyswietl = 1; Wyswietl();}
if(MAC_ADR == XIAOMI_BLE_DEVICE_2_MAC){BLE_DEVICE = 2; wyswietl = 1; Wyswietl();}
if(MAC_ADR == XIAOMI_BLE_DEVICE_3_MAC){BLE_DEVICE = 3; wyswietl = 1; Wyswietl();}
}
void Wyswietl(){
if(wyswietl == 1){
Serial.print("Urządzenie:");
Serial.print(BLE_DEVICE);
Serial.print(" MAC: ");
Serial.print(MAC_ADR);
Serial.print(" Temp: ");
Serial.print(current_temperature,1);
Serial.print("stC. Wilgotnosc: ");
Serial.print(current_humidity);
Serial.print("%. Bateria: ");
Serial.print(current_batt);
Serial.println("%.");
if (BLE_DEVICE == 1) {
temp1 = (current_temperature);
wilg1 = current_humidity;
bat1 = current_batt;
od1 = 0;
}
if (BLE_DEVICE == 2) {
temp2 = (current_temperature);
wilg2 = current_humidity;
bat2 = current_batt;
od2 = 0;
}
if (BLE_DEVICE == 3) {
temp3 = (current_temperature);
wilg3 = (current_humidity);
bat3 = (current_batt);
od3 = 0;
}
if (od1 > 5){
temp1 = -275;
wilg1 = -1;
bat1 = 0;
od1 = 0;
}
if (od2 > 5){
temp2 = -275;
wilg2 = -1;
bat2 = 0;
od2 = 0;
}
if (od3 > 5){
temp3 = -275;
wilg3 = -1;
bat3 = 0;
od3 = 0;
}
wyswietl = 0;
}
}
void Zamien_litery() //Zamieniamy otrzymywane małe litery na duże
{
zmienna.replace('a', 'A');
zmienna.replace('b', 'B');
zmienna.replace('c', 'C');
zmienna.replace('d', 'D');
zmienna.replace('e', 'E');
zmienna.replace('f', 'F');
}