2019-05-10 05:17:29 +00:00
|
|
|
#include "./Config.h"
|
|
|
|
#include "./Static.h"
|
|
|
|
|
|
|
|
HardwareConfig
|
|
|
|
HardwareConfig::load() {
|
|
|
|
HardwareConfig ret;
|
|
|
|
EEPROM.get(0, ret);
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
HardwareConfig::save() {
|
|
|
|
HardwareConfig dataCopy{*this};
|
|
|
|
dataCopy.checksum = getCRC();
|
|
|
|
EEPROM.put(0, dataCopy);
|
|
|
|
}
|
|
|
|
|
2021-03-28 01:19:55 +00:00
|
|
|
LinearCoordinateMapping
|
|
|
|
HardwareConfig::toCoordMap() const
|
|
|
|
{
|
|
|
|
auto pixelCount = min(HardwareConfig::MAX_LED_NUM, max(1, data.pixelCount));
|
|
|
|
auto startPixel = min(pixelCount, max(1, data.startPixel));
|
|
|
|
return LinearCoordinateMapping{pixelCount, startPixel};
|
|
|
|
}
|
|
|
|
|
2019-05-10 05:17:29 +00:00
|
|
|
bool
|
|
|
|
HardwareConfig::isValid() const
|
|
|
|
{
|
2021-03-28 01:19:55 +00:00
|
|
|
return version == 1 && checksum == getCRC() && data.pixelCount <= MAX_LED_NUM;
|
2019-05-10 05:17:29 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
uint8_t
|
|
|
|
HardwareConfig::getCRC() const
|
|
|
|
{
|
|
|
|
const unsigned char* message = reinterpret_cast<const unsigned char*>(&data);
|
|
|
|
constexpr uint8_t length = sizeof(data);
|
|
|
|
unsigned char i, j, crc = 0;
|
|
|
|
for(i = 0; i < length; i++) {
|
|
|
|
crc ^= message[i];
|
|
|
|
for(j = 0; j < 8; j++) {
|
|
|
|
if (crc & 1) {
|
|
|
|
crc ^= CRC7_POLY;
|
|
|
|
}
|
|
|
|
crc >>= 1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return crc;
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
ConfigService::onStart()
|
|
|
|
{
|
2021-03-28 01:19:55 +00:00
|
|
|
Log.info("Starting configuration service...");
|
2019-05-10 05:17:29 +00:00
|
|
|
m_config = HardwareConfig::load();
|
|
|
|
if (m_config.isValid()) {
|
|
|
|
Log.info("Configuration found!");
|
|
|
|
} else {
|
|
|
|
Log.info("No configuration found. Writing defaults...");
|
|
|
|
m_config = HardwareConfig{};
|
|
|
|
m_config.save();
|
|
|
|
}
|
2021-03-28 01:19:55 +00:00
|
|
|
m_coordMap = m_config.toCoordMap();
|
|
|
|
|
|
|
|
m_pixelCount = AnimatedNumber{max(1, m_coordMap.pixelCount)};
|
|
|
|
m_startPixel = AnimatedNumber{max(0, m_coordMap.startPixel)};
|
2019-05-10 05:17:29 +00:00
|
|
|
Log.info("Configured to use %d pixels, starting at %d", m_pixelCount.value(), m_startPixel.value());
|
|
|
|
Log.info("Loading task states...");
|
|
|
|
for(int i = 0; i < 32; i++) {
|
|
|
|
auto svc = m_config.data.serviceStates[i];
|
|
|
|
if (strlen(svc.name) > 0) {
|
|
|
|
Log.info("* %s: %s", svc.name, svc.isRunning ? "RUNNING" : "STOPPED");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
ConfigService::onConnected()
|
|
|
|
{
|
|
|
|
Log.info("Connecting photon configuration...");
|
|
|
|
Particle.function("pixelCount", &ConfigService::setPixelCount, this);
|
|
|
|
Particle.function("startPixel", &ConfigService::setStartPixel, this);
|
|
|
|
|
|
|
|
Particle.function("save", &ConfigService::photonSave, this);
|
|
|
|
Particle.variable("pixelCount", m_pixelCountInt);
|
|
|
|
Particle.variable("startPixel", m_startPixelInt);
|
|
|
|
|
|
|
|
publishConfig();
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
ConfigService::loop()
|
|
|
|
{
|
2021-03-28 01:19:55 +00:00
|
|
|
//m_startPixel.update();
|
|
|
|
//m_pixelCount.update();
|
|
|
|
//m_coordMap.pixelCount = max(1, m_pixelCount.value());
|
|
|
|
//m_coordMap.startPixel = max(0, m_startPixel.value());
|
2019-05-10 05:17:29 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
ConfigService::handleEvent(const InputEvent &evt)
|
|
|
|
{
|
2021-03-28 01:19:55 +00:00
|
|
|
switch(evt.intent) {
|
|
|
|
case InputEvent::NetworkStatus:
|
|
|
|
onConnected();
|
|
|
|
break;
|
|
|
|
case InputEvent::SetDisplayLength:
|
|
|
|
Log.info("Updating pixel count from %d to %d", m_coordMap.pixelCount, evt.asInt());
|
|
|
|
m_config.data.pixelCount = evt.asInt();
|
|
|
|
m_coordMap = m_config.toCoordMap();
|
|
|
|
m_pixelCountInt = evt.asInt();
|
|
|
|
//m_pixelCount = m_config.data.pixelCount;
|
|
|
|
//m_coordMap.pixelCount = evt.asInt();
|
|
|
|
Log.info("Count is now %d", m_coordMap.pixelCount);
|
|
|
|
break;
|
|
|
|
case InputEvent::SetDisplayOffset:
|
|
|
|
Log.info("Updating pixel offset from %d to %d", m_coordMap.startPixel, evt.asInt());
|
|
|
|
m_config.data.startPixel = evt.asInt();
|
|
|
|
m_coordMap = m_config.toCoordMap();
|
|
|
|
m_startPixelInt = evt.asInt();
|
|
|
|
Log.info("Offset is now %d", m_coordMap.startPixel);
|
|
|
|
//m_coordMap.startPixel = evt.asInt();
|
|
|
|
//m_startPixel = m_config.data.startPixel;
|
|
|
|
break;
|
|
|
|
case InputEvent::SaveConfigurationRequest:
|
|
|
|
Log.info("Saving configuration");
|
|
|
|
m_config.save();
|
|
|
|
break;
|
2019-05-10 05:17:29 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
ConfigService::publishConfig() const
|
|
|
|
{
|
|
|
|
char buf[255];
|
|
|
|
snprintf(buf, sizeof(buf), "{\"pixels\": \"%d\", \"offset\": \"%d\"}", m_config.data.pixelCount, m_config.data.startPixel);
|
|
|
|
Particle.publish("renderbug/config", buf, PRIVATE);
|
|
|
|
}
|
|
|
|
|
|
|
|
int
|
|
|
|
ConfigService::photonSave(String command)
|
|
|
|
{
|
|
|
|
m_config.save();
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
int
|
|
|
|
ConfigService::setPixelCount(String command)
|
|
|
|
{
|
|
|
|
m_config.data.pixelCount = command.toInt();
|
|
|
|
m_pixelCount = m_config.data.pixelCount;
|
|
|
|
publishConfig();
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
int
|
|
|
|
ConfigService::setStartPixel(String command)
|
|
|
|
{
|
|
|
|
m_config.data.startPixel = command.toInt();
|
|
|
|
m_startPixel = m_config.data.startPixel;
|
|
|
|
publishConfig();
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
STATIC_ALLOC(ConfigService);
|