2023-07-06 21:47:13 +03:00
//=======================================================================================================
// Это файл сенсора, в нем осуществляется чтение сенсора.
// для добавления сенсора вам нужно скопировать этот файл и заменить в нем текст ExamleModule на название вашего сенсора
// Название должно быть уникальным, коротким и отражать суть сенсора.
// Обязательные библиотеки из ядра IoTM
# include "Global.h"
# include "classes/IoTItem.h"
2023-09-22 20:52:30 +03:00
//! Здесь подключаем стороннюю библиотеку при необходимости (ExternalLibrary заменить)
// #include <ExternalLibrary.h>
# include "ExternalLibrary.h" //удалить, только для примера. Внешние библиотеки правильно в <>
2023-07-06 21:47:13 +03:00
2023-09-22 20:52:30 +03:00
//! Объяевляем класс IoTGpio для работы с GPIO
2023-07-06 21:47:13 +03:00
extern IoTGpio IoTgpio ;
//=========================================================================================================
//=========================================================================================================
2023-09-22 20:52:30 +03:00
// Объявление сторонней библиотекит с использованием глобавльных объектов
2023-07-06 21:47:13 +03:00
//=======================================================================================================
//! Объявляем стороннюю библиотеку при необходимости (ExternalLibrary заменить)
// !!! ЗДЕСЬ И ДАЛЕЕ libXX Н А З В А Т Ь уникальным именем)
ExternalLibrary * libXX = nullptr ;
// Функция инициализации библиотечного класса, возвращает Единстрвенный указать на библиотеку
// instanceLibXX Н А З В А Т Ь по наименованию модуля (instanceДа тчикХ )
// ПРИ НЕОБХДИМОСТИ передаем любые нужные параметры для инициализации библиотеки (в данном случае PIN)
2023-09-22 20:52:30 +03:00
//
// !!! ВЫзвать данную функцию нужно хотябы один раз,
2023-07-06 21:47:13 +03:00
// но в каждом конструкторе класса модуля ExampleModule_A, ExampleModule_B и т.д.
// или можно вывывать постоянно при обращении к библиотеке, типа: instanceLibXX().READ_LIB_DATA_OTHER();
2023-09-22 20:52:30 +03:00
//
// !!!!!! В деструкторах ~ExampleModule_B() и ~ExampleModule_A() надо УДАЛЯТЬ объект libXX, ЕСЛИ в функцию instanceLibXX чтото передается.
// Удаляем класс библиотеки, а то при переконфигурации в нем не поменяются PIN и дугие параметры передаваемые в библиотеку.
// P.S. Н е для всех, если используется map или vector то лучше не надо.
2023-07-06 21:47:13 +03:00
ExternalLibrary * instanceLibXX ( int pin )
{
if ( ! libXX )
{ // Если библиотека ранее инициализировалась, то просто вернем указатель
// Инициализируем библиотеку
libXX = new ExternalLibrary ( ) ;
libXX - > begin ( pin ) ; // При необходимости делаем begin библиотеке
}
return libXX ;
}
//=========================================================================================================
//=========================================================================================================
// Первый класс модуля для определения 1-г о элемента (параметра)
// Служит для запроса и отображения парметра/элемента датчика
// IoTManager система модульная: один парметр - один элемент (класс)
//
//=========================================================================================================
//=========================================================================================================
// ребенок - родитель
class ExampleModule_A : public IoTItem
{
private :
//=======================================================================================================
// Секция переменных.
// Это секция где Вы можете объявлять переменные и объекты arduino библиотек, что бы
// впоследствии использовать их в loop и setup
unsigned int _pin ;
// пользовательская переменная, в данном случае для считывания аналогового сигнала
int adc ;
public :
//=======================================================================================================
// setup()
// это аналог setup из arduino. Здесь вы можете выполнять методы инициализации сенсора.
// Такие как ...begin и подставлять в них параметры полученные из web интерфейса.
// В с е параметры хранятся в перемененной parameters, вы можете прочитать любой параметр используя jsonRead функции:
// jsonReadStr, jsonReadBool, jsonReadInt
ExampleModule_A ( String parameters ) : IoTItem ( parameters )
{
2023-09-22 20:52:30 +03:00
// Читаем пользовательскую переменную PIN, должна быть объявлена в в modeinfo.json
2023-07-06 21:47:13 +03:00
_pin = jsonReadInt ( parameters , " pin " ) ;
// другой вариант чтения парметров модуля
jsonRead ( parameters , F ( " int " ) , _interval , false ) ;
}
//=======================================================================================================
// doByInterval() - основная функция периодической работы
// это аналог loop из arduino, но вызываемый каждые int секунд, заданные в настройках. Здесь вы должны выполнить чтение вашего сенсора
// а затем выполнить regEvent - это регистрация произошедшего события чтения
// здесь так же доступны все переменные из секции переменных, и полученные в setup
// если у сенсора несколько величин то делайте несколько regEvent
// не используйте delay - помните, что данный loop общий для всех модулей. Если у вас планируется длительная операция, постарайтесь разбить е е на порции
// и выполнить за несколько тактов
void doByInterval ( )
{
// Пример получения данных из библиотеки, где READ_LIB_DATA_OTHER - функция Вашей библиотеки
value . valD = instanceLibXX ( _pin ) - > READ_LIB_DATA_OTHER ( ) ;
// Здесь Наменование произвольным но понятным к какому модулю относится
regEvent ( value . valD , " ExampleModule " ) ; // обязательный вызов хотяб один для регистрации события в ядре IoTM
}
//=======================================================================================================
// loop(), если не нужно переопределять, удалить.
// полный аналог loop() из arduino. Нужно помнить, что все модули имеют равный поочередный доступ к центральному loop(), поэтому, необходимо следить
// за задержками в алгоритме и не создавать пауз. Кроме того, данная версия перегружает родительскую, поэтому doByInterval() отключается, если
// не повторить механизм расчета интервалов.
void loop ( )
{
// Пример получения данных с аналоговым датчиком
adc = IoTgpio . analogRead ( _pin ) ;
// Блок вызова doByInterval, так как если определили loop, то сам он не вызовится
2023-09-05 00:20:03 +03:00
IoTItem : : loop ( ) ;
2023-07-06 21:47:13 +03:00
}
2023-09-22 20:52:30 +03:00
~ ExampleModule_A ( )
{
// Удаляем класс библиотеки, а то при переконфигурации в нем не поменяются PIN и дугие параметры передаваемые в библиотеку.
delete libXX ;
libXX = nullptr ;
} ;
2023-07-06 21:47:13 +03:00
} ;
//=========================================================================================================
//=========================================================================================================
// Второй класс модуля для определения 2-г о элемента (параметра)
// Делается по аналогии с первым классом, служит для запроса и отображения другого парметра если их несколько с одного датчика
// IoTManager система модульная: один парметр - один элемент (класс)
//
// Содержит описание дополнительных методов onModuleOrder и execute
//=========================================================================================================
//=========================================================================================================
class ExampleModule_B : public IoTItem
{
private :
2023-09-22 20:52:30 +03:00
// Пользовательские переменные
2023-07-06 21:47:13 +03:00
unsigned int _pin ;
2023-09-22 20:52:30 +03:00
2023-07-06 21:47:13 +03:00
public :
ExampleModule_B ( String parameters ) : IoTItem ( parameters )
{
2023-09-22 20:52:30 +03:00
// Читаем пользовательскую переменную PIN, должна быть объявлена в в modeinfo.json
2023-07-06 21:47:13 +03:00
_pin = jsonReadInt ( parameters , " pin " ) ;
2023-09-22 20:52:30 +03:00
// Можно инициализировать библиотеку один раз, а потом используем указатель
2023-07-06 21:47:13 +03:00
instanceLibXX ( _pin ) ;
libXX - > READ_LIB_DATA_OTHER ( ) ;
}
void doByInterval ( )
{
// Пример получения данных из библиотеки, где READ_LIB_DATA_OTHER - функция Вашей библиотеки
value . valD = libXX - > READ_LIB_DATA_OTHER ( ) ;
// Здесь Наменование произвольным но понятным к какому модулю относится
regEvent ( value . valD , " ExampleModule " ) ; // обязательный вызов хотяб один для регистрации события в ядре IoTM
}
2023-09-22 20:52:30 +03:00
//================ обработка кнопок из конфигурации ===================
2023-07-06 21:47:13 +03:00
// Хук (переопределение виртуальной функции) для обработки кнопки (в value будут данные с собственной панели ввода)
// Что бы кнопка была без поля ввода, нужно в modeinfo.json указать "btn-Example": nil
void onModuleOrder ( String & key , String & value )
{
if ( key = = " Example " ) // название кнопки btn-Example
{
SerialPrint ( " i " , F ( " Sensor ExampleModule " ) , " User run calibration " + value ) ;
// ЧТО Т О Делаем
}
}
2023-09-22 20:52:30 +03:00
//================ обработка команд из сценария===================
2023-07-06 21:47:13 +03:00
// Хук (переопределение виртуальной функции) для обработки команды из сценария (в param будут даныые переданные в функции в сценарии)
IoTValue execute ( String command , std : : vector < IoTValue > & param )
{
if ( command = = " expampleFunc " )
{
if ( param . size ( ) )
{
// Забираем данные из другого модуля по е г о ID
// Если в сценарии передадим id модуля
String value = getItemValue ( param [ 0 ] . valS ) ;
// Что то делаем с этим параметром
return { } ;
}
}
else if ( command = = " expample2 " )
{
if ( param . size ( ) = = 2 )
{
SerialPrint ( " i " , F ( " Sensor ExampleModule " ) , " expample2: " + param [ 0 ] . valS + " , " + param [ 1 ] . valS ) ;
// Передаем полученные данные на дальнейшую обработку
// foo(param[0].valS, param[1].valS);
return { } ;
}
}
else if ( command = = " expampleAny " )
{
if ( param . size ( ) > = 1 )
{
int sizeOfParam = param . size ( ) ;
for ( unsigned int i = 0 ; i < sizeOfParam ; i + + )
{
SerialPrint ( " i " , F ( " Sensor ExampleModule " ) , " expampleAny: " + param [ i ] . valS ) ;
// Что то делаем с каждым принятым значением
// foo(param[i].valD);
}
}
}
return { } ;
}
void foo ( String logid , String value )
{
// Прсото пример кокой-то функции
}
2023-09-22 20:52:30 +03:00
~ ExampleModule_B ( )
{
// Удаляем класс библиотеки, а то при переконфигурации в нем не поменяются PIN и дугие параметры передаваемые в библиотеку.
delete libXX ;
libXX = nullptr ;
} ;
2023-07-06 21:47:13 +03:00
} ;
//=========================================================================================================
//=========================================================================================================
// Функция для связи модуля с ядром IoTM
// !!! ЗДЕСЬ getAPI_ИМ Я ИМЯ должно совпадать с "moduleName" из modeinfo.json
// после замены названия сенсора, на функцию можно не обращать внимания
// если сенсор предполагает использование общего объекта библиотеки для нескольких экземпляров сенсора, то в данной функции необходимо предусмотреть
// создание и контроль соответствующих глобальных переменных
//=========================================================================================================
//=========================================================================================================
void * getAPI_ExampleModule ( String subtype , String param )
{
if ( subtype = = F ( " ExampleModule_A " ) )
{ // !!! ЗДЕСЬ subtype ДОЛЖЕН СОВПАДАТЬ С subtype из modeinfo.json
return new ExampleModule_A ( param ) ;
}
else if ( subtype = = F ( " ExampleModule_B " ) )
{ // !!! ЗДЕСЬ subtype ДОЛЖЕН СОВПАДАТЬ С subtype из modeinfo.json
return new ExampleModule_B ( param ) ;
}
else
{
return nullptr ;
}
}