add WordClock Features
This commit is contained in:
		@@ -29,13 +29,14 @@ lib_compat_mode = strict
 | 
			
		||||
framework = arduino
 | 
			
		||||
monitor_speed = 115200
 | 
			
		||||
 | 
			
		||||
extra_scripts = 
 | 
			
		||||
extra_scripts =
 | 
			
		||||
 pre:scripts/build_interface.py
 | 
			
		||||
 | 
			
		||||
lib_deps =
 | 
			
		||||
  ArduinoJson@>=6.0.0,<7.0.0
 | 
			
		||||
  ESP Async WebServer@>=1.2.0,<2.0.0
 | 
			
		||||
  AsyncMqttClient@>=0.8.2,<1.0.0
 | 
			
		||||
  adafruit/Adafruit NeoPixel@^1.7.0
 | 
			
		||||
  
 | 
			
		||||
[env:esp12e]
 | 
			
		||||
platform = espressif8266
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										159
									
								
								src/Clock.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										159
									
								
								src/Clock.cpp
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,159 @@
 | 
			
		||||
//
 | 
			
		||||
// Created by lukas on 06.03.21.
 | 
			
		||||
//
 | 
			
		||||
 | 
			
		||||
#include "Clock.h"
 | 
			
		||||
 | 
			
		||||
