mirror of
https://github.com/arendst/Tasmota.git
synced 2025-04-25 07:17:16 +00:00
Merge branch 'device-groups' of https://github.com/pcdiem/Tasmota into pwm-dimmer
This commit is contained in:
commit
d0bb1b36e4
@ -2,7 +2,7 @@
|
||||
|
||||
The device groups module provides a framework to allow multiple devices to be in a group with values such as power, light color/temperature/brightness, PWM values, sensor values, etc. shared with other devices in the group. For example, with multiple light modules in a device group, the light settings can be changed on one module and the settings will automatically be changed on the other light modules. Dimmer switch modules could be in a device group with light modules and the dimmer switch could control the power, brightness and colors of all the lights in the group. Multiple dimmer switches could be in a device group to form a 3-way/4-way dimmer switch.
|
||||
|
||||
UDP broadcasts, followed by UDP unicasts if necessary, are used to send updates to all devices so updates are fast. There is no need for an MQTT server but all the devices in a group must be on the same IP network.
|
||||
UDP multicasts, followed by UDP unicasts if necessary, are used to send updates to all devices so updates are fast. There is no need for an MQTT server but all the devices in a group must be on the same IP network.
|
||||
|
||||
To include device groups support in the build, define USE_DEVICE_GROUPS in your user_config_override. This adds 3.5K to the code size. All devices in a group must be running firmware with device group support and have device groups enabled.
|
||||
|
||||
@ -13,7 +13,7 @@ To enable device groups, set Option16 to 1 and **restart the device**.
|
||||
|
||||
The device group name is the MQTT group topic set with the GroupTopic command. All devices in the same IP network with the same group topic are in the same group. Some modules may define additional device groups. For example, if Remote Device Mode is enabled, the PWM Dimmer module defines three devices groups.
|
||||
|
||||
The items that are sent to the group and the items that are received from the group are selected with the DevGroupShare command. By default all items are sent and received from the group. An example of when the DevGroupShare command would be used is when you have a group of lights that you control with a dimmer switch and home automation software. You want the dimmer switch to be able to control all items. The home automation software controls each light individually. When it controls the whole group, it actually sends command to each light in the group. If you use the home automation software to turn an individual light on or off or change it’s brightness, color or scheme, you do not want the change to be replicated to the other lights. In this case, you would set the incoming and outgoing item masks to 255 on the dimmer switch (DevGroupShare 255,255) and set the incoming item mask to 255 and outgoing item mask to 0 on all the lights (DevGroupShare 255,0).
|
||||
The items that are sent to the group and the items that are received from the group are selected with the DevGroupShare command. By default all items are sent and received from the group. An example of when the DevGroupShare command would be used is when you have a group of lights that you control with a dimmer switch and home automation software. You want the dimmer switch to be able to control all items. The home automation software controls each light individually. When it controls the whole group, it actually sends command to each light in the group. If you use the home automation software to turn an individual light on or off or change it’s brightness, color or scheme, you do not want the change to be replicated to the other lights. In this case, you would set the incoming and outgoing item masks to 0xffffffff (all items) on the dimmer switch (DevGroupShare 0xffffffff,0xffffffff) and set the incoming item mask to 0xffffffff and outgoing item mask to 0 on all the lights (DevGroupShare 0xffffffff,0).
|
||||
|
||||
|
||||
### Commands
|
||||
@ -29,7 +29,7 @@ The items that are sent to the group and the items that are received from the gr
|
||||
<tr>
|
||||
<td>DevGroupShare
|
||||
</td>
|
||||
<td><in>,<out> = set incoming and outgoing shared item mask (default = 255,255)
|
||||
<td><in>,<out> = set incoming and outgoing shared item mask (default = 0xffffffff,0xffffffff)
|
||||
<p>
|
||||
1 = Power, 2 = Light brightness, 4 = Light fade/speed, 8 = Light scheme, 16 = Light color, 32 = Minimum brightness
|
||||
</td>
|
||||
|
@ -575,11 +575,6 @@ typedef union {
|
||||
ADC_MODE(ADC_VCC); // Set ADC input for Power Supply Voltage usage
|
||||
#endif
|
||||
|
||||
// Settings re-purposed for device groups
|
||||
#define device_groups_enabled ws_clock_reverse // SetOption16 - Enable device groups
|
||||
#define device_group_share_in domoticz_sensor_idx[0] // Bitmask of device group items imported
|
||||
#define device_group_share_out domoticz_sensor_idx[1] // Bitmask of device group items exported
|
||||
|
||||
// Settings re-purposed for the PWM_DIMMER module
|
||||
#ifdef USE_PWM_DIMMER
|
||||
#define led_timeout light_signal // SetOption18 - Turn brightness LED's off 5 seconds after last change
|
||||
|
@ -1677,7 +1677,7 @@ void CmndDevGroupShare(void)
|
||||
ParseParameters(2, parm);
|
||||
Settings.device_group_share_in = parm[0];
|
||||
Settings.device_group_share_out = parm[1];
|
||||
Response_P(PSTR("{\"" D_CMND_DEVGROUP_SHARE "\":{\"In\":%d,\"Out\":%d}}"), Settings.device_group_share_in, Settings.device_group_share_out);
|
||||
Response_P(PSTR("{\"" D_CMND_DEVGROUP_SHARE "\":{\"In\":%x,\"Out\":%x}}"), Settings.device_group_share_in, Settings.device_group_share_out);
|
||||
}
|
||||
#endif // USE_DEVICE_GROUPS
|
||||
|
||||
|
@ -49,7 +49,8 @@ struct device_group {
|
||||
|
||||
struct device_group * device_groups;
|
||||
uint16_t outgoing_sequence = 0;
|
||||
bool initialized = false;
|
||||
bool device_groups_initialized = false;
|
||||
bool device_groups_initialization_failed = false;
|
||||
bool building_status_message = false;
|
||||
bool processing_remote_device_message = false;
|
||||
bool waiting_for_acks;
|
||||
@ -57,21 +58,18 @@ bool udp_was_connected = false;
|
||||
|
||||
void DeviceGroupsInit(void)
|
||||
{
|
||||
/*
|
||||
Initialize the device information for each device group. The group name is the MQTT group topic.
|
||||
*/
|
||||
if (Settings.flag.device_groups_enabled) {
|
||||
// Initialize the device information for each device group. The group name is the MQTT group topic.
|
||||
device_groups = (struct device_group *)calloc(device_group_count, sizeof(struct device_group));
|
||||
if (device_groups == nullptr) {
|
||||
AddLog_P2(LOG_LEVEL_ERROR, "DGR: error allocating %u-element device group array", device_group_count);
|
||||
Settings.flag.device_groups_enabled = false;
|
||||
AddLog_P2(LOG_LEVEL_ERROR, PSTR("DGR: error allocating %u-element device group array"), device_group_count);
|
||||
device_groups_initialization_failed = true;
|
||||
return;
|
||||
}
|
||||
|
||||
for (uint32_t device_group_index = 0; device_group_index < device_group_count; device_group_index++) {
|
||||
struct device_group * device_group = &device_groups[device_group_index];
|
||||
strcpy(device_group->group_name, SettingsText((device_group_index == 0 ? SET_MQTT_GRP_TOPIC : SET_MQTT_GRP_TOPIC2 + device_group_index - 1)));
|
||||
device_group->message_header_length = sprintf(device_group->message, "%s%s HTTP/1.1\n\n", kDeviceGroupMessage, device_group->group_name);
|
||||
device_group->message_header_length = sprintf_P(device_group->message, PSTR("%s%s HTTP/1.1\n\n"), kDeviceGroupMessage, device_group->group_name);
|
||||
device_group->last_full_status_sequence = -1;
|
||||
}
|
||||
|
||||
@ -79,17 +77,16 @@ void DeviceGroupsInit(void)
|
||||
|
||||
// If both in and out shared items masks are 0, assume they're unitialized and initialize them.
|
||||
if (!Settings.device_group_share_in && !Settings.device_group_share_out) {
|
||||
Settings.device_group_share_in = Settings.device_group_share_out = 0xff;
|
||||
Settings.device_group_share_in = Settings.device_group_share_out = 0xffffffff;
|
||||
}
|
||||
|
||||
initialized = true;
|
||||
}
|
||||
device_groups_initialized = true;
|
||||
}
|
||||
|
||||
char * IPAddressToString(const IPAddress& ip_address)
|
||||
{
|
||||
static char buffer[16];
|
||||
sprintf(buffer, "%u.%u.%u.%u", ip_address[0], ip_address[1], ip_address[2], ip_address[3]);
|
||||
sprintf_P(buffer, PSTR("%u.%u.%u.%u"), ip_address[0], ip_address[1], ip_address[2], ip_address[3]);
|
||||
return buffer;
|
||||
}
|
||||
|
||||
@ -131,13 +128,13 @@ void SendDeviceGroupPacket(IPAddress ip, char * packet, int len, const char * la
|
||||
}
|
||||
delay(10);
|
||||
}
|
||||
AddLog_P2(LOG_LEVEL_ERROR, "DGR: error sending %s packet", label);
|
||||
AddLog_P2(LOG_LEVEL_ERROR, PSTR("DGR: error sending %s packet"), label);
|
||||
}
|
||||
|
||||
void _SendDeviceGroupMessage(uint8_t device_group_index, DeviceGroupMessageType message_type, ...)
|
||||
{
|
||||
// If device groups are not enabled, ignore this request.
|
||||
if (!Settings.flag.device_groups_enabled) return;
|
||||
if (!Settings.flag4.device_groups_enabled) return;
|
||||
|
||||
// If UDP is not set up, ignore this request.
|
||||
if (!udp_connected) return;
|
||||
@ -152,7 +149,7 @@ void _SendDeviceGroupMessage(uint8_t device_group_index, DeviceGroupMessageType
|
||||
if (device_group->initial_status_requests_remaining) return;
|
||||
|
||||
// A full status request is a request from a remote device for the status of every item we
|
||||
// control. As long as we're building it, we may as well broadcast the status update to all
|
||||
// control. As long as we're building it, we may as well multicast the status update to all
|
||||
// device group members.
|
||||
char * message_ptr = &device_group->message[device_group->message_header_length];
|
||||
if (message_type == DGR_MSGTYP_FULL_STATUS) {
|
||||
@ -164,10 +161,10 @@ void _SendDeviceGroupMessage(uint8_t device_group_index, DeviceGroupMessageType
|
||||
// Call the drivers to build the status update.
|
||||
if (!++outgoing_sequence) outgoing_sequence = 1;
|
||||
#ifdef DEVICE_GROUPS_DEBUG
|
||||
AddLog_P2(LOG_LEVEL_DEBUG, "Building device group %s full status packet", device_group->group_name);
|
||||
AddLog_P2(LOG_LEVEL_DEBUG, PSTR("Building device group %s full status packet"), device_group->group_name);
|
||||
#endif // DEVICE_GROUPS_DEBUG
|
||||
device_group->message_length = 0;
|
||||
_SendDeviceGroupMessage(device_group_index, DGR_MSGTYP_PARTIAL_UPDATE, DGR_ITEM_POWER, power);
|
||||
SendDeviceGroupMessage(device_group_index, DGR_MSGTYP_PARTIAL_UPDATE, DGR_ITEM_POWER, power);
|
||||
XdrvMailbox.command_code = DGR_ITEM_STATUS;
|
||||
XdrvCall(FUNC_DEVICE_GROUP_REQUEST);
|
||||
building_status_message = false;
|
||||
@ -191,7 +188,7 @@ void _SendDeviceGroupMessage(uint8_t device_group_index, DeviceGroupMessageType
|
||||
va_list ap;
|
||||
|
||||
#ifdef DEVICE_GROUPS_DEBUG
|
||||
AddLog_P2(LOG_LEVEL_DEBUG, "Building device group %s packet", device_group->group_name);
|
||||
AddLog_P2(LOG_LEVEL_DEBUG, PSTR("Building device group %s packet"), device_group->group_name);
|
||||
#endif // DEVICE_GROUPS_DEBUG
|
||||
uint16_t original_sequence = outgoing_sequence;
|
||||
if (!building_status_message && message_type != DGR_MSGTYP_PARTIAL_UPDATE && !++outgoing_sequence) outgoing_sequence = 1;
|
||||
@ -204,7 +201,7 @@ void _SendDeviceGroupMessage(uint8_t device_group_index, DeviceGroupMessageType
|
||||
else if (message_type == DGR_MSGTYP_UPDATE_DIRECT)
|
||||
value |= DGR_FLAG_DIRECT;
|
||||
#ifdef DEVICE_GROUPS_DEBUG
|
||||
AddLog_P2(LOG_LEVEL_DEBUG, ">sequence=%u, flags=%u", outgoing_sequence, value);
|
||||
AddLog_P2(LOG_LEVEL_DEBUG, PSTR(">sequence=%u, flags=%u"), outgoing_sequence, value);
|
||||
#endif // DEVICE_GROUPS_DEBUG
|
||||
*message_ptr++ = value & 0xff;
|
||||
*message_ptr++ = value >> 8;
|
||||
@ -303,7 +300,7 @@ void _SendDeviceGroupMessage(uint8_t device_group_index, DeviceGroupMessageType
|
||||
}
|
||||
}
|
||||
#ifdef DEVICE_GROUPS_DEBUG
|
||||
AddLog_P2(LOG_LEVEL_DEBUG, "%u items carried over from previous update", kept_item_count);
|
||||
AddLog_P2(LOG_LEVEL_DEBUG, PSTR("%u items carried over from previous update"), kept_item_count);
|
||||
#endif // DEVICE_GROUPS_DEBUG
|
||||
}
|
||||
|
||||
@ -316,7 +313,7 @@ void _SendDeviceGroupMessage(uint8_t device_group_index, DeviceGroupMessageType
|
||||
value = va_arg(ap, int);
|
||||
if (shared) {
|
||||
#ifdef DEVICE_GROUPS_DEBUG
|
||||
AddLog_P2(LOG_LEVEL_DEBUG, ">item=%u, value=%u", item, value);
|
||||
AddLog_P2(LOG_LEVEL_DEBUG, PSTR(">item=%u, value=%u"), item, value);
|
||||
#endif // DEVICE_GROUPS_DEBUG
|
||||
*message_ptr++ = value & 0xff;
|
||||
if (item > DGR_ITEM_MAX_8BIT) {
|
||||
@ -335,7 +332,7 @@ void _SendDeviceGroupMessage(uint8_t device_group_index, DeviceGroupMessageType
|
||||
if (shared) {
|
||||
value = strlen((const char *)value_ptr);
|
||||
#ifdef DEVICE_GROUPS_DEBUG
|
||||
AddLog_P2(LOG_LEVEL_DEBUG, ">item=%u, value=%s", item, value_ptr);
|
||||
AddLog_P2(LOG_LEVEL_DEBUG, PSTR(">item=%u, value=%s"), item, value_ptr);
|
||||
#endif // DEVICE_GROUPS_DEBUG
|
||||
*message_ptr++ = value;
|
||||
memcpy(message_ptr, value_ptr, value);
|
||||
@ -348,7 +345,7 @@ void _SendDeviceGroupMessage(uint8_t device_group_index, DeviceGroupMessageType
|
||||
value_ptr = va_arg(ap, uint8_t *);
|
||||
if (shared) {
|
||||
#ifdef DEVICE_GROUPS_DEBUG
|
||||
AddLog_P2(LOG_LEVEL_DEBUG, ">item=%u, value=%u,%u,%u,%u,%u", item, *value_ptr, *(value_ptr + 1), *(value_ptr + 2), *(value_ptr + 3), *(value_ptr + 4));
|
||||
AddLog_P2(LOG_LEVEL_DEBUG, PSTR(">item=%u, value=%u,%u,%u,%u,%u"), item, *value_ptr, *(value_ptr + 1), *(value_ptr + 2), *(value_ptr + 3), *(value_ptr + 4));
|
||||
#endif // DEVICE_GROUPS_DEBUG
|
||||
memmove(message_ptr, value_ptr, 5);
|
||||
message_ptr += 5;
|
||||
@ -374,11 +371,11 @@ void _SendDeviceGroupMessage(uint8_t device_group_index, DeviceGroupMessageType
|
||||
if (building_status_message || message_type == DGR_MSGTYP_PARTIAL_UPDATE) return;
|
||||
}
|
||||
|
||||
// Broadcast the packet.
|
||||
// Multicast the packet.
|
||||
#ifdef DEVICE_GROUPS_DEBUG
|
||||
AddLog_P2(LOG_LEVEL_DEBUG, "DGR: sending %u-byte device group %s packet via broadcast, sequence=%u", device_group->message_length, device_group->group_name, device_group->message[device_group->message_header_length] | device_group->message[device_group->message_header_length + 1] << 8);
|
||||
AddLog_P2(LOG_LEVEL_DEBUG, PSTR("DGR: sending %u-byte device group %s packet via multicast, sequence=%u"), device_group->message_length, device_group->group_name, device_group->message[device_group->message_header_length] | device_group->message[device_group->message_header_length + 1] << 8);
|
||||
#endif // DEVICE_GROUPS_DEBUG
|
||||
SendDeviceGroupPacket(IPAddress(239,255,255,250), device_group->message, device_group->message_length, "Broadcast");
|
||||
SendDeviceGroupPacket(IPAddress(239,255,255,250), device_group->message, device_group->message_length, PSTR("Multicast"));
|
||||
device_group->next_ack_check_time = millis() + 100;
|
||||
|
||||
if (message_type == DGR_MSGTYP_UPDATE_MORE_TO_COME) {
|
||||
@ -418,11 +415,11 @@ void ProcessDeviceGroupMessage(char * packet, int packet_length)
|
||||
if (!device_group_member) {
|
||||
device_group_member = (struct device_group_member *)calloc(1, sizeof(struct device_group_member));
|
||||
if (device_group_member == nullptr) {
|
||||
AddLog_P2(LOG_LEVEL_ERROR, "DGR: error allocating device group member block");
|
||||
AddLog_P2(LOG_LEVEL_ERROR, PSTR("DGR: error allocating device group member block"));
|
||||
return;
|
||||
}
|
||||
#ifdef DEVICE_GROUPS_DEBUG
|
||||
AddLog_P2(LOG_LEVEL_DEBUG, "DGR: adding member %s (%p)", IPAddressToString(remote_ip), device_group_member);
|
||||
AddLog_P2(LOG_LEVEL_DEBUG, PSTR("DGR: adding member %s (%p)"), IPAddressToString(remote_ip), device_group_member);
|
||||
#endif // DEVICE_GROUPS_DEBUG
|
||||
device_group_member->ip_address = remote_ip;
|
||||
*flink = device_group_member;
|
||||
@ -435,7 +432,7 @@ void ProcessDeviceGroupMessage(char * packet, int packet_length)
|
||||
}
|
||||
|
||||
// Find the start of the actual message (after the http header).
|
||||
message_ptr = strstr(message_ptr, "\n\n");
|
||||
message_ptr = strstr_P(message_ptr, PSTR("\n\n"));
|
||||
if (message_ptr == nullptr) return;
|
||||
message_ptr += 2;
|
||||
|
||||
@ -452,7 +449,7 @@ void ProcessDeviceGroupMessage(char * packet, int packet_length)
|
||||
flags = *message_ptr++;
|
||||
flags |= *message_ptr++ << 8;
|
||||
#ifdef DEVICE_GROUPS_DEBUG
|
||||
AddLog_P2(LOG_LEVEL_DEBUG, "Received device group %s packet from %s: sequence=%u, flags=%u", device_group->group_name, IPAddressToString(remote_ip), message_sequence, flags);
|
||||
AddLog_P2(LOG_LEVEL_DEBUG, PSTR("Received device group %s packet from %s: sequence=%u, flags=%u"), device_group->group_name, IPAddressToString(remote_ip), message_sequence, flags);
|
||||
#endif // DEVICE_GROUPS_DEBUG
|
||||
|
||||
// If this is an ack message, save the message sequence if it's newwer than the last ack we
|
||||
@ -463,7 +460,7 @@ void ProcessDeviceGroupMessage(char * packet, int packet_length)
|
||||
}
|
||||
device_group_member->timeout_time = 0;
|
||||
#ifdef DEVICE_GROUPS_DEBUG
|
||||
AddLog_P2(LOG_LEVEL_DEBUG, "<ack");
|
||||
AddLog_P2(LOG_LEVEL_DEBUG, PSTR("<ack"));
|
||||
#endif // DEVICE_GROUPS_DEBUG
|
||||
return;
|
||||
}
|
||||
@ -472,7 +469,7 @@ void ProcessDeviceGroupMessage(char * packet, int packet_length)
|
||||
if (!(flags & DGR_FLAG_MORE_TO_COME)) {
|
||||
*(message_ptr - 2) = DGR_FLAG_ACK;
|
||||
*(message_ptr - 1) = 0;
|
||||
SendDeviceGroupPacket(remote_ip, packet, message_ptr - packet, "Ack");
|
||||
SendDeviceGroupPacket(remote_ip, packet, message_ptr - packet, PSTR("Ack"));
|
||||
}
|
||||
|
||||
// If this is a status request message, then if the requestor didn't just ack our previous full
|
||||
@ -482,7 +479,7 @@ void ProcessDeviceGroupMessage(char * packet, int packet_length)
|
||||
_SendDeviceGroupMessage(device_group_index, DGR_MSGTYP_FULL_STATUS);
|
||||
}
|
||||
#ifdef DEVICE_GROUPS_DEBUG
|
||||
AddLog_P2(LOG_LEVEL_DEBUG, "<status request");
|
||||
AddLog_P2(LOG_LEVEL_DEBUG, PSTR("<status request"));
|
||||
#endif // DEVICE_GROUPS_DEBUG
|
||||
return;
|
||||
}
|
||||
@ -490,7 +487,7 @@ void ProcessDeviceGroupMessage(char * packet, int packet_length)
|
||||
// If we already processed this or a later message from this group member, ignore this message.
|
||||
if (message_sequence < device_group_member->received_sequence && device_group_member->received_sequence - message_sequence > 64536) {
|
||||
#ifdef DEVICE_GROUPS_DEBUG
|
||||
AddLog_P2(LOG_LEVEL_DEBUG, "<old message");
|
||||
AddLog_P2(LOG_LEVEL_DEBUG, PSTR("<old message"));
|
||||
#endif // DEVICE_GROUPS_DEBUG
|
||||
return;
|
||||
}
|
||||
@ -537,7 +534,7 @@ void ProcessDeviceGroupMessage(char * packet, int packet_length)
|
||||
case DGR_ITEM_LIGHT_CHANNELS:
|
||||
break;
|
||||
default:
|
||||
AddLog_P2(LOG_LEVEL_ERROR, "DGR: ********** invalid item=%u received from device group %s member %s", item, device_group->group_name, IPAddressToString(remote_ip));
|
||||
AddLog_P2(LOG_LEVEL_ERROR, PSTR("DGR: ********** invalid item=%u received from device group %s member %s"), item, device_group->group_name, IPAddressToString(remote_ip));
|
||||
}
|
||||
#endif // DEVICE_GROUPS_DEBUG
|
||||
|
||||
@ -555,7 +552,7 @@ void ProcessDeviceGroupMessage(char * packet, int packet_length)
|
||||
light_fade = value;
|
||||
}
|
||||
#ifdef DEVICE_GROUPS_DEBUG
|
||||
AddLog_P2(LOG_LEVEL_DEBUG, "<item=%u, value=%u", item, value);
|
||||
AddLog_P2(LOG_LEVEL_DEBUG, PSTR("<item=%u, value=%u"), item, value);
|
||||
#endif // DEVICE_GROUPS_DEBUG
|
||||
XdrvMailbox.payload = value;
|
||||
}
|
||||
@ -563,7 +560,7 @@ void ProcessDeviceGroupMessage(char * packet, int packet_length)
|
||||
value = *message_ptr++;
|
||||
if (value >= packet_length - (message_ptr - packet)) goto badmsg; // Malformed message
|
||||
#ifdef DEVICE_GROUPS_DEBUG
|
||||
AddLog_P2(LOG_LEVEL_DEBUG, "<item=%u, value=%.*s", item, value, message_ptr);
|
||||
AddLog_P2(LOG_LEVEL_DEBUG, PSTR("<item=%u, value=%.*s"), item, value, message_ptr);
|
||||
#endif // DEVICE_GROUPS_DEBUG
|
||||
XdrvMailbox.data_len = value;
|
||||
XdrvMailbox.data = message_ptr;
|
||||
@ -573,7 +570,7 @@ void ProcessDeviceGroupMessage(char * packet, int packet_length)
|
||||
switch (item) {
|
||||
case DGR_ITEM_LIGHT_CHANNELS:
|
||||
#ifdef DEVICE_GROUPS_DEBUG
|
||||
AddLog_P2(LOG_LEVEL_DEBUG, "<item=%u, value=%u,%u,%u,%u,%u", item, *message_ptr, *(message_ptr + 1), *(message_ptr + 2), *(message_ptr + 3), *(message_ptr + 4));
|
||||
AddLog_P2(LOG_LEVEL_DEBUG, PSTR("<item=%u, value=%u,%u,%u,%u,%u"), item, *message_ptr, *(message_ptr + 1), *(message_ptr + 2), *(message_ptr + 3), *(message_ptr + 4));
|
||||
#endif // DEVICE_GROUPS_DEBUG
|
||||
XdrvMailbox.data = message_ptr;
|
||||
message_ptr += 5;
|
||||
@ -601,28 +598,27 @@ void ProcessDeviceGroupMessage(char * packet, int packet_length)
|
||||
|
||||
processing_remote_device_message = false;
|
||||
#ifdef DEVICE_GROUPS_DEBUG
|
||||
AddLog_P2(LOG_LEVEL_DEBUG, "<processed");
|
||||
AddLog_P2(LOG_LEVEL_DEBUG, PSTR("<processed"));
|
||||
#endif // DEVICE_GROUPS_DEBUG
|
||||
return;
|
||||
|
||||
badmsg:
|
||||
AddLog_P2(LOG_LEVEL_ERROR, "DGR: malformed message received from %s", IPAddressToString(remote_ip));
|
||||
AddLog_P2(LOG_LEVEL_ERROR, PSTR("DGR: malformed message received from %s"), IPAddressToString(remote_ip));
|
||||
#ifdef DEVICE_GROUPS_DEBUG
|
||||
AddLog_P2(LOG_LEVEL_DEBUG, "packet_length=%u, offset=%u", packet_length, message_ptr - packet);
|
||||
AddLog_P2(LOG_LEVEL_DEBUG, PSTR("packet_length=%u, offset=%u"), packet_length, message_ptr - packet);
|
||||
#endif // DEVICE_GROUPS_DEBUG
|
||||
processing_remote_device_message = false;
|
||||
}
|
||||
|
||||
void DeviceGroupsLoop(void)
|
||||
{
|
||||
if (!Settings.flag.device_groups_enabled) return;
|
||||
if (!Settings.flag4.device_groups_enabled) return;
|
||||
if (udp_connected) {
|
||||
if (!udp_was_connected) {
|
||||
udp_was_connected = true;
|
||||
if (!initialized) {
|
||||
DeviceGroupsInit();
|
||||
if (!Settings.flag.device_groups_enabled) return;
|
||||
}
|
||||
|
||||
if (!device_groups_initialized) DeviceGroupsInit();
|
||||
if (device_groups_initialization_failed) return;
|
||||
|
||||
for (uint32_t device_group_index = 0; device_group_index < device_group_count; device_group_index++) {
|
||||
device_group * device_group = &device_groups[device_group_index];
|
||||
@ -634,12 +630,14 @@ void DeviceGroupsLoop(void)
|
||||
*message_ptr++ = 0;
|
||||
device_group->message_length = message_ptr - device_group->message;
|
||||
device_group->initial_status_requests_remaining = 5;
|
||||
device_group->next_ack_check_time = millis() + 2000;
|
||||
device_group->next_ack_check_time = millis() + 1000;
|
||||
}
|
||||
|
||||
waiting_for_acks = true;
|
||||
}
|
||||
|
||||
if (device_groups_initialization_failed) return;
|
||||
|
||||
if (waiting_for_acks) {
|
||||
uint32_t now = millis();
|
||||
waiting_for_acks = false;
|
||||
@ -649,10 +647,10 @@ void DeviceGroupsLoop(void)
|
||||
if (device_group->next_ack_check_time <= now) {
|
||||
if (device_group->initial_status_requests_remaining) {
|
||||
#ifdef DEVICE_GROUPS_DEBUG
|
||||
AddLog_P2(LOG_LEVEL_DEBUG, "DGR: sending initial status request for group %s", device_group->group_name);
|
||||
AddLog_P2(LOG_LEVEL_DEBUG, PSTR("DGR: sending initial status request for group %s"), device_group->group_name);
|
||||
#endif // DEVICE_GROUPS_DEBUG
|
||||
if (--device_group->initial_status_requests_remaining) {
|
||||
SendDeviceGroupPacket(IPAddress(239,255,255,250), device_group->message, device_group->message_length, "Initial");
|
||||
SendDeviceGroupPacket(IPAddress(239,255,255,250), device_group->message, device_group->message_length, PSTR("Initial"));
|
||||
device_group->message[device_group->message_header_length + 2] = DGR_FLAG_STATUS_REQUEST; // The reset flag is on only for the first packet - turn it off now
|
||||
device_group->next_ack_check_time = now + 200;
|
||||
waiting_for_acks = true;
|
||||
@ -671,16 +669,16 @@ void DeviceGroupsLoop(void)
|
||||
|
||||
if (device_group_member->timeout_time && device_group_member->timeout_time < now) {
|
||||
#ifdef DEVICE_GROUPS_DEBUG
|
||||
AddLog_P2(LOG_LEVEL_DEBUG, "DGR: removing member %s (%p)", IPAddressToString(device_group_member->ip_address), device_group_member);
|
||||
AddLog_P2(LOG_LEVEL_DEBUG, PSTR("DGR: removing member %s (%p)"), IPAddressToString(device_group_member->ip_address), device_group_member);
|
||||
#endif // DEVICE_GROUPS_DEBUG
|
||||
*flink = device_group_member->flink;
|
||||
free(device_group_member);
|
||||
}
|
||||
else {
|
||||
#ifdef DEVICE_GROUPS_DEBUG
|
||||
AddLog_P2(LOG_LEVEL_DEBUG, "DGR: sending %u-byte device group %s packet via unicast to %s, sequence %u, last message acked=%u", device_group->message_length, device_group->group_name, IPAddressToString(device_group_member->ip_address), outgoing_sequence, device_group_member->acked_sequence);
|
||||
AddLog_P2(LOG_LEVEL_DEBUG, PSTR("DGR: sending %u-byte device group %s packet via unicast to %s, sequence %u, last message acked=%u"), device_group->message_length, device_group->group_name, IPAddressToString(device_group_member->ip_address), outgoing_sequence, device_group_member->acked_sequence);
|
||||
#endif // DEVICE_GROUPS_DEBUG
|
||||
SendDeviceGroupPacket(device_group_member->ip_address, device_group->message, device_group->message_length, "Unicast");
|
||||
SendDeviceGroupPacket(device_group_member->ip_address, device_group->message, device_group->message_length, PSTR("Unicast"));
|
||||
if (!device_group_member->timeout_time) device_group_member->timeout_time = now + 15000;
|
||||
acked = false;
|
||||
flink = &device_group_member->flink;
|
||||
|
@ -137,7 +137,7 @@ void PollUdp(void)
|
||||
}
|
||||
|
||||
#ifdef USE_DEVICE_GROUPS
|
||||
if (Settings.flag.device_groups_enabled && !strncmp_P(packet_buffer, kDeviceGroupMessage, sizeof(DEVICE_GROUP_MESSAGE) - 1)) {
|
||||
if (Settings.flag4.device_groups_enabled && !strncmp_P(packet_buffer, kDeviceGroupMessage, sizeof(DEVICE_GROUP_MESSAGE) - 1)) {
|
||||
ProcessDeviceGroupMessage(packet_buffer, len);
|
||||
}
|
||||
#endif // USE_DEVICE_GROUPS
|
||||
|
@ -560,7 +560,7 @@ void WifiCheck(uint8_t param)
|
||||
}
|
||||
#ifdef USE_EMULATION
|
||||
#ifdef USE_DEVICE_GROUPS
|
||||
if (Settings.flag2.emulation || Settings.flag.device_groups_enabled) { UdpConnect(); }
|
||||
if (Settings.flag2.emulation || Settings.flag4.device_groups_enabled) { UdpConnect(); }
|
||||
#else // USE_DEVICE_GROUPS
|
||||
if (Settings.flag2.emulation) { UdpConnect(); }
|
||||
#endif // USE_DEVICE_GROUPS
|
||||
|
@ -290,9 +290,6 @@ void setup(void)
|
||||
#ifdef USE_ARDUINO_OTA
|
||||
ArduinoOTAInit();
|
||||
#endif // USE_ARDUINO_OTA
|
||||
#ifdef USE_DEVICE_GROUPS
|
||||
DeviceGroupsInit();
|
||||
#endif // USE_DEVICE_GROUPS
|
||||
|
||||
XdrvCall(FUNC_INIT);
|
||||
XsnsCall(FUNC_INIT);
|
||||
|
@ -73,6 +73,16 @@ extern "C" void custom_crash_callback(struct rst_info * rst_info, uint32_t stack
|
||||
#define MODULE SONOFF_BASIC // [Module] Select default model
|
||||
#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
|
||||
|
||||
/*********************************************************************************************\
|
||||
* [tasmota-sensors.bin]
|
||||
* Provide an image with useful supported sensors enabled
|
||||
@ -249,6 +259,8 @@ extern "C" void custom_crash_callback(struct rst_info * rst_info, uint32_t stack
|
||||
#undef USE_EMULATION // Disable Belkin WeMo and Hue Bridge emulation for Alexa (-16k code, -2k mem)
|
||||
#undef USE_EMULATION_HUE // Disable Hue Bridge emulation for Alexa (+14k code, +2k mem common)
|
||||
#undef USE_EMULATION_WEMO // Disable Belkin WeMo emulation for Alexa (+6k code, +2k mem common)
|
||||
#undef USE_DEVICE_GROUPS // Disable support for device groups (+3k5 code)
|
||||
#undef USE_PWM_DIMMER_REMOTE // Disbale support for remote switches to PWM Dimmer
|
||||
#undef DEBUG_THEO // Disable debug code
|
||||
#undef USE_DEBUG_DRIVER // Disable debug code
|
||||
#endif // FIRMWARE_KNX_NO_EMULATION
|
||||
@ -286,6 +298,8 @@ extern "C" void custom_crash_callback(struct rst_info * rst_info, uint32_t stack
|
||||
#undef USE_DEEPSLEEP // Disable support for deepsleep (+1k code)
|
||||
#undef USE_EXS_DIMMER // Disable support for EX-Store WiFi Dimmer
|
||||
#undef USE_HOTPLUG // Disable support for HotPlug
|
||||
#undef USE_DEVICE_GROUPS // Disable support for device groups (+3k5 code)
|
||||
#undef USE_PWM_DIMMER_REMOTE // Disbale support for remote switches to PWM Dimmer
|
||||
|
||||
#undef USE_ENERGY_SENSOR // Disable energy sensors (-14k code)
|
||||
#undef USE_PZEM004T // Disable PZEM004T energy sensor
|
||||
@ -362,6 +376,8 @@ extern "C" void custom_crash_callback(struct rst_info * rst_info, uint32_t stack
|
||||
#undef USE_DEEPSLEEP // Disable support for deepsleep (+1k code)
|
||||
#undef USE_EXS_DIMMER // Disable support for EX-Store WiFi Dimmer
|
||||
#undef USE_HOTPLUG // Disable support for HotPlug
|
||||
#undef USE_DEVICE_GROUPS // Disable support for device groups (+3k5 code)
|
||||
#undef USE_PWM_DIMMER_REMOTE // Disbale support for remote switches to PWM Dimmer
|
||||
|
||||
// -- Optional light modules ----------------------
|
||||
//#undef USE_LIGHT // Also disable all Dimmer/Light support
|
||||
@ -583,6 +599,8 @@ extern "C" void custom_crash_callback(struct rst_info * rst_info, uint32_t stack
|
||||
#undef USE_DEEPSLEEP // Disable support for deepsleep (+1k code)
|
||||
#undef USE_EXS_DIMMER // Disable support for EX-Store WiFi Dimmer
|
||||
#undef USE_HOTPLUG // Disable support for HotPlug
|
||||
#undef USE_DEVICE_GROUPS // Disable support for device groups (+3k5 code)
|
||||
#undef USE_PWM_DIMMER_REMOTE // Disbale support for remote switches to PWM Dimmer
|
||||
|
||||
// -- Optional light modules ----------------------
|
||||
#undef USE_LIGHT // Disable support for lights
|
||||
@ -711,16 +729,6 @@ const char kDeviceGroupMessage[] PROGMEM = DEVICE_GROUP_MESSAGE;
|
||||
uint8_t device_group_count = 1;
|
||||
#endif // USE_DEVICE_GROUPS
|
||||
|
||||
#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
|
||||
|
||||
#ifdef DEBUG_TASMOTA_CORE
|
||||
#define DEBUG_CORE_LOG(...) AddLog_Debug(__VA_ARGS__)
|
||||
#else
|
||||
|
@ -2982,7 +2982,7 @@ bool Xdrv01(uint8_t function)
|
||||
PollDnsWebserver();
|
||||
#ifdef USE_EMULATION
|
||||
#ifdef USE_DEVICE_GROUPS
|
||||
if (Settings.flag2.emulation || Settings.flag.device_groups_enabled) { PollUdp(); }
|
||||
if (Settings.flag2.emulation || Settings.flag4.device_groups_enabled) { PollUdp(); }
|
||||
#else // USE_DEVICE_GROUPS
|
||||
if (Settings.flag2.emulation) { PollUdp(); }
|
||||
#endif // USE_DEVICE_GROUPS
|
||||
|
Loading…
x
Reference in New Issue
Block a user