forked from fsaris/EspHome-AwoX-BLE-mesh-hub
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
0 parents
commit 4e6c411
Showing
9 changed files
with
1,159 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
# Gitignore settings for ESPHome | ||
# This is an example and may include too much for your use-case. | ||
# You can modify this file to suit your needs. | ||
/.esphome/ | ||
/secrets.yaml |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
# EspHome component: AwoX BLE mesh hub | ||
# EspHome component: AwoX BLE mesh hub |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
esphome: | ||
name: "awox-ble-mesh-hub" | ||
|
||
esp32: | ||
board: esp32dev | ||
framework: | ||
type: arduino | ||
|
||
status_led: | ||
pin: GPIO2 | ||
|
||
# Enable logging | ||
logger: | ||
#level: VERY_VERBOSE | ||
|
||
mqtt: | ||
broker: !secret mqtt_host | ||
username: !secret mqtt_user | ||
password: !secret mqtt_password | ||
|
||
ota: | ||
password: "988af1bdbc81aa0760c360430673b560" | ||
|
||
wifi: | ||
ssid: !secret wifi_ssid | ||
password: !secret wifi_password | ||
|
||
external_components: | ||
- source: | ||
type: local | ||
path: components | ||
|
||
esp32_ble_tracker: | ||
scan_parameters: | ||
active: false | ||
|
||
awox_mesh: | ||
mesh_name: !secret mesh_name | ||
mesh_password: !secret mesh_password |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
__pycache__ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,49 @@ | ||
import esphome.codegen as cg | ||
import esphome.config_validation as cv | ||
from esphome.components import esp32_ble_tracker, esp32_ble_client | ||
|
||
from esphome.const import CONF_ID | ||
|
||
AUTO_LOAD = ["esp32_ble_client", "esp32_ble_tracker"] | ||
DEPENDENCIES = ["mqtt", "esp32"] | ||
|
||
awox_ns = cg.esphome_ns.namespace("awox_mesh") | ||
|
||
Awox = awox_ns.class_("AwoxMesh", esp32_ble_tracker.ESPBTDeviceListener, cg.Component) | ||
MeshDevice = awox_ns.class_("MeshDevice", esp32_ble_client.BLEClientBase) | ||
|
||
CONNECTION_SCHEMA = esp32_ble_tracker.ESP_BLE_DEVICE_SCHEMA.extend( | ||
{ | ||
cv.GenerateID(): cv.declare_id(MeshDevice), | ||
} | ||
).extend(cv.COMPONENT_SCHEMA) | ||
|
||
CONFIG_SCHEMA = ( | ||
cv.Schema( | ||
{ | ||
cv.GenerateID(): cv.declare_id(Awox), | ||
cv.Required("mesh_name"): cv.string_strict, | ||
cv.Required("mesh_password"): cv.string_strict, | ||
cv.Optional("connection", {}): CONNECTION_SCHEMA, | ||
} | ||
) | ||
.extend(esp32_ble_tracker.ESP_BLE_DEVICE_SCHEMA) | ||
.extend(cv.COMPONENT_SCHEMA) | ||
) | ||
|
||
|
||
async def to_code(config): | ||
var = cg.new_Pvariable(config[CONF_ID]) | ||
await cg.register_component(var, config) | ||
await esp32_ble_tracker.register_ble_device(var, config) | ||
|
||
connection_var = cg.new_Pvariable(config["connection"][CONF_ID]) | ||
cg.add(connection_var.set_mesh_name(config["mesh_name"])) | ||
cg.add(connection_var.set_mesh_password(config["mesh_password"])) | ||
|
||
await cg.register_component(connection_var, config["connection"]) | ||
cg.add(var.register_connection(connection_var)) | ||
await esp32_ble_tracker.register_client(connection_var, config["connection"]) | ||
|
||
# Crypto | ||
cg.add_library("rweather/Crypto", "0.4.0") |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,94 @@ | ||
#pragma once | ||
|
||
#ifdef USE_ESP32 | ||
#include <cstring> | ||
#include <cstdio> | ||
#include <algorithm> | ||
#include "awox_mesh.h" | ||
|
||
#include "esphome/core/log.h" | ||
|
||
namespace esphome { | ||
namespace awox_mesh { | ||
|
||
static const char *const TAG = "AwoxMesh"; | ||
|
||
FoundDevice AwoxMesh::add_to_devices(const esp32_ble_tracker::ESPBTDevice &device) { | ||
this->devices_.erase( | ||
std::remove_if(this->devices_.begin(), this->devices_.end(), | ||
[device](const FoundDevice &_f) { return _f.address == device.address_uint64(); }), | ||
this->devices_.end()); | ||
|
||
static FoundDevice found = {}; | ||
found.address_str = device.address_str(); | ||
found.address = device.address_uint64(); | ||
found.rssi = device.get_rssi(); | ||
found.last_detected = esphome::millis(); | ||
this->devices_.push_back(found); | ||
|
||
this->remove_devices_that_are_not_available(); | ||
|
||
this->sort_devices(); | ||
|
||
return found; | ||
} | ||
|
||
bool AwoxMesh::parse_device(const esp32_ble_tracker::ESPBTDevice &device) { | ||
if (device.address_str().rfind("A4:C1", 0) != 0) { | ||
return false; | ||
} | ||
|
||
FoundDevice found = add_to_devices(device); | ||
|
||
ESP_LOGV(TAG, "Found Awox device %s - %s. RSSI: %d dB (total devices: %d)", device.get_name().c_str(), | ||
device.address_str().c_str(), device.get_rssi(), this->devices_.size()); | ||
|
||
return true; | ||
} | ||
|
||
void AwoxMesh::setup() { | ||
Component::setup(); | ||
|
||
this->connection->set_disconnect_callback([this]() { ESP_LOGI(TAG, "disconnected"); }); | ||
} | ||
|
||
void AwoxMesh::loop() { | ||
if (esphome::millis() - this->start > 20000 && this->devices_.size() > 0 && this->connection->address_str() == "") { | ||
ESP_LOGD(TAG, "Total devices: %d", this->devices_.size()); | ||
for (int i = 0; i < this->devices_.size(); i++) { | ||
ESP_LOGD(TAG, "AVailable device %s => rssi: %d", this->devices_[i].address_str.c_str(), this->devices_[i].rssi); | ||
} | ||
auto device = this->devices_.front(); | ||
|
||
ESP_LOGI(TAG, "Try to connect %s => rssi: %d", device.address_str.c_str(), device.rssi); | ||
this->connection->set_address(device.address); | ||
this->connection->connect(); | ||
|
||
this->set_timeout("connecting", 20000, [this, device]() { | ||
if (this->connection->connected()) { | ||
return; | ||
} | ||
ESP_LOGI(TAG, "Failed to connect %s => rssi: %d", device.address_str.c_str(), device.rssi); | ||
this->remove_devices_that_are_not_available(); | ||
this->connection->disconnect(); | ||
this->connection->set_address(0); | ||
}); | ||
} | ||
} | ||
|
||
void AwoxMesh::sort_devices() { | ||
std::stable_sort(this->devices_.begin(), this->devices_.end(), | ||
[](FoundDevice a, FoundDevice b) { return a.rssi > b.rssi; }); | ||
} | ||
|
||
void AwoxMesh::remove_devices_that_are_not_available() { | ||
const uint32_t now = esphome::millis(); | ||
this->devices_.erase(std::remove_if(this->devices_.begin(), this->devices_.end(), | ||
[&](const FoundDevice &_f) { return now - _f.last_detected > 20000; }), | ||
this->devices_.end()); | ||
} | ||
|
||
} // namespace awox_mesh | ||
} // namespace esphome | ||
|
||
#endif |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,61 @@ | ||
#pragma once | ||
|
||
#ifdef USE_ESP32 | ||
|
||
#include <map> | ||
#include <vector> | ||
|
||
#include <AES.h> | ||
#include <Crypto.h> | ||
#include <GCM.h> | ||
|
||
#include "esphome/core/hal.h" | ||
#include "esphome/components/esp32_ble_client/ble_client_base.h" | ||
#include "esphome/components/esp32_ble_tracker/esp32_ble_tracker.h" | ||
#include "esphome/core/automation.h" | ||
#include "esphome/core/component.h" | ||
#include "esphome/core/defines.h" | ||
|
||
#include "mesh_device.h" | ||
|
||
namespace esphome { | ||
namespace awox_mesh { | ||
|
||
using namespace esp32_ble_client; | ||
|
||
struct FoundDevice { | ||
std::string address_str; | ||
uint64_t address{0}; | ||
int rssi{0}; | ||
uint32_t last_detected; | ||
}; | ||
|
||
class AwoxMesh : public esp32_ble_tracker::ESPBTDeviceListener, public Component { | ||
uint32_t start; | ||
FoundDevice add_to_devices(const esp32_ble_tracker::ESPBTDevice &device); | ||
void sort_devices(); | ||
void remove_devices_that_are_not_available(); | ||
|
||
public: | ||
void setup() override; | ||
|
||
AwoxMesh() { this->start = esphome::millis(); } | ||
bool parse_device(const esp32_ble_tracker::ESPBTDevice &device) override; | ||
|
||
void on_scan_end() override { ESP_LOGD("AwoxMesh", "scan end"); } | ||
|
||
void register_connection(MeshDevice *connection) { | ||
ESP_LOGD("AwoxMesh", "register_connection"); | ||
this->connection = connection; | ||
} | ||
void loop() override; | ||
|
||
protected: | ||
MeshDevice *connection; | ||
std::vector<FoundDevice> devices_{}; | ||
}; | ||
|
||
} // namespace awox_mesh | ||
} // namespace esphome | ||
|
||
#endif |
Oops, something went wrong.