Clock::Clock() : strip(NUMPIXELS, D5, NEO_GRB + NEO_KHZ800), refreshTicker() {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void Clock::init() {
 | 
			
		||||
  strip.begin();
 | 
			
		||||
  strip.clear();
 | 
			
		||||
  strip.show();
 | 
			
		||||
 | 
			
		||||
  refreshTicker.attach(10, [this]() { this->refreshTime(); });
 | 
			
		||||
  this->refreshTime();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void Clock::paintAllwaysOnLeds() {
 | 
			
		||||
  printWord(types::es, Adafruit_NeoPixel::Color(150, 150, 0));
 | 
			
		||||
  printWord(types::ist, Adafruit_NeoPixel::Color(150, 0, 150));
 | 
			
		||||
  printWord(types::uhr, Adafruit_NeoPixel::Color(0, 0, 150));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void Clock::printWord(std::vector<int> word, uint32_t color) {
 | 
			
		||||
  for (const int i : word) {
 | 
			
		||||
    strip.setPixelColor(i, color);
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void Clock::refreshTime() {
 | 
			
		||||
  strip.clear();
 | 
			
		||||
 | 
			
		||||
  // grab the current instant in unix seconds
 | 
			
		||||
  time_t now = time(nullptr);
 | 
			
		||||
  if (now <= 604800) {
 | 
			
		||||
    strip.show();
 | 
			
		||||
    return;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  tm* loctime = localtime(&now);
 | 
			
		||||
 | 
			
		||||
  const uint8_t hour = loctime->tm_hour;
 | 
			
		||||
  const uint8_t minute = loctime->tm_min;
 | 
			
		||||
 | 
			
		||||
  paintAllwaysOnLeds();
 | 
			
		||||
  setTime(hour, minute);
 | 
			
		||||
  strip.show();
 | 
			
		||||
 | 
			
		||||
  Serial.print("time now: ");
 | 
			
		||||
  Serial.print(hour);
 | 
			
		||||
  Serial.print("h ");
 | 
			
		||||
  Serial.print(minute);
 | 
			
		||||
  Serial.println("M");
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void Clock::setTime(uint8_t hour, uint8_t minute) {
 | 
			
		||||
  const uint8_t minuteselector = minute / 5;
 | 
			
		||||
 | 
			
		||||
  // if minuteselector >= 4 +1 to hour
 | 
			
		||||
  if (minuteselector >= 4)
 | 
			
		||||
    hour++;
 | 
			
		||||
 | 
			
		||||
  // convert to 12h format
 | 
			
		||||
  if (hour >= 12)
 | 
			
		||||
    hour = hour - 12;
 | 
			
		||||
 | 
			
		||||
  std::vector<int> hourWord;
 | 
			
		||||
 | 
			
		||||
  hourWord = hour == 1    ? types::ein
 | 
			
		||||
             : hour == 2  ? types::zwei
 | 
			
		||||
             : hour == 3  ? types::drei
 | 
			
		||||
             : hour == 4  ? types::vier
 | 
			
		||||
             : hour == 5  ? types::fuenf2
 | 
			
		||||
             : hour == 6  ? types::sechs
 | 
			
		||||
             : hour == 7  ? types::sieben
 | 
			
		||||
             : hour == 8  ? types::acht
 | 
			
		||||
             : hour == 9  ? types::neun
 | 
			
		||||
             : hour == 10 ? types::zehn2
 | 
			
		||||
             : hour == 11 ? types::elf
 | 
			
		||||
             : hour == 0  ? types::zwoelf
 | 
			
		||||
                          : hourWord;
 | 
			
		||||
 | 
			
		||||
  printWord(hourWord, Adafruit_NeoPixel::Color(0, 150, 0));
 | 
			
		||||
 | 
			
		||||
  // fuenf / zehn / viertl word
 | 
			
		||||
  std::vector<int> minuteWord;
 | 
			
		||||
  if (minuteselector == 1 || minuteselector == 5 || minuteselector == 7 || minuteselector == 11)
 | 
			
		||||
    minuteWord = types::fuenf;
 | 
			
		||||
  else if (minuteselector == 2 || minuteselector == 4 || minuteselector == 8 || minuteselector == 10)
 | 
			
		||||
    minuteWord = types::zehn;
 | 
			
		||||
  else if (minuteselector == 3)
 | 
			
		||||
    minuteWord = types::viertel;
 | 
			
		||||
  else if (minuteselector == 9)
 | 
			
		||||
    minuteWord = types::dreiviertel;
 | 
			
		||||
  else if (minuteselector == 6)
 | 
			
		||||
    minuteWord = types::halb;
 | 
			
		||||
 | 
			
		||||
  printWord(minuteWord, Adafruit_NeoPixel::Color(0, 150, 0));
 | 
			
		||||
 | 
			
		||||
  // vor / nach
 | 
			
		||||
  std::vector<int> vornachWord;
 | 
			
		||||
  if (minuteselector == 1 || minuteselector == 2 || minuteselector == 3 || minuteselector == 7 || minuteselector == 8)
 | 
			
		||||
    vornachWord = types::nach;
 | 
			
		||||
  else if (minuteselector == 4 || minuteselector == 5 || minuteselector == 10 || minuteselector == 11)
 | 
			
		||||
    vornachWord = types::vor;
 | 
			
		||||
  printWord(vornachWord, Adafruit_NeoPixel::Color(150, 150, 150));
 | 
			
		||||
 | 
			
		||||
  // halb
 | 
			
		||||
  if (minuteselector >= 4 && minuteselector <= 8)
 | 
			
		||||
    printWord(types::halb, Adafruit_NeoPixel::Color(150, 0, 0));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const std::vector<int> types::es = calcPixels(0, 0, 2);
 | 
			
		||||
const std::vector<int> types::ist = calcPixels(3, 0, 3);
 | 
			
		||||
const std::vector<int> types::fuenf = calcPixels(8, 0, 4);
 | 
			
		||||
const std::vector<int> types::zehn = calcPixels(0, 1, 4);
 | 
			
		||||
const std::vector<int> types::zwanzig = calcPixels(5, 1, 7);
 | 
			
		||||
const std::vector<int> types::drei = calcPixels(1, 2, 3);
 | 
			
		||||
const std::vector<int> types::viertel = calcPixels(5, 2, 7);
 | 
			
		||||
const std::vector<int> types::dreiviertel = calcPixels(1, 2, 11);
 | 
			
		||||
const std::vector<int> types::vor = calcPixels(0, 3, 3);
 | 
			
		||||
const std::vector<int> types::nach = calcPixels(3, 3, 4);
 | 
			
		||||
const std::vector<int> types::halb = calcPixels(8, 3, 4);
 | 
			
		||||
const std::vector<int> types::zwoelf = calcPixels(0, 4, 5);
 | 
			
		||||
const std::vector<int> types::sieben = calcPixels(6, 4, 6);
 | 
			
		||||
const std::vector<int> types::ein = calcPixels(0, 5, 3);
 | 
			
		||||
const std::vector<int> types::eins = calcPixels(0, 5, 4);
 | 
			
		||||
const std::vector<int> types::vier = calcPixels(4, 5, 4);
 | 
			
		||||
const std::vector<int> types::acht = calcPixels(8, 5, 4);
 | 
			
		||||
const std::vector<int> types::sechs = calcPixels(0, 6, 5);
 | 
			
		||||
const std::vector<int> types::zwei = calcPixels(6, 6, 5);
 | 
			
		||||
const std::vector<int> types::fuenf2 = calcPixels(1, 7, 5);
 | 
			
		||||
const std::vector<int> types::elf = calcPixels(5, 7, 3);
 | 
			
		||||
const std::vector<int> types::zehn2 = calcPixels(8, 7, 4);
 | 
			
		||||
const std::vector<int> types::neun = calcPixels(0, 8, 4);
 | 
			
		||||
const std::vector<int> types::drei2 = calcPixels(4, 8, 4);
 | 
			
		||||
const std::vector<int> types::ein2 = calcPixels(6, 8, 3);
 | 
			
		||||
const std::vector<int> types::uhr = calcPixels(9, 8, 3);
 | 
			
		||||
 | 
			
		||||
uint8_t types::convert(uint8_t x, uint8_t y) {
 | 
			
		||||
  const bool upRow = (x % 2) == 0;
 | 
			
		||||
 | 
			
		||||
  int val = x * 9 + y;
 | 
			
		||||
  // if its a row upwards we need to calculate the additional down and up pixels
 | 
			
		||||
  if (upRow)
 | 
			
		||||
    // we need to go the rest down (9 -y) and up (*2) and subtract the too many added 10
 | 
			
		||||
    val += ((9 - y) * 2) - 10;
 | 
			
		||||
  return val;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
std::vector<int> types::calcPixels(uint8_t x, uint8_t y, uint8_t nrPixels) {
 | 
			
		||||
  std::vector<int> vec;
 | 
			
		||||
  for (uint8_t i = 0; i < nrPixels; i++) {
 | 
			
		||||
    vec.push_back(convert(x + i, y));
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  return vec;
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										48
									
								
								src/Clock.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										48
									
								
								src/Clock.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,48 @@
 | 
			
		||||
//
 | 
			
		||||
// Created by lukas on 06.03.21.
 | 
			
		||||
//
 | 
			
		||||
 | 
			
		||||
#ifndef LEDSTRIPINTERFACE_CLOCK_H
 | 
			
		||||
#define LEDSTRIPINTERFACE_CLOCK_H
 | 
			
		||||
 | 
			
		||||
#include <Ticker.h>
 | 
			
		||||
#include "Adafruit_NeoPixel.h"
 | 
			
		||||
#include "Arduino.h"
 | 
			
		||||
#include "../.pio/libdeps/node32s/Adafruit NeoPixel/Adafruit_NeoPixel.h"
 | 
			
		||||
 | 
			
		||||
#define NUMPIXELS 108 // Popular NeoPixel ring size
 | 
			
		||||
 | 
			
		||||
class Clock {
 | 
			
		||||
 private:
 | 
			
		||||
  Adafruit_NeoPixel strip{};
 | 
			
		||||
 | 
			
		||||
  void paintAllwaysOnLeds();
 | 
			
		||||
  void printWord(std::vector<int> word,  uint32_t color);
 | 
			
		||||
  void setTime(uint8_t hour, uint8_t minute);
 | 
			
		||||
 | 
			
		||||
 public:
 | 
			
		||||
  Clock();
 | 
			
		||||
  void init();
 | 
			
		||||
  void refreshTime();
 | 
			
		||||
 | 
			
		||||
  Ticker refreshTicker;
 | 
			
		||||
};
 | 
			
		||||
struct types {
 | 
			
		||||
  static const std::vector<int>
 | 
			
		||||
      es, ist, fuenf,
 | 
			
		||||
      zehn, zwanzig, drei,
 | 
			
		||||
      viertel, dreiviertel, vor,
 | 
			
		||||
      nach, halb, zwoelf,
 | 
			
		||||
      sieben, ein, eins,
 | 
			
		||||
      vier, acht, sechs,
 | 
			
		||||
      zwei, fuenf2, elf,
 | 
			
		||||
      zehn2, neun, drei2,
 | 
			
		||||
      ein2, uhr;
 | 
			
		||||
 | 
			
		||||
  static uint8_t convert(uint8_t x, uint8_t y);
 | 
			
		||||
 | 
			
		||||
  static std::vector<int> calcPixels(uint8_t x, uint8_t y, uint8_t nrPixels);
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#endif  // LEDSTRIPINTERFACE_CLOCK_H
 | 
			
		||||
							
								
								
									
										38
									
								
								src/ClockService.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										38
									
								
								src/ClockService.cpp
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,38 @@
 | 
			
		||||
//
 | 
			
		||||
// Created by lukas on 06.03.21.
 | 
			
		||||
//
 | 
			
		||||
 | 
			
		||||
#include "ClockService.h"
 | 
			
		||||
 | 
			
		||||
ClockService::ClockService(AsyncWebServer* server, SecurityManager* securityManager) :
 | 
			
		||||
    _httpEndpoint(LightState::read,
 | 
			
		||||
                  LightState::update,
 | 
			
		||||
                  this,
 | 
			
		||||
                  server,
 | 
			
		||||
                  LIGHT_SETTINGS_ENDPOINT_PATH,
 | 
			
		||||
                  securityManager,
 | 
			
		||||
                  AuthenticationPredicates::IS_AUTHENTICATED),
 | 
			
		||||
    _webSocket(LightState::read,
 | 
			
		||||
               LightState::update,
 | 
			
		||||
               this,
 | 
			
		||||
               server,
 | 
			
		||||
               LIGHT_SETTINGS_SOCKET_PATH,
 | 
			
		||||
               securityManager,
 | 
			
		||||
               AuthenticationPredicates::IS_AUTHENTICATED),
 | 
			
		||||
    clock() {
 | 
			
		||||
  // configure led to be output
 | 
			
		||||
  pinMode(LED_PIN, OUTPUT);
 | 
			
		||||
 | 
			
		||||
  // configure settings service update handler to update LED state
 | 
			
		||||
  addUpdateHandler([&](const String& originId) { onConfigUpdated(); }, false);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void ClockService::begin() {
 | 
			
		||||
  _state.ledOn = DEFAULT_LED_STATE;
 | 
			
		||||
  onConfigUpdated();
 | 
			
		||||
  clock.init();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void ClockService::onConfigUpdated() {
 | 
			
		||||
  digitalWrite(LED_PIN, _state.ledOn ? LED_ON : LED_OFF);
 | 
			
		||||
}
 | 
			
		||||
@@ -1,11 +1,13 @@
 | 
			
		||||
#ifndef LightStateService_h
 | 
			
		||||
#define LightStateService_h
 | 
			
		||||
//
 | 
			
		||||
// Created by lukas on 06.03.21.
 | 
			
		||||
//
 | 
			
		||||
 | 
			
		||||
#include <LightMqttSettingsService.h>
 | 
			
		||||
#pragma once
 | 
			
		||||
 | 
			
		||||
#include <HttpEndpoint.h>
 | 
			
		||||
#include <MqttPubSub.h>
 | 
			
		||||
#include <WebSocketTxRx.h>
 | 
			
		||||
#include "Clock.h"
 | 
			
		||||
 | 
			
		||||
#define LED_PIN 2
 | 
			
		||||
#define PRINT_DELAY 5000
 | 
			
		||||
@@ -50,7 +52,7 @@ class LightState {
 | 
			
		||||
 | 
			
		||||
  static StateUpdateResult haUpdate(JsonObject& root, LightState& lightState) {
 | 
			
		||||
    String state = root["state"];
 | 
			
		||||
    // parse new led state 
 | 
			
		||||
    // parse new led state
 | 
			
		||||
    boolean newState = false;
 | 
			
		||||
    if (state.equals(ON_STATE)) {
 | 
			
		||||
      newState = true;
 | 
			
		||||
@@ -66,23 +68,17 @@ class LightState {
 | 
			
		||||
  }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
class LightStateService : public StatefulService<LightState> {
 | 
			
		||||
class ClockService : public StatefulService<LightState> {
 | 
			
		||||
 public:
 | 
			
		||||
  LightStateService(AsyncWebServer* server,
 | 
			
		||||
                    SecurityManager* securityManager,
 | 
			
		||||
                    AsyncMqttClient* mqttClient,
 | 
			
		||||
                    LightMqttSettingsService* lightMqttSettingsService);
 | 
			
		||||
  ClockService(AsyncWebServer* server, SecurityManager* securityManager);
 | 
			
		||||
  void begin();
 | 
			
		||||
 | 
			
		||||
 private:
 | 
			
		||||
  HttpEndpoint<LightState> _httpEndpoint;
 | 
			
		||||
  MqttPubSub<LightState> _mqttPubSub;
 | 
			
		||||
  WebSocketTxRx<LightState> _webSocket;
 | 
			
		||||
  AsyncMqttClient* _mqttClient;
 | 
			
		||||
  LightMqttSettingsService* _lightMqttSettingsService;
 | 
			
		||||
 | 
			
		||||
  void registerConfig();
 | 
			
		||||
  Clock clock;
 | 
			
		||||
 | 
			
		||||
  void onConfigUpdated();
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
@@ -1,16 +0,0 @@
 | 
			
		||||
#include <LightMqttSettingsService.h>
 | 
			
		||||
 | 
			
		||||
LightMqttSettingsService::LightMqttSettingsService(AsyncWebServer* server, FS* fs, SecurityManager* securityManager) :
 | 
			
		||||
    _httpEndpoint(LightMqttSettings::read,
 | 
			
		||||
                  LightMqttSettings::update,
 | 
			
		||||
                  this,
 | 
			
		||||
                  server,
 | 
			
		||||
                  LIGHT_BROKER_SETTINGS_PATH,
 | 
			
		||||
                  securityManager,
 | 
			
		||||
                  AuthenticationPredicates::IS_AUTHENTICATED),
 | 
			
		||||
    _fsPersistence(LightMqttSettings::read, LightMqttSettings::update, this, fs, LIGHT_BROKER_SETTINGS_FILE) {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void LightMqttSettingsService::begin() {
 | 
			
		||||
  _fsPersistence.readFromFS();
 | 
			
		||||
}
 | 
			
		||||
@@ -1,41 +0,0 @@
 | 
			
		||||
#ifndef LightMqttSettingsService_h
 | 
			
		||||
#define LightMqttSettingsService_h
 | 
			
		||||
 | 
			
		||||
#include <HttpEndpoint.h>
 | 
			
		||||
#include <FSPersistence.h>
 | 
			
		||||
#include <SettingValue.h>
 | 
			
		||||
 | 
			
		||||
#define LIGHT_BROKER_SETTINGS_FILE "/config/brokerSettings.json"
 | 
			
		||||
#define LIGHT_BROKER_SETTINGS_PATH "/rest/brokerSettings"
 | 
			
		||||
 | 
			
		||||
class LightMqttSettings {
 | 
			
		||||
 public:
 | 
			
		||||
  String mqttPath;
 | 
			
		||||
  String name;
 | 
			
		||||
  String uniqueId;
 | 
			
		||||
 | 
			
		||||
  static void read(LightMqttSettings& settings, JsonObject& root) {
 | 
			
		||||
    root["mqtt_path"] = settings.mqttPath;
 | 
			
		||||
    root["name"] = settings.name;
 | 
			
		||||
    root["unique_id"] = settings.uniqueId;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  static StateUpdateResult update(JsonObject& root, LightMqttSettings& settings) {
 | 
			
		||||
    settings.mqttPath = root["mqtt_path"] | SettingValue::format("homeassistant/light/#{unique_id}");
 | 
			
		||||
    settings.name = root["name"] | SettingValue::format("light-#{unique_id}");
 | 
			
		||||
    settings.uniqueId = root["unique_id"] | SettingValue::format("light-#{unique_id}");
 | 
			
		||||
    return StateUpdateResult::CHANGED;
 | 
			
		||||
  }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
class LightMqttSettingsService : public StatefulService<LightMqttSettings> {
 | 
			
		||||
 public:
 | 
			
		||||
  LightMqttSettingsService(AsyncWebServer* server, FS* fs, SecurityManager* securityManager);
 | 
			
		||||
  void begin();
 | 
			
		||||
 | 
			
		||||
 private:
 | 
			
		||||
  HttpEndpoint<LightMqttSettings> _httpEndpoint;
 | 
			
		||||
  FSPersistence<LightMqttSettings> _fsPersistence;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#endif  // end LightMqttSettingsService_h
 | 
			
		||||
@@ -1,73 +0,0 @@
 | 
			
		||||
#include <LightStateService.h>
 | 
			
		||||
 | 
			
		||||
LightStateService::LightStateService(AsyncWebServer* server,
 | 
			
		||||
                                     SecurityManager* securityManager,
 | 
			
		||||
                                     AsyncMqttClient* mqttClient,
 | 
			
		||||
                                     LightMqttSettingsService* lightMqttSettingsService) :
 | 
			
		||||
    _httpEndpoint(LightState::read,
 | 
			
		||||
                  LightState::update,
 | 
			
		||||
                  this,
 | 
			
		||||
                  server,
 | 
			
		||||
                  LIGHT_SETTINGS_ENDPOINT_PATH,
 | 
			
		||||
                  securityManager,
 | 
			
		||||
                  AuthenticationPredicates::IS_AUTHENTICATED),
 | 
			
		||||
    _mqttPubSub(LightState::haRead, LightState::haUpdate, this, mqttClient),
 | 
			
		||||
    _webSocket(LightState::read,
 | 
			
		||||
               LightState::update,
 | 
			
		||||
               this,
 | 
			
		||||
               server,
 | 
			
		||||
               LIGHT_SETTINGS_SOCKET_PATH,
 | 
			
		||||
               securityManager,
 | 
			
		||||
               AuthenticationPredicates::IS_AUTHENTICATED),
 | 
			
		||||
    _mqttClient(mqttClient),
 | 
			
		||||
    _lightMqttSettingsService(lightMqttSettingsService) {
 | 
			
		||||
  // configure led to be output
 | 
			
		||||
  pinMode(LED_PIN, OUTPUT);
 | 
			
		||||
 | 
			
		||||
  // configure MQTT callback
 | 
			
		||||
  _mqttClient->onConnect(std::bind(&LightStateService::registerConfig, this));
 | 
			
		||||
 | 
			
		||||
  // configure update handler for when the light settings change
 | 
			
		||||
  _lightMqttSettingsService->addUpdateHandler([&](const String& originId) { registerConfig(); }, false);
 | 
			
		||||
 | 
			
		||||
  // configure settings service update handler to update LED state
 | 
			
		||||
  addUpdateHandler([&](const String& originId) { onConfigUpdated(); }, false);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void LightStateService::begin() {
 | 
			
		||||
  _state.ledOn = DEFAULT_LED_STATE;
 | 
			
		||||
  onConfigUpdated();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void LightStateService::onConfigUpdated() {
 | 
			
		||||
  digitalWrite(LED_PIN, _state.ledOn ? LED_ON : LED_OFF);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void LightStateService::registerConfig() {
 | 
			
		||||
  if (!_mqttClient->connected()) {
 | 
			
		||||
    return;
 | 
			
		||||
  }
 | 
			
		||||
  String configTopic;
 | 
			
		||||
  String subTopic;
 | 
			
		||||
  String pubTopic;
 | 
			
		||||
 | 
			
		||||
  DynamicJsonDocument doc(256);
 | 
			
		||||
  _lightMqttSettingsService->read([&](LightMqttSettings& settings) {
 | 
			
		||||
    configTopic = settings.mqttPath + "/config";
 | 
			
		||||
    subTopic = settings.mqttPath + "/set";
 | 
			
		||||
    pubTopic = settings.mqttPath + "/state";
 | 
			
		||||
    doc["~"] = settings.mqttPath;
 | 
			
		||||
    doc["name"] = settings.name;
 | 
			
		||||
    doc["unique_id"] = settings.uniqueId;
 | 
			
		||||
  });
 | 
			
		||||
  doc["cmd_t"] = "~/set";
 | 
			
		||||
  doc["stat_t"] = "~/state";
 | 
			
		||||
  doc["schema"] = "json";
 | 
			
		||||
  doc["brightness"] = false;
 | 
			
		||||
 | 
			
		||||
  String payload;
 | 
			
		||||
  serializeJson(doc, payload);
 | 
			
		||||
  _mqttClient->publish(configTopic.c_str(), 0, false, payload.c_str());
 | 
			
		||||
 | 
			
		||||
  _mqttPubSub.configureTopics(pubTopic, subTopic);
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										16
									
								
								src/main.cpp
									
									
									
									
									
								
							
							
						
						
									
										16
									
								
								src/main.cpp
									
									
									
									
									
								
							@@ -1,17 +1,12 @@
 | 
			
		||||
#include <ESP8266React.h>
 | 
			
		||||
#include <LightMqttSettingsService.h>
 | 
			
		||||
#include <LightStateService.h>
 | 
			
		||||
#include "ClockService.h"
 | 
			
		||||
 | 
			
		||||
#define SERIAL_BAUD_RATE 115200
 | 
			
		||||
 | 
			
		||||
AsyncWebServer server(80);
 | 
			
		||||
ESP8266React esp8266React(&server);
 | 
			
		||||
LightMqttSettingsService lightMqttSettingsService =
 | 
			
		||||
    LightMqttSettingsService(&server, esp8266React.getFS(), esp8266React.getSecurityManager());
 | 
			
		||||
LightStateService lightStateService = LightStateService(&server,
 | 
			
		||||
                                                        esp8266React.getSecurityManager(),
 | 
			
		||||
                                                        esp8266React.getMqttClient(),
 | 
			
		||||
                                                        &lightMqttSettingsService);
 | 
			
		||||
 | 
			
		||||
ClockService cservice = ClockService(&server, esp8266React.getSecurityManager());
 | 
			
		||||
 | 
			
		||||
void setup() {
 | 
			
		||||
  // start serial and filesystem
 | 
			
		||||
@@ -21,10 +16,7 @@ void setup() {
 | 
			
		||||
  esp8266React.begin();
 | 
			
		||||
 | 
			
		||||
  // load the initial light settings
 | 
			
		||||
  lightStateService.begin();
 | 
			
		||||
 | 
			
		||||
  // start the light service
 | 
			
		||||
  lightMqttSettingsService.begin();
 | 
			
		||||
  cservice.begin();
 | 
			
		||||
 | 
			
		||||
  // start the server
 | 
			
		||||
  server.begin();
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user