#include <Arduino.h>
// --- Обязательные константы ядра ---
const char* DEVICE_TYPE = "my_device"; // тип устройства
const char* FW_VERSION = "1.0 dev";
const uint8_t CHANNEL_NUM = 2; // 0 если каналы не используются
#include <sh_core.h>
#include "MyDeviceLogic.h"
// --- Хук для /status ---
void appendStatusJsonFields(String &json) {
// json уже содержит "status":"ok"
// добавляем дополнительные поля
json += ",\"my_field\":42";
}
// --- Хук для /about ---
void appendAboutJsonFields(String &json) {
json += ",\"channels\":" + String(CHANNEL_NUM);
}
// --- Обработчик /action ---
bool deviceHandleAction(const String &action,
const String ¶msJson,
String &errorCode,
String &errorMessage)
{
if (action == "my_action") {
// ...
return true;
}
errorCode = "IllegalActionOrParams";
errorMessage = "Unknown action";
return false;
}
// --- Сброс к заводским настройкам ---
void deviceHandleReset() {
// очистить EEPROM устройства (диапазон DEVICE_EEPROM_START..EEPROM_SIZE)
EEPROM.begin(EEPROM_SIZE);
for (uint16_t addr = DEVICE_EEPROM_START; addr < EEPROM_SIZE; addr++) {
EEPROM.write(addr, 0xFF);
}
EEPROM.commit();
EEPROM.end();
}
void setup() {
coreSetup();
// инициализация GPIO, сенсоров и т.п.
}
void loop() {
coreLoop();
// своя логика
}
Каналы читаются из EEPROM через API ядра:
uint8_t pin = sh_channel_pin(ch); // GPIO пин канала uint8_t ind = sh_channel_indicator(ch); // GPIO пин индикатора uint8_t fb_pin = sh_channel_feedback_pin(ch); // GPIO пин обратной связи bool inverted = sh_channel_is_inverted(ch); // флаг инверсии
Если pin == SH_PIN_UNUSED (0xFF) — канал не задействован:
if (pin == SH_PIN_UNUSED) continue;
Ядро занимает адреса 0..~293. Для хранения данных устройства:
const uint16_t MY_EEPROM_BASE = getDeviceEepromStart(); // = 512 const uint16_t MY_DATA_ADDR = MY_EEPROM_BASE; // float = 4 байта const uint16_t MY_STATE_ADDR = MY_EEPROM_BASE + 4;
#include <sh_core.h>
// Пример отправки события
String json = "{\"device_id\":\"" + getUniqueID() + "\","
"\"event_name\":\"my_event\","
"\"data\":{\"channel\":0}}";
int http_code = 0;
core_post_json_to_server("/events/new", json, 3000, http_code);
Путь для событий по умолчанию /events/new. Можно переопределить:
const char* core_get_event_path() { return "/events/new"; }
DEVICE_TYPE |
Описание |
|---|---|
relay |
Реле (1–8 каналов), хранит состояние в EEPROM |
button |
Блок кнопок с RGB-индикаторами NeoPixel |
sensor |
Мультисенсор (radar, climate, light, mic) |
hatch |
Моторизованный люк (3 реле + концевик) |
Библиотека sh_core поддерживает ESP8266 и ESP32 через платформенные заголовки:
devices/sh_core_esp8266/src/platform/esp8266/sh_platform_esp8266.hdevices/sh_core_esp8266/src/platform/esp32/sh_platform_esp32.hАктивный платформенный заголовок выбирается через sh_platform.h.
| Компонент | Пины |
|---|---|
| BH1750 (свет) | SDA=16, SCL=17, I2C addr=0x5C |
| BME280 (климат) | SDA=18, SCL=19, I2C addr=0x76 |
| LD2420 (radar) | RX=4, TX=15, 115200 baud |
| MAX4466 (mic) | ADC=34 |
| Компонент | Пин |
|---|---|
| Силовое реле | GPIO18 (хардкод HATCH_POWER_RELAY_PIN) |
| Реле «открыть» (канал 0) | через channels schema |
| Реле «закрыть» (канал 1) | через channels schema |
| Концевик «закрыто» | feedback-пин канала 1 |