2021-12-23 09:09:26 +03:00
# include "Utils/JsonUtils.h"
# include "Utils/SerialPrint.h"
# include "Utils/StringUtils.h"
# include "Class/IoTSensor.h"
# include "Class/IoTModule.h"
# include "DallasTemperature.h"
# include <OneWire.h>
2021-12-24 20:03:38 +03:00
# include <map>
2021-12-23 09:09:26 +03:00
2021-12-24 20:03:38 +03:00
//глобальные списки необходимы для хранения объектов о б активных линиях 1-wire используемых разными датчиками из модуля. Ключ - номер пина
std : : map < int , OneWire * > oneWireTemperatureArray ;
std : : map < int , DallasTemperature * > sensorsTemperatureArray ;
2021-12-23 09:09:26 +03:00
class IoTSensorDallas : public IoTSensor {
private :
//описание переменных экземпляра датчика - аналог глобальных переменных из Arduino
2021-12-24 20:03:38 +03:00
//для работы библиотеки с несколькими линиями необходимо обеспечить каждый экземпляр класса ссылками на объекты настроенные на эти линии
2021-12-23 09:09:26 +03:00
OneWire * oneWire ;
2021-12-24 20:03:38 +03:00
DallasTemperature * sensors ;
2021-12-23 09:09:26 +03:00
//описание параметров передаваемых из настроек датчика из веба
String _addr ;
unsigned int _pin ;
unsigned int _index ;
public :
//аналог setup() из Arduino
IoTSensorDallas ( String parameters ) {
2021-12-27 21:24:55 +03:00
//передаем часть базовых параметров в конструктор базового класса для обеспечения работы е г о методов
init ( jsonReadStr ( parameters , " key " ) , jsonReadStr ( parameters , " id " ) , jsonReadInt ( parameters , " int " ) ) ;
2021-12-23 09:09:26 +03:00
_pin = jsonReadInt ( parameters , " pin " ) ;
_index = jsonReadInt ( parameters , " index " ) ;
_addr = jsonReadStr ( parameters , " addr " ) ;
2021-12-24 20:03:38 +03:00
//учитываем, что библиотека может работать с несколькими линиями на разных пинах, поэтому инициируем библиотеку, если линия ранее не использовалась
if ( oneWireTemperatureArray . find ( _pin ) = = oneWireTemperatureArray . end ( ) ) {
oneWire = new OneWire ( ( uint8_t ) _pin ) ;
sensors = new DallasTemperature ( ) ;
sensors - > setOneWire ( oneWire ) ;
sensors - > begin ( ) ;
sensors - > setResolution ( 12 ) ;
oneWireTemperatureArray [ _pin ] = oneWire ;
sensorsTemperatureArray [ _pin ] = sensors ;
} else {
oneWire = oneWireTemperatureArray [ _pin ] ;
sensors = sensorsTemperatureArray [ _pin ] ;
}
2021-12-23 09:09:26 +03:00
}
~ IoTSensorDallas ( ) { }
//аналог loop() из Arduino но квотируемый по времени параметром interval
void doByInterval ( ) {
2021-12-24 20:03:38 +03:00
//запускаем опрос измерений у всех датчиков на линии
sensors - > requestTemperatures ( ) ;
2021-12-23 09:09:26 +03:00
2021-12-24 20:03:38 +03:00
//Определяем адрес. Если парамтер addr не установлен, то узнаем адрес по индексу
2021-12-23 09:09:26 +03:00
DeviceAddress deviceAddress ;
if ( _addr = = " " ) {
2021-12-24 20:03:38 +03:00
sensors - > getAddress ( deviceAddress , _index ) ;
2021-12-23 09:09:26 +03:00
} else {
string2hex ( _addr . c_str ( ) , deviceAddress ) ;
}
2021-12-24 20:03:38 +03:00
//получаем температуру по адресу
float value = sensors - > getTempC ( deviceAddress ) ;
2021-12-23 09:09:26 +03:00
char addrStr [ 20 ] = " " ;
2021-12-24 20:03:38 +03:00
hex2string ( deviceAddress , 8 , addrStr ) ;
2021-12-23 09:09:26 +03:00
regEvent ( ( String ) value , " addr: " + String ( addrStr ) ) ; //обязательный вызов для отправки результата работы
}
} ;
2021-12-23 13:02:06 +03:00
//технический класс для взаимодействия с ядром, меняются только названия
2021-12-23 09:09:26 +03:00
class IoTModuleDallasTemp : public IoTModule {
2021-12-23 13:02:06 +03:00
//обязательный метод для инициализации экземпляра датчика, вызывается при чтении конфигурации. Нужно учитывать, что некоторые датчики могут обеспечивать
//несколько измерений, для каждого будет отдельный вызов.
2021-12-23 09:09:26 +03:00
void * initInstance ( String parameters ) {
return new IoTSensorDallas ( parameters ) ;
} ;
2021-12-27 21:24:55 +03:00
//обязательный к заполнению метод, если модуль использует свои глобальные переменные. Необходимо сбросить и очистить используемую память.
void clear ( ) {
2021-12-30 12:11:19 +03:00
// for (auto it = sensorsTemperatureArray.cbegin(), next_it = it; it != sensorsTemperatureArray.cend(); it = next_it) {
// ++next_it;
// DallasTemperature* tmpptr = it->second; //временно сохраняем указатель на сенсор, т.к. е г о преждевременное удаление оставит поломаную запись в векторе, к которой может обратиться ядро и вызвать исключение
// sensorsTemperatureArray.erase(it);
// delete tmpptr; //а далее уже удаляем объект сенсора
// }
2021-12-27 22:05:23 +03:00
2021-12-30 12:11:19 +03:00
// for (auto it = oneWireTemperatureArray.cbegin(), next_it = it; it != oneWireTemperatureArray.cend(); it = next_it) {
// ++next_it;
// OneWire* tmpptr = it->second; //временно сохраняем указатель на сенсор, т.к. е г о преждевременное удаление оставит поломаную запись в векторе, к которой может обратиться ядро и вызвать исключение
// oneWireTemperatureArray.erase(it);
// delete tmpptr; //а далее уже удаляем объект сенсора
// }
2021-12-27 21:24:55 +03:00
}
2021-12-23 13:02:06 +03:00
//обязательный метод для отправки информации о модуле,
2021-12-23 09:09:26 +03:00
ModuleInfo getInfo ( ) {
ModuleInfo MI ;
2021-12-27 21:24:55 +03:00
MI . name = " dallas-temp " ;
MI . title = " Датчик температуры Ds18b20 " ;
MI . parameters = " { \" key \" : \" dallas-temp \" , \" id \" : \" tmp \" , \" addr \" : \" \" , \" int \" : \" 10 \" , \" pin \" : \" 18 \" , \" index \" : \" 0 \" } " ;
2021-12-23 09:09:26 +03:00
MI . type = " Sensor " ;
return MI ;
} ;
} ;
2021-12-23 13:02:06 +03:00
//точка входа в модуль для заполнения вектора, требуется только изменить имя и прописать в файле api.cpp
2021-12-30 12:11:19 +03:00
void * getApiIoTSensorDallasTemp ( ) {
return new IoTModuleDallasTemp ( ) ;
2021-12-23 09:09:26 +03:00
}