Implemented motion sensor settings
Moved all settings to JSON storage
This commit is contained in:
parent
f6808c4833
commit
981d6ac1bb
52
API.md
52
API.md
@ -10,6 +10,8 @@
|
|||||||
- [POST /api/steps](#post-apisteps)
|
- [POST /api/steps](#post-apisteps)
|
||||||
- [GET /api/triggers/time](#get-apitriggerstime)
|
- [GET /api/triggers/time](#get-apitriggerstime)
|
||||||
- [POST /api/triggers/time](#post-apitriggerstime)
|
- [POST /api/triggers/time](#post-apitriggerstime)
|
||||||
|
- [GET /api/triggers/motion](#get-apitriggersmotion)
|
||||||
|
- [POST /api/triggers/motion](#post-apitriggersmotion)
|
||||||
- [POST /api/firmware](#post-apifirmware)
|
- [POST /api/firmware](#post-apifirmware)
|
||||||
|
|
||||||
## GET /api/version
|
## GET /api/version
|
||||||
@ -203,6 +205,56 @@ enabled: whether or not this trigger is enabled
|
|||||||
|
|
||||||
Changes the time trigger settings. Request body format is the same as is returned in the GET request.
|
Changes the time trigger settings. Request body format is the same as is returned in the GET request.
|
||||||
|
|
||||||
|
|
||||||
|
## GET /api/triggers/motion
|
||||||
|
|
||||||
|
Returns the current settings for the motion triggers.
|
||||||
|
|
||||||
|
delay: How long to keep the lights on after the last sensor stops detecting motion.
|
||||||
|
|
||||||
|
pin: GPIO pin to which the motion sensor is connected. High is assumed to be active.
|
||||||
|
|
||||||
|
direction:
|
||||||
|
Enumeration determining from which side the sweep animation starts if transitionTime is set.
|
||||||
|
|
||||||
|
| value | description |
|
||||||
|
| ----- | --- |
|
||||||
|
| 1 | Non-directional. All steps change brightness at the same time. |
|
||||||
|
| 2 | Top-down. Starts a sweeping fade from the top step. |
|
||||||
|
| 3 | Bottom-up. Starts a sweeping fade from the bottom step. |
|
||||||
|
|
||||||
|
brightness: value from 0 to 255
|
||||||
|
|
||||||
|
enabled: whether or not this trigger is enabled
|
||||||
|
|
||||||
|
*Example response:*
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"enabled": true,
|
||||||
|
"enabledDuringTimeTrigger": true,
|
||||||
|
"transitionTime": 1000,
|
||||||
|
"delay": 30000,
|
||||||
|
"triggers": [
|
||||||
|
{
|
||||||
|
"pin": 14,
|
||||||
|
"brightness": 64,
|
||||||
|
"direction": 2,
|
||||||
|
"enabled": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"pin": 15,
|
||||||
|
"brightness": 64,
|
||||||
|
"direction": 3,
|
||||||
|
"enabled": true
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## POST /api/triggers/motion
|
||||||
|
|
||||||
|
Changes the motion trigger settings. Request body format is the same as is returned in the GET request.
|
||||||
|
|
||||||
## POST /api/firmware
|
## POST /api/firmware
|
||||||
|
|
||||||
Uploads new firmware. The bin file should be posted as a multipart/form-data file attachment. Name is not relevant.
|
Uploads new firmware. The bin file should be posted as a multipart/form-data file attachment. Name is not relevant.
|
@ -45,7 +45,7 @@
|
|||||||
#include <StreamString.h>
|
#include <StreamString.h>
|
||||||
#include <base64.h>
|
#include <base64.h>
|
||||||
|
|
||||||
#include "ESP8266HTTPClient-h4xx0red.h"
|
#include "./ESP8266HTTPClient-h4xx0red.h"
|
||||||
|
|
||||||
class TransportTraits
|
class TransportTraits
|
||||||
{
|
{
|
||||||
|
@ -4,10 +4,10 @@
|
|||||||
const uint8_t VersionMajor = 2;
|
const uint8_t VersionMajor = 2;
|
||||||
const uint8_t VersionMinor = 0;
|
const uint8_t VersionMinor = 0;
|
||||||
const uint8_t VersionPatch = 0;
|
const uint8_t VersionPatch = 0;
|
||||||
const uint8_t VersionMetadata = 17;
|
const uint8_t VersionMetadata = 18;
|
||||||
const char VersionBranch[] = "release/2.0";
|
const char VersionBranch[] = "release/2.0";
|
||||||
const char VersionSemVer[] = "2.0.0-beta.1";
|
const char VersionSemVer[] = "2.0.0-beta.1";
|
||||||
const char VersionFullSemVer[] = "2.0.0-beta.1+17";
|
const char VersionFullSemVer[] = "2.0.0-beta.1+18";
|
||||||
const char VersionCommitDate[] = "2018-01-14";
|
const char VersionCommitDate[] = "2018-01-14";
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -4,12 +4,12 @@
|
|||||||
*
|
*
|
||||||
* https://git.x2software.net/pub/Stairs
|
* https://git.x2software.net/pub/Stairs
|
||||||
*/
|
*/
|
||||||
#include "charproperties.h"
|
#include "./charproperties.h"
|
||||||
#include <cstddef>
|
#include <cstddef>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include "debug.h"
|
#include "./debug.h"
|
||||||
|
|
||||||
void CharProperties::assignChar(char** field, const char* newValue)
|
void assignChar(char** field, const char* newValue)
|
||||||
{
|
{
|
||||||
if (*field != nullptr)
|
if (*field != nullptr)
|
||||||
delete *field;
|
delete *field;
|
||||||
|
@ -9,10 +9,6 @@
|
|||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
class CharProperties
|
|
||||||
{
|
|
||||||
protected:
|
|
||||||
void assignChar(char** field, const char* newValue);
|
void assignChar(char** field, const char* newValue);
|
||||||
};
|
|
||||||
|
|
||||||
#endif
|
#endif
|
@ -3,7 +3,7 @@
|
|||||||
* Copyright 2017 (c) Mark van Renswoude
|
* Copyright 2017 (c) Mark van Renswoude
|
||||||
*/
|
*/
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include "PCA9685.h"
|
#include "./PCA9685.h"
|
||||||
#include <Wire.h>
|
#include <Wire.h>
|
||||||
|
|
||||||
#include <Arduino.h>
|
#include <Arduino.h>
|
||||||
|
@ -14,8 +14,9 @@ static const uint32_t SerialDebugStartupDelay = 2000;
|
|||||||
|
|
||||||
static const char* ConnectionSettingsFile = "/connection.json";
|
static const char* ConnectionSettingsFile = "/connection.json";
|
||||||
static const char* SystemSettingsFile = "/system.json";
|
static const char* SystemSettingsFile = "/system.json";
|
||||||
static const char* StepSettingsFile = "/stepsettings.dat";
|
static const char* StepsSettingsFile = "/steps.json";
|
||||||
static const char* TimeTriggerSettingsFile = "/timetriggersettings.dat";
|
static const char* TimeTriggerSettingsFile = "/timetriggers.json";
|
||||||
|
static const char* MotionTriggerSettingsFile = "/motiontriggers.json";
|
||||||
|
|
||||||
|
|
||||||
static const char* DefaultAPSSIDPrefix = "Stairs-";
|
static const char* DefaultAPSSIDPrefix = "Stairs-";
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
*
|
*
|
||||||
* https://git.x2software.net/pub/Stairs
|
* https://git.x2software.net/pub/Stairs
|
||||||
*/
|
*/
|
||||||
#include "debug.h"
|
#include "./debug.h"
|
||||||
|
|
||||||
|
|
||||||
void _dinit()
|
void _dinit()
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
#ifndef __serialdebug
|
#ifndef __serialdebug
|
||||||
#define __serialdebug
|
#define __serialdebug
|
||||||
|
|
||||||
#include "config.h"
|
#include "./config.h"
|
||||||
#include <Arduino.h>
|
#include <Arduino.h>
|
||||||
|
|
||||||
void _dinit();
|
void _dinit();
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
*
|
*
|
||||||
* https://git.x2software.net/pub/Stairs
|
* https://git.x2software.net/pub/Stairs
|
||||||
*/
|
*/
|
||||||
#include "global.h"
|
#include "./global.h"
|
||||||
|
|
||||||
ConnectionSettings* connectionSettings = new ConnectionSettings();
|
ConnectionSettings* connectionSettings = new ConnectionSettings();
|
||||||
bool connectionSettingsChanged = false;
|
bool connectionSettingsChanged = false;
|
||||||
@ -18,6 +18,9 @@ bool stepsSettingsChanged = false;
|
|||||||
TimeTriggerSettings* timeTriggerSettings = new TimeTriggerSettings();
|
TimeTriggerSettings* timeTriggerSettings = new TimeTriggerSettings();
|
||||||
bool timeTriggerSettingsChanged = false;
|
bool timeTriggerSettingsChanged = false;
|
||||||
|
|
||||||
|
MotionTriggerSettings* motionTriggerSettings = new MotionTriggerSettings();
|
||||||
|
bool motionTriggerSettingsChanged = false;
|
||||||
|
|
||||||
|
|
||||||
Stairs* stairs;
|
Stairs* stairs;
|
||||||
|
|
||||||
|
14
src/global.h
14
src/global.h
@ -10,11 +10,12 @@
|
|||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
#include <IPAddress.h>
|
#include <IPAddress.h>
|
||||||
#include "settings/connection.h"
|
#include "./settings/connection.h"
|
||||||
#include "settings/system.h"
|
#include "./settings/system.h"
|
||||||
#include "settings/steps.h"
|
#include "./settings/steps.h"
|
||||||
#include "settings/triggers/time.h"
|
#include "./settings/triggers/time.h"
|
||||||
#include "stairs.h"
|
#include "./settings/triggers/motion.h"
|
||||||
|
#include "./stairs.h"
|
||||||
|
|
||||||
extern ConnectionSettings* connectionSettings;
|
extern ConnectionSettings* connectionSettings;
|
||||||
extern bool connectionSettingsChanged;
|
extern bool connectionSettingsChanged;
|
||||||
@ -28,6 +29,9 @@ extern bool stepsSettingsChanged;
|
|||||||
extern TimeTriggerSettings* timeTriggerSettings;
|
extern TimeTriggerSettings* timeTriggerSettings;
|
||||||
extern bool timeTriggerSettingsChanged;
|
extern bool timeTriggerSettingsChanged;
|
||||||
|
|
||||||
|
extern MotionTriggerSettings* motionTriggerSettings;
|
||||||
|
extern bool motionTriggerSettingsChanged;
|
||||||
|
|
||||||
|
|
||||||
extern Stairs* stairs;
|
extern Stairs* stairs;
|
||||||
|
|
||||||
|
137
src/main.cpp
137
src/main.cpp
@ -16,29 +16,28 @@ extern "C" {
|
|||||||
#include <user_interface.h>
|
#include <user_interface.h>
|
||||||
}
|
}
|
||||||
|
|
||||||
#include "config.h"
|
#include "./config.h"
|
||||||
#include "debug.h"
|
#include "./debug.h"
|
||||||
#include "global.h"
|
#include "./global.h"
|
||||||
#include "components/PCA9685.h"
|
#include "./components/PCA9685.h"
|
||||||
#include "settings/connection.h"
|
#include "./settings/connection.h"
|
||||||
#include "server/static.h"
|
#include "./server/static.h"
|
||||||
#include "server/settings.h"
|
#include "./server/settings.h"
|
||||||
#include "server/firmware.h"
|
#include "./server/firmware.h"
|
||||||
#include "server/api.h"
|
#include "./server/api.h"
|
||||||
|
|
||||||
|
|
||||||
ADC_MODE(ADC_VCC);
|
ADC_MODE(ADC_VCC);
|
||||||
|
|
||||||
// Forward declarations
|
// Forward declarations
|
||||||
void initWiFi();
|
void initWiFi();
|
||||||
|
void initMotionPins();
|
||||||
#ifdef SerialDebug
|
#ifdef SerialDebug
|
||||||
void wifiEvent(WiFiEvent_t event);
|
void wifiEvent(WiFiEvent_t event);
|
||||||
void updateDebugStatus();
|
void updateDebugStatus();
|
||||||
#endif
|
#endif
|
||||||
void updateLED();
|
void updateLED();
|
||||||
void updateNTPClient();
|
void updateNTPClient();
|
||||||
|
|
||||||
void updateTimeTrigger();
|
|
||||||
void checkTriggers();
|
void checkTriggers();
|
||||||
|
|
||||||
void handleNotFound(AsyncWebServerRequest* request);
|
void handleNotFound(AsyncWebServerRequest* request);
|
||||||
@ -73,10 +72,12 @@ void setup()
|
|||||||
systemSettings->read();
|
systemSettings->read();
|
||||||
stepsSettings->read();
|
stepsSettings->read();
|
||||||
timeTriggerSettings->read();
|
timeTriggerSettings->read();
|
||||||
|
motionTriggerSettings->read();
|
||||||
|
|
||||||
pinMode(systemSettings->pinAPButton(), INPUT_PULLUP);
|
pinMode(systemSettings->pinAPButton(), INPUT_PULLUP);
|
||||||
pinMode(systemSettings->pinLEDAP(), OUTPUT);
|
pinMode(systemSettings->pinLEDAP(), OUTPUT);
|
||||||
pinMode(systemSettings->pinLEDSTA(), OUTPUT);
|
pinMode(systemSettings->pinLEDSTA(), OUTPUT);
|
||||||
|
initMotionPins();
|
||||||
|
|
||||||
|
|
||||||
_dln("Setup :: initializing PCA9685");
|
_dln("Setup :: initializing PCA9685");
|
||||||
@ -142,6 +143,12 @@ void loop()
|
|||||||
ESP.restart();
|
ESP.restart();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (motionTriggerSettingsChanged)
|
||||||
|
{
|
||||||
|
initMotionPins();
|
||||||
|
motionTriggerSettingsChanged = false;
|
||||||
|
}
|
||||||
|
|
||||||
currentTime = millis();
|
currentTime = millis();
|
||||||
|
|
||||||
|
|
||||||
@ -191,12 +198,7 @@ void loop()
|
|||||||
|
|
||||||
updateLED();
|
updateLED();
|
||||||
updateNTPClient();
|
updateNTPClient();
|
||||||
|
|
||||||
if (timeTriggerSettings->enabled() /*|| motionTriggerEnabled*/)
|
|
||||||
{
|
|
||||||
updateTimeTrigger();
|
|
||||||
checkTriggers();
|
checkTriggers();
|
||||||
}
|
|
||||||
|
|
||||||
stairs->tick();
|
stairs->tick();
|
||||||
}
|
}
|
||||||
@ -253,6 +255,20 @@ void initWiFi()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void initMotionPins()
|
||||||
|
{
|
||||||
|
if (!motionTriggerSettings->enabled())
|
||||||
|
return;
|
||||||
|
|
||||||
|
for (uint8_t i = 0; i < motionTriggerSettings->triggerCount(); i++)
|
||||||
|
{
|
||||||
|
MotionTrigger* trigger = motionTriggerSettings->trigger(i);
|
||||||
|
if (trigger->enabled)
|
||||||
|
pinMode(trigger->pin, INPUT);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
#ifdef SerialDebug
|
#ifdef SerialDebug
|
||||||
void wifiEvent(WiFiEvent_t event)
|
void wifiEvent(WiFiEvent_t event)
|
||||||
{
|
{
|
||||||
@ -403,10 +419,20 @@ TimeTrigger* activeTimeTrigger = nullptr;
|
|||||||
void updateTimeTrigger()
|
void updateTimeTrigger()
|
||||||
{
|
{
|
||||||
if (ntpClient == nullptr || !timeTriggerSettings->enabled())
|
if (ntpClient == nullptr || !timeTriggerSettings->enabled())
|
||||||
|
{
|
||||||
|
activeTimeTrigger = nullptr;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (timeTriggerSettingsChanged)
|
||||||
|
{
|
||||||
|
// Time trigger settings changed, activeTimeTrigger pointer is considered
|
||||||
|
// invalid, force recheck
|
||||||
|
timeTriggerSettingsChanged = false;
|
||||||
|
}
|
||||||
|
else if (currentTime - lastTimeTriggerChecked < 10000)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (currentTime - lastTimeTriggerChecked < 10000)
|
|
||||||
return;
|
|
||||||
|
|
||||||
lastTimeTriggerChecked = currentTime;
|
lastTimeTriggerChecked = currentTime;
|
||||||
_dln("Triggers:: updating time trigger");
|
_dln("Triggers:: updating time trigger");
|
||||||
@ -414,11 +440,12 @@ void updateTimeTrigger()
|
|||||||
uint32_t epochTime = ntpClient->getEpochTime();
|
uint32_t epochTime = ntpClient->getEpochTime();
|
||||||
if (epochTime == 0)
|
if (epochTime == 0)
|
||||||
{
|
{
|
||||||
|
activeTimeTrigger = nullptr;
|
||||||
_dln("Triggers:: time not synchronised yet");
|
_dln("Triggers:: time not synchronised yet");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO compensate for UTC
|
// TODO apply timezone offset
|
||||||
|
|
||||||
tmElements_t time;
|
tmElements_t time;
|
||||||
breakTime(epochTime, time);
|
breakTime(epochTime, time);
|
||||||
@ -435,21 +462,59 @@ void updateTimeTrigger()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
uint32_t activeMotionStart = 0;
|
||||||
|
uint16_t activeMotionBrightness = 0;
|
||||||
|
MotionDirection activeMotionDirection = Nondirectional;
|
||||||
|
bool lastMotion = false;
|
||||||
|
|
||||||
|
|
||||||
|
void updateMotionTrigger()
|
||||||
|
{
|
||||||
|
if (!motionTriggerSettings->enabled() || !motionTriggerSettings->triggerCount())
|
||||||
|
{
|
||||||
|
activeMotionStart = 0;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (uint8_t i = 0; i < motionTriggerSettings->triggerCount(); i++)
|
||||||
|
{
|
||||||
|
MotionTrigger* trigger = motionTriggerSettings->trigger(i);
|
||||||
|
|
||||||
|
if (trigger->enabled && digitalRead(trigger->pin) == HIGH)
|
||||||
|
{
|
||||||
|
if (activeMotionStart == 0)
|
||||||
|
{
|
||||||
|
activeMotionDirection = trigger->direction;
|
||||||
|
activeMotionBrightness = trigger->brightness;
|
||||||
|
}
|
||||||
|
|
||||||
|
activeMotionStart = currentTime;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (currentTime - activeMotionStart >= motionTriggerSettings->delay())
|
||||||
|
activeMotionStart = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void checkTriggers()
|
void checkTriggers()
|
||||||
{
|
{
|
||||||
|
if (!timeTriggerSettings->enabled() && activeTimeTrigger == nullptr &&
|
||||||
|
!motionTriggerSettings->enabled() && activeMotionStart == 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
updateTimeTrigger();
|
||||||
|
updateMotionTrigger();
|
||||||
|
|
||||||
bool inTimeTrigger = timeTriggerSettings->enabled() &&
|
bool inTimeTrigger = timeTriggerSettings->enabled() &&
|
||||||
activeTimeTrigger != nullptr &&
|
activeTimeTrigger != nullptr &&
|
||||||
activeTimeTrigger->brightness;
|
activeTimeTrigger->brightness;
|
||||||
bool timeTriggerChanged = activeTimeTrigger != lastTimeTrigger;
|
bool timeTriggerChanged = activeTimeTrigger != lastTimeTrigger;
|
||||||
lastTimeTrigger = activeTimeTrigger;
|
lastTimeTrigger = activeTimeTrigger;
|
||||||
|
|
||||||
// TODO motion sensor settings
|
bool inMotionTrigger = (activeMotionStart > 0) && (!inTimeTrigger || motionTriggerSettings->enabledDuringTimeTrigger());
|
||||||
bool inMotionTrigger = false; // && (alsoDuringTimeTrigger || !inTimeTrigger)
|
bool motionChanged = (activeMotionStart > 0) != lastMotion;
|
||||||
bool motionChanged = false;
|
lastMotion = (activeMotionStart > 0);
|
||||||
|
|
||||||
// TODO dummies, replace these with motionSettings-> values later on
|
|
||||||
uint16_t motionBrightness = 0;
|
|
||||||
uint16_t motionTransitionTime = 0;
|
|
||||||
|
|
||||||
|
|
||||||
if (!motionChanged && !timeTriggerChanged)
|
if (!motionChanged && !timeTriggerChanged)
|
||||||
@ -462,22 +527,28 @@ void checkTriggers()
|
|||||||
{
|
{
|
||||||
_dln("Triggers :: start motion trigger");
|
_dln("Triggers :: start motion trigger");
|
||||||
|
|
||||||
|
if (activeMotionDirection == Nondirectional || motionTriggerSettings->transitionTime() == 0)
|
||||||
|
{
|
||||||
|
stairs->setAll(activeMotionBrightness, motionTriggerSettings->transitionTime(), 0);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
// Start sweep
|
// Start sweep
|
||||||
bool sweepDown = true;
|
|
||||||
uint8_t stepsCount = stepsSettings->count();
|
uint8_t stepsCount = stepsSettings->count();
|
||||||
uint16_t offset = sweepDown ? 0 : motionTransitionTime;
|
uint16_t offsetIncrement = stepsCount > 0 ? (motionTriggerSettings->transitionTime() / stepsCount) * 1.5 : 0;
|
||||||
uint16_t offsetIncrement = stepsCount > 0 ? motionTransitionTime / stepsCount : 0;
|
uint16_t offset = activeMotionDirection == TopDown ? 0 : (stepsCount - 1) * offsetIncrement;
|
||||||
|
|
||||||
for (uint8_t step = 0; step < stepsCount; step++)
|
for (uint8_t step = 0; step < stepsCount; step++)
|
||||||
{
|
{
|
||||||
stairs->set(step, motionBrightness, motionTransitionTime, offset);
|
stairs->set(step, activeMotionBrightness, motionTriggerSettings->transitionTime(), offset);
|
||||||
|
|
||||||
if (sweepDown)
|
if (activeMotionDirection == TopDown)
|
||||||
offset += offsetIncrement;
|
offset += offsetIncrement;
|
||||||
else
|
else
|
||||||
offset -= offsetIncrement;
|
offset -= offsetIncrement;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (inTimeTrigger)
|
if (inTimeTrigger)
|
||||||
@ -485,14 +556,14 @@ void checkTriggers()
|
|||||||
_dln("Triggers :: motion stopped, falling back to time trigger");
|
_dln("Triggers :: motion stopped, falling back to time trigger");
|
||||||
|
|
||||||
// Fall back to time trigger value
|
// Fall back to time trigger value
|
||||||
stairs->setAll(activeTimeTrigger->brightness, motionTransitionTime, 0);
|
stairs->setAll(activeTimeTrigger->brightness, motionTriggerSettings->transitionTime(), 0);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
_dln("Triggers :: motion stopped, turning off");
|
_dln("Triggers :: motion stopped, turning off");
|
||||||
|
|
||||||
// No more motion, no active time trigger, turn off
|
// No more motion, no active time trigger, turn off
|
||||||
stairs->setAll(0, motionTransitionTime, 0);
|
stairs->setAll(0, motionTriggerSettings->transitionTime(), 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
* This code was ported over from Domoticz' SunRiseSet.cpp
|
* This code was ported over from Domoticz' SunRiseSet.cpp
|
||||||
* https://github.com/domoticz/domoticz/
|
* https://github.com/domoticz/domoticz/
|
||||||
*/
|
*/
|
||||||
#include "praisethesun.h"
|
#include "./praisethesun.h"
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
|
|
||||||
|
|
||||||
|
@ -4,11 +4,11 @@
|
|||||||
*
|
*
|
||||||
* https://git.x2software.net/pub/Stairs
|
* https://git.x2software.net/pub/Stairs
|
||||||
*/
|
*/
|
||||||
#include "api.h"
|
#include "./api.h"
|
||||||
#include <ArduinoJson.h>
|
#include <ArduinoJson.h>
|
||||||
#include <IPAddress.h>
|
#include <IPAddress.h>
|
||||||
#include <ESP8266WiFi.h>
|
#include <ESP8266WiFi.h>
|
||||||
#include "shared.h"
|
#include "./shared.h"
|
||||||
#include "../assets/version.h"
|
#include "../assets/version.h"
|
||||||
#include "../debug.h"
|
#include "../debug.h"
|
||||||
#include "../global.h"
|
#include "../global.h"
|
||||||
@ -69,30 +69,8 @@ void handleGetTimeTriggers(AsyncWebServerRequest *request)
|
|||||||
{
|
{
|
||||||
_dln("API :: get time triggers");
|
_dln("API :: get time triggers");
|
||||||
|
|
||||||
uint8_t count = timeTriggerSettings->triggerCount();
|
|
||||||
|
|
||||||
DynamicJsonBuffer jsonBuffer(JSON_ARRAY_SIZE(count) + JSON_OBJECT_SIZE(3) + count*JSON_OBJECT_SIZE(5));
|
|
||||||
JsonObject& root = jsonBuffer.createObject();
|
|
||||||
root["enabled"] = timeTriggerSettings->enabled();
|
|
||||||
root["transitionTime"] = timeTriggerSettings->transitionTime();
|
|
||||||
|
|
||||||
JsonArray& jsonTriggers = root.createNestedArray("triggers");
|
|
||||||
|
|
||||||
for (uint8_t i = 0; i < count; i++)
|
|
||||||
{
|
|
||||||
TimeTrigger* trigger = timeTriggerSettings->trigger(i);
|
|
||||||
|
|
||||||
JsonObject& jsonTrigger = jsonTriggers.createNestedObject();
|
|
||||||
jsonTrigger["time"] = trigger->time;
|
|
||||||
jsonTrigger["daysOfWeek"] = trigger->daysOfWeek;
|
|
||||||
jsonTrigger["brightness"] = trigger->brightness;
|
|
||||||
jsonTrigger["triggerType"] = (uint8_t)trigger->triggerType;
|
|
||||||
jsonTrigger["enabled"] = trigger->enabled;
|
|
||||||
}
|
|
||||||
|
|
||||||
AsyncResponseStream *response = request->beginResponseStream("application/json");
|
AsyncResponseStream *response = request->beginResponseStream("application/json");
|
||||||
root.printTo(*response);
|
timeTriggerSettings->toJson(*response);
|
||||||
|
|
||||||
request->send(response);
|
request->send(response);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -101,45 +79,48 @@ void handlePostTimeTriggers(AsyncWebServerRequest *request, uint8_t *data, size_
|
|||||||
{
|
{
|
||||||
_dln("API :: post time triggers");
|
_dln("API :: post time triggers");
|
||||||
|
|
||||||
DynamicJsonBuffer jsonBuffer(JSON_ARRAY_SIZE(10) + JSON_OBJECT_SIZE(3) + 10*JSON_OBJECT_SIZE(5) + 510);
|
bool changed;
|
||||||
JsonObject& root = jsonBuffer.parseObject((char*)data);
|
if (timeTriggerSettings->fromJson((char*)data, &changed))
|
||||||
if (!root.success())
|
|
||||||
{
|
{
|
||||||
request->send(400);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
JsonArray& jsonTriggers = root["triggers"];
|
|
||||||
if (jsonTriggers.size() > 255)
|
|
||||||
{
|
|
||||||
request->send(400);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
timeTriggerSettings->enabled(root["enabled"]);
|
|
||||||
timeTriggerSettings->transitionTime(root["transitionTime"]);
|
|
||||||
timeTriggerSettings->beginSetTriggers(jsonTriggers.size());
|
|
||||||
|
|
||||||
TimeTrigger trigger;
|
|
||||||
for (uint8_t i = 0; i < jsonTriggers.size(); i++)
|
|
||||||
{
|
|
||||||
JsonObject& jsonTrigger = jsonTriggers[i];
|
|
||||||
|
|
||||||
trigger.time = jsonTrigger["time"];
|
|
||||||
trigger.daysOfWeek = jsonTrigger["daysOfWeek"];
|
|
||||||
trigger.brightness = jsonTrigger["brightness"];
|
|
||||||
trigger.triggerType = (TimeTriggerType)(uint8_t)jsonTrigger["triggerType"];
|
|
||||||
trigger.enabled = jsonTrigger["enabled"];
|
|
||||||
|
|
||||||
timeTriggerSettings->setTrigger(i, &trigger);
|
|
||||||
}
|
|
||||||
|
|
||||||
timeTriggerSettings->endSetTriggers();
|
|
||||||
timeTriggerSettings->write();
|
timeTriggerSettings->write();
|
||||||
|
|
||||||
|
if (changed)
|
||||||
timeTriggerSettingsChanged = true;
|
timeTriggerSettingsChanged = true;
|
||||||
|
|
||||||
request->send(200);
|
request->send(200);
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
request->send(400);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void handleGetMotionTriggers(AsyncWebServerRequest *request)
|
||||||
|
{
|
||||||
|
_dln("API :: get motion triggers");
|
||||||
|
|
||||||
|
AsyncResponseStream *response = request->beginResponseStream("application/json");
|
||||||
|
motionTriggerSettings->toJson(*response);
|
||||||
|
request->send(response);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void handlePostMotionTriggers(AsyncWebServerRequest *request, uint8_t *data, size_t len, size_t index, size_t total)
|
||||||
|
{
|
||||||
|
_dln("API :: post motion triggers");
|
||||||
|
|
||||||
|
bool changed;
|
||||||
|
if (motionTriggerSettings->fromJson((char*)data, &changed))
|
||||||
|
{
|
||||||
|
motionTriggerSettings->write();
|
||||||
|
|
||||||
|
if (changed)
|
||||||
|
motionTriggerSettingsChanged = true;
|
||||||
|
|
||||||
|
request->send(200);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
request->send(400);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void registerAPIRoutes(AsyncWebServer* server)
|
void registerAPIRoutes(AsyncWebServer* server)
|
||||||
@ -149,4 +130,7 @@ void registerAPIRoutes(AsyncWebServer* server)
|
|||||||
|
|
||||||
server->on("/api/triggers/time", HTTP_GET, handleGetTimeTriggers);
|
server->on("/api/triggers/time", HTTP_GET, handleGetTimeTriggers);
|
||||||
server->on("/api/triggers/time", HTTP_POST, devNullRequest, devNullFileUpload, handlePostTimeTriggers);
|
server->on("/api/triggers/time", HTTP_POST, devNullRequest, devNullFileUpload, handlePostTimeTriggers);
|
||||||
|
|
||||||
|
server->on("/api/triggers/motion", HTTP_GET, handleGetMotionTriggers);
|
||||||
|
server->on("/api/triggers/motion", HTTP_POST, devNullRequest, devNullFileUpload, handlePostMotionTriggers);
|
||||||
}
|
}
|
@ -4,7 +4,7 @@
|
|||||||
*
|
*
|
||||||
* https://git.x2software.net/pub/Stairs
|
* https://git.x2software.net/pub/Stairs
|
||||||
*/
|
*/
|
||||||
#include "firmware.h"
|
#include "./firmware.h"
|
||||||
#include "../config.h"
|
#include "../config.h"
|
||||||
#include "../debug.h"
|
#include "../debug.h"
|
||||||
#include "../global.h"
|
#include "../global.h"
|
||||||
|
@ -4,11 +4,11 @@
|
|||||||
*
|
*
|
||||||
* https://git.x2software.net/pub/Stairs
|
* https://git.x2software.net/pub/Stairs
|
||||||
*/
|
*/
|
||||||
#include "settings.h"
|
#include "./settings.h"
|
||||||
#include <ArduinoJson.h>
|
#include <ArduinoJson.h>
|
||||||
#include <IPAddress.h>
|
#include <IPAddress.h>
|
||||||
#include <ESP8266WiFi.h>
|
#include <ESP8266WiFi.h>
|
||||||
#include "shared.h"
|
#include "./shared.h"
|
||||||
#include "../assets/version.h"
|
#include "../assets/version.h"
|
||||||
#include "../debug.h"
|
#include "../debug.h"
|
||||||
#include "../global.h"
|
#include "../global.h"
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
*
|
*
|
||||||
* https://git.x2software.net/pub/Stairs
|
* https://git.x2software.net/pub/Stairs
|
||||||
*/
|
*/
|
||||||
#include "shared.h"
|
#include "./shared.h"
|
||||||
|
|
||||||
void devNullRequest(AsyncWebServerRequest *request) {}
|
void devNullRequest(AsyncWebServerRequest *request) {}
|
||||||
void devNullFileUpload(AsyncWebServerRequest *request, const String& filename, size_t index, uint8_t *data, size_t len, bool final) {}
|
void devNullFileUpload(AsyncWebServerRequest *request, const String& filename, size_t index, uint8_t *data, size_t len, bool final) {}
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
*
|
*
|
||||||
* https://git.x2software.net/pub/Stairs
|
* https://git.x2software.net/pub/Stairs
|
||||||
*/
|
*/
|
||||||
#include "static.h"
|
#include "./static.h"
|
||||||
#include "../debug.h"
|
#include "../debug.h"
|
||||||
#include "../assets/html.h"
|
#include "../assets/html.h"
|
||||||
#include "../assets/js.h"
|
#include "../assets/js.h"
|
||||||
|
70
src/settings/abstractjson.cpp
Normal file
70
src/settings/abstractjson.cpp
Normal file
@ -0,0 +1,70 @@
|
|||||||
|
/*
|
||||||
|
* Stairs
|
||||||
|
* Copyright 2017 (c) Mark van Renswoude
|
||||||
|
*
|
||||||
|
* https://git.x2software.net/pub/Stairs
|
||||||
|
*/
|
||||||
|
#include "./abstractjson.h"
|
||||||
|
#include <FS.h>
|
||||||
|
|
||||||
|
|
||||||
|
void AbstractJsonSettings::read()
|
||||||
|
{
|
||||||
|
_d(getDebugPrefix()); _dln(" :: opening file");
|
||||||
|
File settingsFile = SPIFFS.open(getFilename(), "r");
|
||||||
|
if (!settingsFile)
|
||||||
|
{
|
||||||
|
_d(getDebugPrefix()); _dln(" :: failed to open file");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t size = settingsFile.size();
|
||||||
|
if (size > 1024)
|
||||||
|
{
|
||||||
|
_d(getDebugPrefix()); _dln(" :: file size is too large");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (size == 0)
|
||||||
|
{
|
||||||
|
_d(getDebugPrefix()); _dln(" :: zero size file");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::unique_ptr<char[]> buf(new char[size]);
|
||||||
|
settingsFile.readBytes(buf.get(), size);
|
||||||
|
|
||||||
|
_dln(buf.get());
|
||||||
|
|
||||||
|
if (fromJson(buf.get()))
|
||||||
|
{
|
||||||
|
_d(getDebugPrefix());
|
||||||
|
_dln(" :: read from file");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
_d(getDebugPrefix());
|
||||||
|
_dln(" :: failed to parse file");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void AbstractJsonSettings::write()
|
||||||
|
{
|
||||||
|
_d(getDebugPrefix()); _dln(" :: opening file for writing");
|
||||||
|
File settingsFile = SPIFFS.open(getFilename(), "w");
|
||||||
|
if (!settingsFile)
|
||||||
|
{
|
||||||
|
_d(getDebugPrefix()); _dln(" :: failed to open file for writing");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
toJson(settingsFile);
|
||||||
|
_d(getDebugPrefix()); _dln(" :: written to file");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool AbstractJsonSettings::fromJson(char* data)
|
||||||
|
{
|
||||||
|
return fromJson(data, nullptr);
|
||||||
|
}
|
28
src/settings/abstractjson.h
Normal file
28
src/settings/abstractjson.h
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
/*
|
||||||
|
* Stairs
|
||||||
|
* Copyright 2017 (c) Mark van Renswoude
|
||||||
|
*
|
||||||
|
* https://git.x2software.net/pub/Stairs
|
||||||
|
*/
|
||||||
|
#ifndef __settingsjson
|
||||||
|
#define __settingsjson
|
||||||
|
|
||||||
|
#include "../debug.h"
|
||||||
|
|
||||||
|
class AbstractJsonSettings
|
||||||
|
{
|
||||||
|
protected:
|
||||||
|
virtual const char* getFilename() = 0;
|
||||||
|
virtual const char* getDebugPrefix() = 0;
|
||||||
|
|
||||||
|
public:
|
||||||
|
void read();
|
||||||
|
void write();
|
||||||
|
|
||||||
|
virtual void toJson(Print &print) = 0;
|
||||||
|
virtual bool fromJson(char* data, bool* changed) = 0;
|
||||||
|
|
||||||
|
bool fromJson(char* data);
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
@ -4,65 +4,15 @@
|
|||||||
*
|
*
|
||||||
* https://git.x2software.net/pub/Stairs
|
* https://git.x2software.net/pub/Stairs
|
||||||
*/
|
*/
|
||||||
#include "connection.h"
|
#include "./connection.h"
|
||||||
#include <ArduinoJson.h>
|
#include <ArduinoJson.h>
|
||||||
#include <FS.h>
|
#include "./abstractjson.h"
|
||||||
#include "../debug.h"
|
#include "../debug.h"
|
||||||
#include "../global.h"
|
|
||||||
#include "../config.h"
|
#include "../config.h"
|
||||||
|
#include "../global.h"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void ConnectionSettings::read()
|
|
||||||
{
|
|
||||||
_dln("ConnectionSettings :: opening file");
|
|
||||||
File settingsFile = SPIFFS.open(ConnectionSettingsFile, "r");
|
|
||||||
if (!settingsFile)
|
|
||||||
{
|
|
||||||
_dln("ConnectionSettings :: failed to open file");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t size = settingsFile.size();
|
|
||||||
if (size > 1024)
|
|
||||||
{
|
|
||||||
_dln("ConnectionSettings :: file size is too large");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (size == 0)
|
|
||||||
{
|
|
||||||
_dln("ConnectionSettings :: zero size file");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::unique_ptr<char[]> buf(new char[size]);
|
|
||||||
settingsFile.readBytes(buf.get(), size);
|
|
||||||
|
|
||||||
_dln(buf.get());
|
|
||||||
|
|
||||||
if (fromJson(buf.get()))
|
|
||||||
_dln("ConnectionSettings :: read from file");
|
|
||||||
else
|
|
||||||
_dln("ConnectionSettings :: failed to parse file");
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void ConnectionSettings::write()
|
|
||||||
{
|
|
||||||
_dln("ConnectionSettings :: opening file for writing");
|
|
||||||
File settingsFile = SPIFFS.open(ConnectionSettingsFile, "w");
|
|
||||||
if (!settingsFile)
|
|
||||||
{
|
|
||||||
_dln("ConnectionSettings:: failed to open file for writing");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
toJson(settingsFile);
|
|
||||||
_dln("ConnectionSettings:: written to file");
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void ConnectionSettings::toJson(Print &print)
|
void ConnectionSettings::toJson(Print &print)
|
||||||
{
|
{
|
||||||
DynamicJsonBuffer jsonBuffer(JSON_OBJECT_SIZE(9));
|
DynamicJsonBuffer jsonBuffer(JSON_OBJECT_SIZE(9));
|
||||||
@ -82,12 +32,6 @@ void ConnectionSettings::toJson(Print &print)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool ConnectionSettings::fromJson(char* data)
|
|
||||||
{
|
|
||||||
return fromJson(data, nullptr);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
bool ConnectionSettings::fromJson(char* data, bool* changed)
|
bool ConnectionSettings::fromJson(char* data, bool* changed)
|
||||||
{
|
{
|
||||||
if (changed != nullptr)
|
if (changed != nullptr)
|
||||||
|
@ -10,7 +10,9 @@
|
|||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
#include <IPAddress.h>
|
#include <IPAddress.h>
|
||||||
|
#include "./abstractjson.h"
|
||||||
#include "../charproperties.h"
|
#include "../charproperties.h"
|
||||||
|
#include "../config.h"
|
||||||
|
|
||||||
|
|
||||||
enum ConnectionSettingsFlags
|
enum ConnectionSettingsFlags
|
||||||
@ -21,7 +23,7 @@ enum ConnectionSettingsFlags
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
class ConnectionSettings : CharProperties
|
class ConnectionSettings : public AbstractJsonSettings
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
char* mHostname = nullptr;
|
char* mHostname = nullptr;
|
||||||
@ -32,13 +34,12 @@ class ConnectionSettings : CharProperties
|
|||||||
IPAddress mSubnetMask = (uint32_t)0;
|
IPAddress mSubnetMask = (uint32_t)0;
|
||||||
IPAddress mGateway = (uint32_t)0;
|
IPAddress mGateway = (uint32_t)0;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
virtual const char* getFilename() { return ConnectionSettingsFile; };
|
||||||
|
virtual const char* getDebugPrefix() { return "ConnectionSettings"; };
|
||||||
|
|
||||||
public:
|
public:
|
||||||
void read();
|
|
||||||
void write();
|
|
||||||
|
|
||||||
|
|
||||||
void toJson(Print &print);
|
void toJson(Print &print);
|
||||||
bool fromJson(char* data);
|
|
||||||
bool fromJson(char* data, bool* changed);
|
bool fromJson(char* data, bool* changed);
|
||||||
|
|
||||||
|
|
||||||
|
@ -4,20 +4,11 @@
|
|||||||
*
|
*
|
||||||
* https://git.x2software.net/pub/Stairs
|
* https://git.x2software.net/pub/Stairs
|
||||||
*/
|
*/
|
||||||
#include "steps.h"
|
#include "./steps.h"
|
||||||
#include <FS.h>
|
#include <ArduinoJson.h>
|
||||||
#include "../debug.h"
|
#include "../debug.h"
|
||||||
|
|
||||||
|
|
||||||
struct Header
|
|
||||||
{
|
|
||||||
uint8_t version;
|
|
||||||
uint8_t stepCount;
|
|
||||||
bool useCurve;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
StepsSettings::StepsSettings()
|
StepsSettings::StepsSettings()
|
||||||
{
|
{
|
||||||
for (uint8_t i = 0; i < MaxStepCount; i++)
|
for (uint8_t i = 0; i < MaxStepCount; i++)
|
||||||
@ -25,41 +16,63 @@ StepsSettings::StepsSettings()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void StepsSettings::read()
|
void StepsSettings::toJson(Print &print)
|
||||||
{
|
{
|
||||||
_dln("StepsSettings :: Loading step settings");
|
DynamicJsonBuffer jsonBuffer(JSON_ARRAY_SIZE(16) + JSON_OBJECT_SIZE(3));
|
||||||
File f = SPIFFS.open(StepSettingsFile, "r");
|
|
||||||
if (!f)
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (!f.available())
|
JsonObject& root = jsonBuffer.createObject();
|
||||||
return;
|
root["count"] = count();
|
||||||
|
root["useCurve"] = useCurve();
|
||||||
|
|
||||||
Header header;
|
JsonArray& jsonCurveShift = root.createNestedArray("curveShift");
|
||||||
f.readBytes((char*)&header, sizeof(Header));
|
for (uint8_t step = 0; step < MaxStepCount; step++)
|
||||||
|
jsonCurveShift.add(curveShift(step));
|
||||||
|
|
||||||
if (header.version != 1)
|
root.printTo(print);
|
||||||
return;
|
|
||||||
|
|
||||||
mUseCurve = (header.useCurve == 1);
|
|
||||||
f.readBytes((char*)&mCurveShift, header.stepCount * sizeof(uint16_t));
|
|
||||||
f.close();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void StepsSettings::write()
|
bool StepsSettings::fromJson(char* data, bool* changed)
|
||||||
{
|
{
|
||||||
_dln("StepsSettings :: Saving step settings");
|
if (changed != nullptr)
|
||||||
File f = SPIFFS.open(StepSettingsFile, "w");
|
*changed = false;
|
||||||
if (!f)
|
|
||||||
return;
|
|
||||||
|
|
||||||
Header header;
|
DynamicJsonBuffer jsonBuffer(JSON_ARRAY_SIZE(16) + JSON_OBJECT_SIZE(3) + 80);
|
||||||
header.version = 1;
|
JsonObject& root = jsonBuffer.parseObject(data);
|
||||||
header.useCurve = mUseCurve;
|
|
||||||
header.stepCount = mCount;
|
|
||||||
|
|
||||||
f.write((uint8_t*)&header, sizeof(Header));
|
if (!root.success())
|
||||||
f.write((uint8_t*)&mCurveShift, header.stepCount * sizeof(uint16_t));
|
return false;
|
||||||
f.close();
|
|
||||||
|
uint8_t jsonCount = root["count"];
|
||||||
|
bool jsonUseCurve = root["useCurve"];
|
||||||
|
|
||||||
|
if (jsonCount != count() ||
|
||||||
|
jsonUseCurve != useCurve())
|
||||||
|
{
|
||||||
|
count(jsonCount);
|
||||||
|
useCurve(jsonUseCurve);
|
||||||
|
|
||||||
|
if (changed != nullptr)
|
||||||
|
*changed = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
JsonArray& jsonCurveShift = root["curveShift"];
|
||||||
|
uint8_t stepCount = jsonCurveShift.size();
|
||||||
|
if (stepCount >= MaxStepCount)
|
||||||
|
stepCount = MaxStepCount - 1;
|
||||||
|
|
||||||
|
for (uint8_t step = 0; step < stepCount; step++)
|
||||||
|
{
|
||||||
|
uint16_t value = jsonCurveShift[step];
|
||||||
|
|
||||||
|
if (value != curveShift(step))
|
||||||
|
{
|
||||||
|
curveShift(step, value);
|
||||||
|
if (changed != nullptr)
|
||||||
|
*changed = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
@ -8,22 +8,29 @@
|
|||||||
#define __settingssteps
|
#define __settingssteps
|
||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
#include "./abstractjson.h"
|
||||||
|
#include "../config.h"
|
||||||
|
|
||||||
#define MaxStepCount 16
|
#define MaxStepCount 16
|
||||||
|
|
||||||
|
|
||||||
class StepsSettings
|
class StepsSettings : public AbstractJsonSettings
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
uint8_t mCount = 16;
|
uint8_t mCount = MaxStepCount;
|
||||||
bool mUseCurve = true;
|
bool mUseCurve = true;
|
||||||
uint16_t mCurveShift[MaxStepCount];
|
uint16_t mCurveShift[MaxStepCount];
|
||||||
|
|
||||||
|
protected:
|
||||||
|
virtual const char* getFilename() { return StepsSettingsFile; };
|
||||||
|
virtual const char* getDebugPrefix() { return "StepsSettings"; };
|
||||||
|
|
||||||
public:
|
public:
|
||||||
StepsSettings();
|
StepsSettings();
|
||||||
|
|
||||||
void read();
|
void toJson(Print &print);
|
||||||
void write();
|
bool fromJson(char* data, bool* changed);
|
||||||
|
|
||||||
|
|
||||||
uint8_t count() { return mCount; }
|
uint8_t count() { return mCount; }
|
||||||
void count(uint8_t value) { mCount = value; }
|
void count(uint8_t value) { mCount = value; }
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
*
|
*
|
||||||
* https://git.x2software.net/pub/Stairs
|
* https://git.x2software.net/pub/Stairs
|
||||||
*/
|
*/
|
||||||
#include "system.h"
|
#include "./system.h"
|
||||||
#include <ArduinoJson.h>
|
#include <ArduinoJson.h>
|
||||||
#include <FS.h>
|
#include <FS.h>
|
||||||
#include "../debug.h"
|
#include "../debug.h"
|
||||||
@ -13,56 +13,6 @@
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
void SystemSettings::read()
|
|
||||||
{
|
|
||||||
_dln("SystemSettings :: opening file");
|
|
||||||
File settingsFile = SPIFFS.open(SystemSettingsFile, "r");
|
|
||||||
if (!settingsFile)
|
|
||||||
{
|
|
||||||
_dln("SystemSettings :: failed to open file");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t size = settingsFile.size();
|
|
||||||
if (size > 1024)
|
|
||||||
{
|
|
||||||
_dln("SystemSettings :: file size is too large");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (size == 0)
|
|
||||||
{
|
|
||||||
_dln("SystemSettings :: zero size file");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::unique_ptr<char[]> buf(new char[size]);
|
|
||||||
settingsFile.readBytes(buf.get(), size);
|
|
||||||
|
|
||||||
_dln(buf.get());
|
|
||||||
|
|
||||||
if (fromJson(buf.get()))
|
|
||||||
_dln("SystemSettings :: read from file");
|
|
||||||
else
|
|
||||||
_dln("SystemSettings :: failed to parse file");
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void SystemSettings::write()
|
|
||||||
{
|
|
||||||
_dln("SystemSettings :: opening file for writing");
|
|
||||||
File settingsFile = SPIFFS.open(SystemSettingsFile, "w");
|
|
||||||
if (!settingsFile)
|
|
||||||
{
|
|
||||||
_dln("SystemSettings:: failed to open file for writing");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
toJson(settingsFile);
|
|
||||||
_dln("SystemSettings:: written to file");
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void SystemSettings::toJson(Print &print)
|
void SystemSettings::toJson(Print &print)
|
||||||
{
|
{
|
||||||
DynamicJsonBuffer jsonBuffer(JSON_OBJECT_SIZE(6) + JSON_OBJECT_SIZE(5));
|
DynamicJsonBuffer jsonBuffer(JSON_OBJECT_SIZE(6) + JSON_OBJECT_SIZE(5));
|
||||||
@ -87,11 +37,6 @@ void SystemSettings::toJson(Print &print)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool SystemSettings::fromJson(char* data)
|
|
||||||
{
|
|
||||||
return fromJson(data, nullptr);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool SystemSettings::fromJson(char* data, bool* changed)
|
bool SystemSettings::fromJson(char* data, bool* changed)
|
||||||
{
|
{
|
||||||
if (changed != nullptr)
|
if (changed != nullptr)
|
||||||
|
@ -11,9 +11,10 @@
|
|||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
#include "../charproperties.h"
|
#include "../charproperties.h"
|
||||||
|
#include "./abstractjson.h"
|
||||||
|
|
||||||
|
|
||||||
class SystemSettings : CharProperties
|
class SystemSettings : public AbstractJsonSettings
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
double mLatitude = 0;
|
double mLatitude = 0;
|
||||||
@ -34,13 +35,12 @@ class SystemSettings : CharProperties
|
|||||||
// TODO loginUsername
|
// TODO loginUsername
|
||||||
// TODO loginPassword
|
// TODO loginPassword
|
||||||
|
|
||||||
|
protected:
|
||||||
|
virtual const char* getFilename() { return SystemSettingsFile; };
|
||||||
|
virtual const char* getDebugPrefix() { return "SystemSettings"; };
|
||||||
|
|
||||||
public:
|
public:
|
||||||
void read();
|
|
||||||
void write();
|
|
||||||
|
|
||||||
|
|
||||||
void toJson(Print &print);
|
void toJson(Print &print);
|
||||||
bool fromJson(char* data);
|
|
||||||
bool fromJson(char* data, bool* changed);
|
bool fromJson(char* data, bool* changed);
|
||||||
|
|
||||||
|
|
||||||
|
81
src/settings/triggers/motion.cpp
Normal file
81
src/settings/triggers/motion.cpp
Normal file
@ -0,0 +1,81 @@
|
|||||||
|
/*
|
||||||
|
* Stairs
|
||||||
|
* Copyright 2017 (c) Mark van Renswoude
|
||||||
|
*
|
||||||
|
* https://git.x2software.net/pub/Stairs
|
||||||
|
*/
|
||||||
|
#include "./motion.h"
|
||||||
|
#include <string.h>
|
||||||
|
#include <ArduinoJson.h>
|
||||||
|
#include "../../debug.h"
|
||||||
|
#include "../../global.h"
|
||||||
|
|
||||||
|
|
||||||
|
void MotionTriggerSettings::toJson(Print &print)
|
||||||
|
{
|
||||||
|
DynamicJsonBuffer jsonBuffer(JSON_ARRAY_SIZE(2) + 2*JSON_OBJECT_SIZE(4) + JSON_OBJECT_SIZE(5));
|
||||||
|
|
||||||
|
JsonObject& root = jsonBuffer.createObject();
|
||||||
|
root["enabled"] = enabled();
|
||||||
|
root["enabledDuringTimeTrigger"] = enabledDuringTimeTrigger();
|
||||||
|
root["transitionTime"] = transitionTime();
|
||||||
|
root["delay"] = delay();
|
||||||
|
|
||||||
|
JsonArray& jsonTriggers = root.createNestedArray("triggers");
|
||||||
|
|
||||||
|
for (uint8_t i = 0; i < triggerCount(); i++)
|
||||||
|
{
|
||||||
|
MotionTrigger* triggerItem = trigger(i);
|
||||||
|
|
||||||
|
JsonObject& jsonTrigger = jsonTriggers.createNestedObject();
|
||||||
|
jsonTrigger["pin"] = triggerItem->pin;
|
||||||
|
jsonTrigger["brightness"] = triggerItem->brightness;
|
||||||
|
jsonTrigger["direction"] = (uint8_t)triggerItem->direction;
|
||||||
|
jsonTrigger["enabled"] = triggerItem->enabled;
|
||||||
|
}
|
||||||
|
|
||||||
|
root.printTo(print);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool MotionTriggerSettings::fromJson(char* data, bool* changed)
|
||||||
|
{
|
||||||
|
if (changed != nullptr)
|
||||||
|
*changed = false;
|
||||||
|
|
||||||
|
DynamicJsonBuffer jsonBuffer(JSON_ARRAY_SIZE(2) + 2*JSON_OBJECT_SIZE(4) + JSON_OBJECT_SIZE(5) + 200);
|
||||||
|
JsonObject& root = jsonBuffer.parseObject(data);
|
||||||
|
|
||||||
|
if (!root.success())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
|
||||||
|
enabled(root["enabled"]);
|
||||||
|
enabledDuringTimeTrigger(root["enabledDuringTimeTrigger"]);
|
||||||
|
transitionTime(root["transitionTime"]);
|
||||||
|
delay(root["delay"]);
|
||||||
|
|
||||||
|
JsonArray& jsonTriggers = root["triggers"];
|
||||||
|
if (mTriggers != nullptr)
|
||||||
|
delete [] mTriggers;
|
||||||
|
|
||||||
|
mTriggerCount = jsonTriggers.size();
|
||||||
|
mTriggers = new MotionTrigger[mTriggerCount];
|
||||||
|
|
||||||
|
|
||||||
|
for (uint8_t i = 0; i < mTriggerCount; i++)
|
||||||
|
{
|
||||||
|
JsonObject& jsonTrigger = jsonTriggers[i];
|
||||||
|
MotionTrigger* trigger = &mTriggers[i];
|
||||||
|
|
||||||
|
trigger->pin = jsonTrigger["pin"];
|
||||||
|
trigger->brightness = jsonTrigger["brightness"];
|
||||||
|
trigger->direction = (MotionDirection)(uint8_t)jsonTrigger["direction"];
|
||||||
|
trigger->enabled = jsonTrigger["enabled"];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (changed != nullptr)
|
||||||
|
*changed = true;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
67
src/settings/triggers/motion.h
Normal file
67
src/settings/triggers/motion.h
Normal file
@ -0,0 +1,67 @@
|
|||||||
|
/*
|
||||||
|
* Stairs
|
||||||
|
* Copyright 2017 (c) Mark van Renswoude
|
||||||
|
*
|
||||||
|
* https://git.x2software.net/pub/Stairs
|
||||||
|
*/
|
||||||
|
#ifndef __settingstriggersmotion
|
||||||
|
#define __settingstriggersmotion
|
||||||
|
|
||||||
|
#include <Arduino.h>
|
||||||
|
#include "../../config.h"
|
||||||
|
#include "../abstractjson.h"
|
||||||
|
|
||||||
|
|
||||||
|
enum MotionDirection
|
||||||
|
{
|
||||||
|
Nondirectional = 1,
|
||||||
|
TopDown = 2,
|
||||||
|
BottomUp = 3
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
struct MotionTrigger
|
||||||
|
{
|
||||||
|
uint8_t pin;
|
||||||
|
uint8_t brightness;
|
||||||
|
MotionDirection direction;
|
||||||
|
bool enabled;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
class MotionTriggerSettings : public AbstractJsonSettings
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
bool mEnabled = false;
|
||||||
|
bool mEnabledDuringTimeTrigger = false;
|
||||||
|
uint16_t mTransitionTime = 0;
|
||||||
|
uint32_t mDelay = 0;
|
||||||
|
uint8_t mTriggerCount = 0;
|
||||||
|
MotionTrigger* mTriggers = nullptr;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
virtual const char* getFilename() { return MotionTriggerSettingsFile; };
|
||||||
|
virtual const char* getDebugPrefix() { return "MotionTriggerSettings"; };
|
||||||
|
|
||||||
|
public:
|
||||||
|
void toJson(Print &print);
|
||||||
|
bool fromJson(char* data, bool* changed);
|
||||||
|
|
||||||
|
|
||||||
|
bool enabled() { return mEnabled; }
|
||||||
|
void enabled(bool value) { mEnabled = value; }
|
||||||
|
|
||||||
|
bool enabledDuringTimeTrigger() { return mEnabledDuringTimeTrigger; }
|
||||||
|
void enabledDuringTimeTrigger(bool value) { mEnabledDuringTimeTrigger = value; }
|
||||||
|
|
||||||
|
uint16_t transitionTime() { return mTransitionTime; }
|
||||||
|
void transitionTime(uint16_t value) { mTransitionTime = value; }
|
||||||
|
|
||||||
|
uint32_t delay() { return mDelay; }
|
||||||
|
void delay(uint32_t value) { mDelay = value; }
|
||||||
|
|
||||||
|
uint8_t triggerCount() { return mTriggerCount; }
|
||||||
|
MotionTrigger* trigger(uint8_t index) { return &mTriggers[index]; }
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
@ -4,9 +4,9 @@
|
|||||||
*
|
*
|
||||||
* https://git.x2software.net/pub/Stairs
|
* https://git.x2software.net/pub/Stairs
|
||||||
*/
|
*/
|
||||||
#include "time.h"
|
#include "./time.h"
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <FS.h>
|
#include <ArduinoJson.h>
|
||||||
#include "../../debug.h"
|
#include "../../debug.h"
|
||||||
#include "../../global.h"
|
#include "../../global.h"
|
||||||
#include "../../praisethesun.h"
|
#include "../../praisethesun.h"
|
||||||
@ -46,62 +46,76 @@ DayOfWeek toDayOfWeek(timeDayOfWeek_t timeDay)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
struct Header
|
|
||||||
|
|
||||||
|
void TimeTriggerSettings::toJson(Print &print)
|
||||||
{
|
{
|
||||||
uint8_t version;
|
DynamicJsonBuffer jsonBuffer(JSON_ARRAY_SIZE(10) + JSON_OBJECT_SIZE(3) + 10*JSON_OBJECT_SIZE(5));
|
||||||
uint8_t triggerCount;
|
|
||||||
uint16_t transitionTime;
|
|
||||||
bool enabled;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
JsonObject& root = jsonBuffer.createObject();
|
||||||
|
root["enabled"] = enabled();
|
||||||
|
root["transitionTime"] = transitionTime();
|
||||||
|
|
||||||
void TimeTriggerSettings::read()
|
JsonArray& jsonTriggers = root.createNestedArray("triggers");
|
||||||
|
|
||||||
|
for (uint8_t i = 0; i < triggerCount(); i++)
|
||||||
{
|
{
|
||||||
_dln("TimeTriggerSettings :: Loading time triggers");
|
TimeTrigger* triggerItem = trigger(i);
|
||||||
File f = SPIFFS.open(TimeTriggerSettingsFile, "r");
|
|
||||||
if (!f)
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (!f.available())
|
JsonObject& jsonTrigger = jsonTriggers.createNestedObject();
|
||||||
return;
|
jsonTrigger["time"] = triggerItem->time;
|
||||||
|
jsonTrigger["daysOfWeek"] = triggerItem->daysOfWeek;
|
||||||
|
jsonTrigger["brightness"] = triggerItem->brightness;
|
||||||
|
jsonTrigger["triggerType"] = (uint8_t)triggerItem->triggerType;
|
||||||
|
jsonTrigger["enabled"] = triggerItem->enabled;
|
||||||
|
}
|
||||||
|
|
||||||
Header header;
|
root.printTo(print);
|
||||||
f.readBytes((char*)&header, sizeof(Header));
|
|
||||||
|
|
||||||
if (header.version != 1)
|
|
||||||
return;
|
|
||||||
|
|
||||||
mEnabled = header.enabled;
|
|
||||||
mTransitionTime = header.transitionTime;
|
|
||||||
beginSetTriggers(header.triggerCount);
|
|
||||||
|
|
||||||
if (header.triggerCount > 0)
|
|
||||||
f.readBytes((char*)&mTriggers, header.triggerCount * sizeof(TimeTrigger));
|
|
||||||
|
|
||||||
endSetTriggers();
|
|
||||||
|
|
||||||
f.close();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void TimeTriggerSettings::write()
|
bool TimeTriggerSettings::fromJson(char* data, bool* changed)
|
||||||
{
|
{
|
||||||
_dln("TimeTriggerSettings :: Saving time triggers");
|
if (changed != nullptr)
|
||||||
File f = SPIFFS.open(TimeTriggerSettingsFile, "w");
|
*changed = false;
|
||||||
if (!f)
|
|
||||||
return;
|
|
||||||
|
|
||||||
Header header;
|
DynamicJsonBuffer jsonBuffer(JSON_ARRAY_SIZE(10) + JSON_OBJECT_SIZE(3) + 10*JSON_OBJECT_SIZE(5) + 270);
|
||||||
header.version = 1;
|
JsonObject& root = jsonBuffer.parseObject(data);
|
||||||
header.enabled = mEnabled;
|
|
||||||
header.transitionTime = mTransitionTime;
|
|
||||||
header.triggerCount = mTriggerCount;
|
|
||||||
|
|
||||||
f.write((uint8_t*)&header, sizeof(Header));
|
if (!root.success())
|
||||||
f.write((uint8_t*)&mTriggers, header.triggerCount * sizeof(TimeTrigger));
|
return false;
|
||||||
f.close();
|
|
||||||
|
|
||||||
|
enabled(root["enabled"]);
|
||||||
|
transitionTime(root["transitionTime"]);
|
||||||
|
|
||||||
|
JsonArray& jsonTriggers = root["triggers"];
|
||||||
|
if (mTriggers != nullptr)
|
||||||
|
delete [] mTriggers;
|
||||||
|
|
||||||
|
mTriggerCount = jsonTriggers.size();
|
||||||
|
mTriggers = new TimeTrigger[mTriggerCount];
|
||||||
|
|
||||||
|
|
||||||
|
for (uint8_t i = 0; i < mTriggerCount; i++)
|
||||||
|
{
|
||||||
|
JsonObject& jsonTrigger = jsonTriggers[i];
|
||||||
|
TimeTrigger* trigger = &mTriggers[i];
|
||||||
|
|
||||||
|
trigger->time = jsonTrigger["time"];
|
||||||
|
trigger->daysOfWeek = jsonTrigger["daysOfWeek"];
|
||||||
|
trigger->brightness = jsonTrigger["brightness"];
|
||||||
|
trigger->triggerType = (TimeTriggerType)(uint8_t)jsonTrigger["triggerType"];
|
||||||
|
trigger->enabled = jsonTrigger["enabled"];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (changed != nullptr)
|
||||||
|
*changed = true;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
TimeTrigger* TimeTriggerSettings::getActiveTrigger(tmElements_t &time)
|
TimeTrigger* TimeTriggerSettings::getActiveTrigger(tmElements_t &time)
|
||||||
{
|
{
|
||||||
@ -176,55 +190,3 @@ TimeTrigger* TimeTriggerSettings::getActiveTrigger(tmElements_t &time)
|
|||||||
|
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void TimeTriggerSettings::beginSetTriggers(uint8_t count)
|
|
||||||
{
|
|
||||||
if (mTriggers != nullptr)
|
|
||||||
delete [] mTriggers;
|
|
||||||
|
|
||||||
mTriggers = new TimeTrigger[count];
|
|
||||||
mTriggerCount = count;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void TimeTriggerSettings::setTrigger(uint8_t index, TimeTrigger* value)
|
|
||||||
{
|
|
||||||
memcpy(&mTriggers[index], value, sizeof(TimeTrigger));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void TimeTriggerSettings::endSetTriggers()
|
|
||||||
{
|
|
||||||
/* No need to sort, sunrise / sunset triggers already mess things up anyways
|
|
||||||
// Sort triggers by time of day
|
|
||||||
// Based on the Comb sort implementation by Rob Tillaart
|
|
||||||
// http://forum.arduino.cc/index.php?topic=280486.0
|
|
||||||
uint8_t i, j;
|
|
||||||
uint8_t gap;
|
|
||||||
bool swapped = true;
|
|
||||||
TimeTrigger temp;
|
|
||||||
|
|
||||||
gap = mTriggerCount;
|
|
||||||
while (gap > 1 || swapped)
|
|
||||||
{
|
|
||||||
if (gap > 1)
|
|
||||||
{
|
|
||||||
gap = gap * 10/13;
|
|
||||||
if (gap == 9 || gap == 10) gap = 11;
|
|
||||||
}
|
|
||||||
|
|
||||||
swapped = false;
|
|
||||||
for (i = 0, j = gap; j < mTriggerCount; i++, j++)
|
|
||||||
{
|
|
||||||
if (mTriggers[i].time > mTriggers[j].time)
|
|
||||||
{
|
|
||||||
temp = mTriggers[i];
|
|
||||||
mTriggers[i] = mTriggers[j];
|
|
||||||
mTriggers[j] = temp;
|
|
||||||
swapped = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
}
|
|
@ -9,6 +9,8 @@
|
|||||||
|
|
||||||
#include <Arduino.h>
|
#include <Arduino.h>
|
||||||
#include <TimeLib.h>
|
#include <TimeLib.h>
|
||||||
|
#include "../../config.h"
|
||||||
|
#include "../abstractjson.h"
|
||||||
|
|
||||||
enum DayOfWeek
|
enum DayOfWeek
|
||||||
{
|
{
|
||||||
@ -44,7 +46,7 @@ struct TimeTrigger
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
class TimeTriggerSettings
|
class TimeTriggerSettings : public AbstractJsonSettings
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
bool mEnabled = false;
|
bool mEnabled = false;
|
||||||
@ -52,9 +54,13 @@ class TimeTriggerSettings
|
|||||||
uint8_t mTriggerCount = 0;
|
uint8_t mTriggerCount = 0;
|
||||||
TimeTrigger* mTriggers = nullptr;
|
TimeTrigger* mTriggers = nullptr;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
virtual const char* getFilename() { return ConnectionSettingsFile; };
|
||||||
|
virtual const char* getDebugPrefix() { return "ConnectionSettings"; };
|
||||||
|
|
||||||
public:
|
public:
|
||||||
void read();
|
void toJson(Print &print);
|
||||||
void write();
|
bool fromJson(char* data, bool* changed);
|
||||||
|
|
||||||
|
|
||||||
TimeTrigger* getActiveTrigger(tmElements_t &time);
|
TimeTrigger* getActiveTrigger(tmElements_t &time);
|
||||||
@ -68,10 +74,6 @@ class TimeTriggerSettings
|
|||||||
|
|
||||||
uint8_t triggerCount() { return mTriggerCount; }
|
uint8_t triggerCount() { return mTriggerCount; }
|
||||||
TimeTrigger* trigger(uint8_t index) { return &mTriggers[index]; }
|
TimeTrigger* trigger(uint8_t index) { return &mTriggers[index]; }
|
||||||
|
|
||||||
void beginSetTriggers(uint8_t count);
|
|
||||||
void setTrigger(uint8_t index, TimeTrigger* value);
|
|
||||||
void endSetTriggers();
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
@ -1,8 +1,8 @@
|
|||||||
#include "stairs.h"
|
#include "./stairs.h"
|
||||||
#include <Math.h>
|
#include <Math.h>
|
||||||
#include <FS.h>
|
#include <FS.h>
|
||||||
#include "debug.h"
|
#include "./debug.h"
|
||||||
#include "global.h"
|
#include "./global.h"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -1,9 +1,9 @@
|
|||||||
#ifndef __Stairs
|
#ifndef __Stairs
|
||||||
#define __Stairs
|
#define __Stairs
|
||||||
|
|
||||||
#include "components/PCA9685.h"
|
#include "./components/PCA9685.h"
|
||||||
#include "config.h"
|
#include "./config.h"
|
||||||
#include "settings/steps.h"
|
#include "./settings/steps.h"
|
||||||
|
|
||||||
struct Step
|
struct Step
|
||||||
{
|
{
|
||||||
|
Loading…
Reference in New Issue
Block a user