Merge pull request #8280 from pcdiem/device-groups-11

Add DGR light sequence support
This commit is contained in:
Theo Arends 2020-04-26 09:03:33 +02:00 committed by GitHub
commit 07c033e5d4
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 72 additions and 19 deletions

View File

@ -398,6 +398,7 @@
#define D_CMND_RGBWWTABLE "RGBWWTable"
#define D_CMND_ROTATION "Rotation"
#define D_CMND_SCHEME "Scheme"
#define D_CMND_SEQUENCE_OFFSET "SequenceOffset"
#define D_CMND_SPEED "Speed"
#define D_CMND_WAKEUP "Wakeup"
#define D_CMND_WAKEUPDURATION "WakeUpDuration"

View File

@ -426,7 +426,7 @@
#define DEVICE_GROUPS_PORT 4447 // Device groups multicast port
#define USE_DEVICE_GROUPS_SEND // Add support for the DevGroupSend command (+0k6 code)
#define USE_PWM_DIMMER // Add support for MJ-SD01/acenx/NTONPOWER PWM dimmers (+2k2 code, DGR=0k4)
#define USE_PWM_DIMMER_REMOTE // Add support for remote switches to PWM Dimmer, also adds device groups support (+0k9 code plus device groups size)
#define USE_PWM_DIMMER_REMOTE // Add support for remote switches to PWM Dimmer (requires USE_DEVICE_GROUPS) (+0k9 code)
//#define USE_KEELOQ // Add support for Jarolift rollers by Keeloq algorithm (+4k5 code)
#define USE_SONOFF_D1 // Add support for Sonoff D1 Dimmer (+0k7 code)
@ -441,6 +441,7 @@
#define USE_SONOFF_L1 // Add support for Sonoff L1 led control
#define USE_ELECTRIQ_MOODL // Add support for ElectriQ iQ-wifiMOODL RGBW LED controller (+0k3 code)
#define USE_LIGHT_PALETTE // Add support for color palette (+0k7 code)
#define USE_DGR_LIGHT_SEQUENCE // Add support for device group light sequencing (requires USE_DEVICE_GROUPS) (+0k2 code)
// -- Counter input -------------------------------
#define USE_COUNTER // Enable inputs as counter (+0k8 code)

View File

