diff --git a/src/ArduinoHomeLibrary.h b/src/ArduinoHomeLibrary.h index 17832eb..02c45c5 100644 --- a/src/ArduinoHomeLibrary.h +++ b/src/ArduinoHomeLibrary.h @@ -12,4 +12,5 @@ #include "services/irc_service.h" #include "services/info_service.h" #include "services/rgb_service.h" +#include "services/light_service.h" #include "services/relay_service.h" diff --git a/src/services/light_service.cpp b/src/services/light_service.cpp new file mode 100644 index 0000000..d0e998e --- /dev/null +++ b/src/services/light_service.cpp @@ -0,0 +1,108 @@ +#include +#include + +#include "utils/utils.h" +#include "utils/string_stream.h" +#include "runtime.h" +#include "dispatcher_service.h" +#include "configuration_service.h" +#include "light_service.h" + +#define NAME "LightService" + +#ifndef PWMRANGE +#define PWMRANGE 255 +#endif + +namespace ah { + namespace services { + + struct LightServiceConfig { + bool state; + uint8_t value; + }; + + #if PWMRANGE != 255 + static inline uint16_t pwmValue(uint8_t value) { + return static_cast(value) * PWMRANGE / 255; + } + #endif + + LightService::LightService(const int &ppin, const char *pid) + : id(pid ? pid : "light"), pin(ppin), config(nullptr) { + utils::StringStream ss(settings); + ss << "pin=" << pin; + } + + void LightService::init() { + dispatcher = Runtime::getDispatcherService(); + config = Runtime::getConfigurationService()->createItem(); + + dispatcher->registerGetter(id, [this](ArduinoJson::JsonVariant &value) { + JsonObject& data = DispatcherService::sharedBuffer().createObject(); + data["state"] = config->state; + data["value"] = config->value; + + value = data; + return true; + }); + + dispatcher->registerSetter(id, [this](const ArduinoJson::JsonVariant &value) { + if(!value.is()) { + return false; + } + + JsonObject& data = value.as(); + + if(data.containsKey("state")) { config->state = data["state"]; } + if(data.containsKey("value")) { config->value = data["value"]; } + + apply(); + config->save(); + + return true; + }); + } + + void LightService::setup() { + // be sure to enable pwm before use + analogWrite(pin, 1); + + config->load(); + apply(); + } + + void LightService::apply() { + AH_DEBUG(id << ": apply state=" << config->state << ", value=" << config->value << endl); + + if(config->state) { + #if PWMRANGE != 255 + analogWrite(pin, pwmValue(config->value)); + #else + analogWrite(pin, config->value); + #endif + } else { + analogWrite(pin, 0); + } + + JsonObject& data = DispatcherService::sharedBuffer().createObject(); + data["state"] = config->state; + data["value"] = config->value; + + dispatcher->notify(id, data); + } + + const char *LightService::getName() const { + return NAME; + } + + const char *LightService::getId() const { + return id; + } + + const char *LightService::getSettings() const { + return settings.c_str(); + } + + } // namespace services +} // namespace ah diff --git a/src/services/light_service.h b/src/services/light_service.h new file mode 100644 index 0000000..93c7397 --- /dev/null +++ b/src/services/light_service.h @@ -0,0 +1,41 @@ +#ifndef __ARDUINO_HOME_LIGHT_SERVICE_H__ +#define __ARDUINO_HOME_LIGHT_SERVICE_H__ + +#include "service.h" + +namespace ah { + namespace services { + + template + class ConfigItem; + + struct LightServiceConfig; + struct DispatcherService; + + struct LightService : public Service { + explicit LightService(const int &ppin, const char *pid = nullptr); + virtual ~LightService() = default; + + virtual void init(); + virtual void setup(); + + virtual const char *getName() const; + virtual const char *getId() const; + virtual const char *getSettings() const; + + private: + void apply(); + + const char *id; + + int pin; + + DispatcherService *dispatcher; + ConfigItem *config; + String settings; + }; + + } // namespace services +} // namespace ah + +#endif // __ARDUINO_HOME_LIGHT_SERVICE_H__