Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Simplify handling of multiple WizMotes #16

Open
wants to merge 5 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 1 addition & 5 deletions components/esp_now/esp_now_component.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -62,9 +62,7 @@ void ESPNowComponent::setup() {
ESP_LOGCONFIG(TAG, "ESP-NOW setup complete");
}
void ESPNowComponent::loop() {
if (receive_queue_.empty())
return;
while (true) {
while (!receive_queue_.empty()) {
std::unique_ptr<ESPNowPacket> packet = std::move(this->receive_queue_.front());
this->receive_queue_.pop();
#if ESPHOME_VERSION_CODE >= VERSION_CODE(2022, 1, 0)
Expand All @@ -78,8 +76,6 @@ void ESPNowComponent::loop() {
listener->on_esp_now_message(*packet);

this->on_packet_->trigger(*packet);
if (this->receive_queue_.empty())
break;
}
}
void ESPNowComponent::dump_config() { ESP_LOGCONFIG(TAG, "esp_now:"); }
Expand Down
48 changes: 4 additions & 44 deletions components/wizmote/wizmote.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,54 +4,14 @@ namespace esphome {
namespace wizmote {
void WizMoteListener::on_esp_now_message(esp_now::ESPNowPacket packet) {
WizMotePacket wizmote = WizMotePacket::build(packet);
if (update_wizmote_history(&wizmote))
return;

this->on_button_->trigger(wizmote);
}

bool WizMoteListener::update_wizmote_history(WizMotePacket *packet)
{
uint8_t index = 0;
if (find_bssid_index(packet, &index))
{
if (this->history[index].sequence == packet->sequence)
return true;

// We had a matching MAC, but not a matching sequence,
this->history[index].sequence = packet->sequence;
if (this->last_sequence_[wizmote.mac_address] == wizmote.sequence) {
return;
}

for (uint8_t i = (WIZMOTEHISTORYSIZE - 1); i > 0; i--)
memcpy(&(this->history[i]), &(this->history[i-1]), sizeof(WizMoteHistory));
this->history[0].sequence = packet->sequence;
memcpy(this->history[0].bssid, packet->bssid, 6);

return false;
}
this->last_sequence_[wizmote.mac_address] = wizmote.sequence;

bool WizMoteListener::find_bssid_index(WizMotePacket *packet, uint8_t *index)
{
for (uint8_t i = 0; i < WIZMOTEHISTORYSIZE; i++)
{
if (is_bssid_equal(packet, &(this->history[i])))
{
*index = i;
return true;
}
}
return false;
this->on_button_->trigger(wizmote);
}

bool WizMoteListener::is_bssid_equal(WizMotePacket *packet, WizMoteHistory *history)
{
for (uint8_t i = 0; i < 6; i++)
{
if (packet->bssid[i] != history->bssid[i])
return false;
}
return true;
}

} // namespace wizmote
} // namespace esphome
54 changes: 24 additions & 30 deletions components/wizmote/wizmote.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,43 +4,41 @@
#include "esphome/core/automation.h"
#include "esphome/core/helpers.h"

#include <vector>
#include <map>

namespace esphome {
namespace wizmote {

static const uint8_t WIZMOTEHISTORYSIZE = 20;

typedef struct WizMotePacket {
uint8_t bssid[6];

uint8_t program; // 0x91 for ON button, 0x81 for all others
uint8_t seq[4]; // Incremetal sequence number 32 bit unsigned integer LSB first
uint8_t byte5 = 32; // Unknown
typedef uint64_t MACAddress;

typedef struct __attribute__((__packed__)) WizMotePacket {
union {
uint8_t bssid[6];
MACAddress mac_address;
};

union {
uint8_t program; // 0x91 for ON button, 0x81 for all others
struct __attribute__((__packed__)) {
unsigned :4;
unsigned pairing:1;
unsigned :3;
};
};
uint32_t sequence; // Incremental sequence number 32 bit unsigned integer LE
uint8_t dType1 = 32; // Data type: button (32)
uint8_t button; // Identifies which button is being pressed
uint8_t byte8 = 1; // Unknown, but always 0x01
uint8_t byte9 = 100; // Unnkown, but always 0x64

uint8_t byte10; // Unknown, maybe checksum
uint8_t byte11; // Unknown, maybe checksum
uint8_t byte12; // Unknown, maybe checksum
uint8_t byte13; // Unknown, maybe checksum

uint32_t sequence;
uint8_t dType2 = 1; // Data type: batteryLevel (1)
uint8_t batteryLevel; // WiZMote batteryLevel out of 100
uint8_t mac[4]; // CCM MAC (Message Authentication Code)

static inline WizMotePacket build(esp_now::ESPNowPacket espnow_packet) {
WizMotePacket packet;
memcpy(packet.bssid, espnow_packet.get_bssid().data(), 6);
memcpy(&(packet.program), espnow_packet.get_data().data(), espnow_packet.get_data().size());
packet.sequence = encode_uint32(packet.seq[3], packet.seq[2], packet.seq[1], packet.seq[0]);
memcpy(&packet.program, espnow_packet.get_data().data(), espnow_packet.get_data().size());
return packet;
}
} WizMotePacket;

typedef struct WizMoteHistory {
uint8_t bssid[6];
uint32_t sequence;
} WizMoteHistory;

class WizMoteListener : public esp_now::ESPNowListener {
public:
Expand All @@ -49,13 +47,9 @@ class WizMoteListener : public esp_now::ESPNowListener {
Trigger<WizMotePacket> *get_on_button_trigger() { return this->on_button_; }

protected:
bool update_wizmote_history(WizMotePacket *packet);
bool find_bssid_index(WizMotePacket *packet, uint8_t *index);
bool is_bssid_equal(WizMotePacket *packet, WizMoteHistory *history);
WizMoteHistory history[WIZMOTEHISTORYSIZE] = {0,};
std::map<MACAddress, uint32_t> last_sequence_;
Trigger<WizMotePacket> *on_button_ = new Trigger<WizMotePacket>();
};


} // namespace wizmote
} // namespace esphome