@ -350,7 +350,7 @@ void SendReceiveDeviceGroupMessage(struct device_group * device_group, struct de
else {
switch (item) {
case DGR_ITEM_LIGHT_CHANNELS:
log_length = snprintf(log_ptr, log_remaining, PSTR("%u,%u,%u,%u,%u"), *message_ptr, *(message_ptr + 1), *(message_ptr + 2), *(message_ptr + 3), *(message_ptr + 4));
log_length = snprintf(log_ptr, log_remaining, PSTR("%u,%u,%u,%u,%u,%u"), *message_ptr, *(message_ptr + 1), *(message_ptr + 2), *(message_ptr + 3), *(message_ptr + 4), *(message_ptr + 5));
break;
}
}
@ -549,7 +549,7 @@ bool _SendDeviceGroupMessage(uint8_t device_group_index, DevGroupMessageType mes
else {
switch (item) {
case DGR_ITEM_LIGHT_CHANNELS:
for (int i = 0; i < 5; i++) {
for (int i = 0; i < 6; i++) {
*out_ptr++ = strtoul((char *)value_ptr, (char **)&value_ptr, 0);
if (*value_ptr == ',') value_ptr++;
}
@ -665,7 +665,7 @@ bool _SendDeviceGroupMessage(uint8_t device_group_index, DevGroupMessageType mes
else {
switch (item) {
case DGR_ITEM_LIGHT_CHANNELS:
value = 5;
value = 6;
break;
}
}

View File

@ -114,15 +114,10 @@ extern "C" void resetPins();
#define MESSZ (MQTT_MAX_PACKET_SIZE -TOPSZ -7) // Max number of characters in JSON message string
#endif
#ifdef USE_PWM_DIMMER_REMOTE
#ifdef USE_PWM_DIMMER
#ifndef USE_DEVICE_GROUPS
#define USE_DEVICE_GROUPS
#endif // USE_DEVICE_GROUPS
#else // USE_PWM_DIMMER
#undef USE_PWM_DIMMER_REMOTE
#endif // USE_PWM_DIMMER
#endif // USE_PWM_DIMMER_REMOTE
#undef USE_DGR_LIGHT_SEQUENCE
#endif // USE_DEVICE_GROUPS
#ifndef DOMOTICZ_UPDATE_TIMER
#define DOMOTICZ_UPDATE_TIMER 0 // [DomoticzUpdateTimer] Send relay status (0 = disable, 1 - 3600 seconds) (Optional)

View File

@ -135,6 +135,9 @@ const char kLightCommands[] PROGMEM = "|" // No prefix
#ifdef USE_LIGHT_PALETTE
"|" D_CMND_PALETTE
#endif // USE_LIGHT_PALETTE
#ifdef USE_DGR_LIGHT_SEQUENCE
"|" D_CMND_SEQUENCE_OFFSET
#endif // USE_DGR_LIGHT_SEQUENCE
"|UNDOCA" ;
void (* const LightCommand[])(void) PROGMEM = {
@ -144,6 +147,9 @@ void (* const LightCommand[])(void) PROGMEM = {
#ifdef USE_LIGHT_PALETTE
&CmndPalette,
#endif // USE_LIGHT_PALETTE
#ifdef USE_DGR_LIGHT_SEQUENCE
&CmndSequenceOffset,
#endif // USE_DGR_LIGHT_SEQUENCE
&CmndUndocA };
// Light color mode, either RGB alone, or white-CT alone, or both only available if ct_rgb_linked is false
@ -284,6 +290,10 @@ struct LIGHT {
#ifdef USE_DEVICE_GROUPS
uint8_t last_scheme = 0;
bool devgrp_no_channels_out = false; // don't share channels with device group (e.g. if scheme set by other device)
#ifdef USE_DGR_LIGHT_SEQUENCE
uint8_t sequence_offset = 0; // number of channel changes this light is behind the master
uint8_t * channels_fifo;
#endif // USE_DGR_LIGHT_SEQUENCE
#endif // USE_DEVICE_GROUPS
#ifdef USE_LIGHT_PALETTE
uint8_t palette_count = 0; // palette entry count
@ -2225,16 +2235,22 @@ void calcGammaBulbs(uint16_t cur_col_10[5]) {
void LightSendDeviceGroupStatus(bool force)
{
static uint8_t last_channels[LST_MAX];
static uint8_t channels_sequence = 0;
static uint8_t last_bri;
uint8_t bri = light_state.getBri();
bool send_bri_update = (force || bri != last_bri);
if (Light.subtype > LST_SINGLE && !Light.devgrp_no_channels_out) {
uint8_t channels[LST_MAX];
uint8_t channels[LST_MAX + 1];
light_state.getChannels(channels);
if (force || memcmp(last_channels, channels, LST_MAX)) {
if (force || memcmp(last_channels, channels, LST_MAX)
#ifdef USE_LIGHT_PALETTE
|| (Settings.light_scheme && Light.palette_count)
#endif // USE_LIGHT_PALETTE
) {
memcpy(last_channels, channels, LST_MAX);
channels[LST_MAX] = ++channels_sequence;
SendLocalDeviceGroupMessage((send_bri_update ? DGR_MSGTYP_PARTIAL_UPDATE : DGR_MSGTYP_UPDATE), DGR_ITEM_LIGHT_CHANNELS, channels);
}
}
@ -2285,7 +2301,30 @@ void LightHandleDevGroupItem(void)
}
break;
case DGR_ITEM_LIGHT_CHANNELS:
#ifdef USE_DGR_LIGHT_SEQUENCE
{
static uint8_t last_sequence = 0;
// If a sequence offset is set, set the channels to the ones we received <SequenceOffset>
// changes ago.
if (Light.sequence_offset) {
light_controller.changeChannels(Light.channels_fifo);
// Shift the fifo down and load the newly received channels at the end for this update and
// any updates we missed.
int last_entry = (Light.sequence_offset - 1) * LST_MAX;
for (uint8_t sequence = (uint8_t)XdrvMailbox.data[LST_MAX]; (uint8_t)(sequence - last_sequence) > 0; last_sequence++) {
memmove(Light.channels_fifo, &Light.channels_fifo[LST_MAX], last_entry);
memcpy(&Light.channels_fifo[last_entry], XdrvMailbox.data, LST_MAX);
}
}
else {
#endif // USE_DGR_LIGHT_SEQUENCE
light_controller.changeChannels((uint8_t *)XdrvMailbox.data);
#ifdef USE_DGR_LIGHT_SEQUENCE
}
}
#endif // USE_DGR_LIGHT_SEQUENCE
send_state = true;
break;
case DGR_ITEM_LIGHT_FIXED_COLOR:
@ -2922,12 +2961,15 @@ void CmndPalette(void)
for (int entry = 0; entry < Light.palette_count; entry++) {
if (Settings.flag.decimal_text) { // SetOption17 - Switch between decimal or hexadecimal output
*p++ = '"';
for (uint32_t i = 0; i < Light.subtype; i++) {
p += sprintf_P(p, PSTR("%d,"), *palette_entry++);
}
*(p - 1) = '"';
}
else {
for (uint32_t i = 0; i < Light.subtype; i++) {
p += sprintf_P(p, PSTR("%02X"), *palette_entry++);
}
memcpy(Light.current_color, palette_entry, Light.subtype);
LightGetColor(p);
p += strlen(p);
if (Settings.flag.decimal_text) { // SetOption17 - Switch between decimal or hexadecimal output
*p++ = '"';
}
*p++ = ',';
}
@ -2939,6 +2981,20 @@ void CmndPalette(void)
}
#endif // USE_LIGHT_PALETTE
#ifdef USE_DGR_LIGHT_SEQUENCE
void CmndSequenceOffset(void)
{
if ((XdrvMailbox.payload >= 0) && (XdrvMailbox.payload <= 255)) {
if (XdrvMailbox.payload != Light.sequence_offset) {
if (Light.sequence_offset) free(Light.channels_fifo);
Light.sequence_offset = XdrvMailbox.payload;
if (Light.sequence_offset) Light.channels_fifo = (uint8_t *)calloc(Light.sequence_offset, LST_MAX);
}
}
ResponseCmndNumber(Light.sequence_offset);
}
#endif // USE_DGR_LIGHT_SEQUENCE
void CmndUndocA(void)
{
// Theos legacy status