WiFi networks priority (#658)

* WiFi networks priority

Fixes https://github.com/esphome/feature-requests/issues/136

* Print priority
This commit is contained in:
Otto Winter 2019-07-03 20:42:46 +02:00 committed by GitHub
parent 6516a6ff7e
commit 1876c21e3e
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 60 additions and 1 deletions

View file

@ -5,7 +5,7 @@ from esphome.automation import Condition
from esphome.const import CONF_AP, CONF_BSSID, CONF_CHANNEL, CONF_DNS1, CONF_DNS2, CONF_DOMAIN, \
CONF_FAST_CONNECT, CONF_GATEWAY, CONF_HIDDEN, CONF_ID, CONF_MANUAL_IP, CONF_NETWORKS, \
CONF_PASSWORD, CONF_POWER_SAVE_MODE, CONF_REBOOT_TIMEOUT, CONF_SSID, CONF_STATIC_IP, \
CONF_SUBNET, CONF_USE_ADDRESS
CONF_SUBNET, CONF_USE_ADDRESS, CONF_PRIORITY
from esphome.core import CORE, HexInt, coroutine_with_priority
AUTO_LOAD = ['network']
@ -72,6 +72,7 @@ WIFI_NETWORK_AP = WIFI_NETWORK_BASE.extend({
WIFI_NETWORK_STA = WIFI_NETWORK_BASE.extend({
cv.Optional(CONF_BSSID): cv.mac_address,
cv.Optional(CONF_HIDDEN): cv.boolean,
cv.Optional(CONF_PRIORITY, default=0.0): cv.float_,
})
@ -161,6 +162,8 @@ def wifi_network(config, static_ip):
cg.add(ap.set_channel(config[CONF_CHANNEL]))
if static_ip is not None:
cg.add(ap.set_manual_ip(manual_ip(static_ip)))
if CONF_PRIORITY in config:
cg.add(ap.set_priority(config[CONF_PRIORITY]))
return ap

View file

@ -273,6 +273,9 @@ void WiFiComponent::print_connect_params_() {
int8_t rssi = WiFi.RSSI();
print_signal_bars(rssi, signal_bars);
ESP_LOGCONFIG(TAG, " Signal strength: %d dB %s", rssi, signal_bars);
if (this->selected_ap_.get_bssid().has_value()) {
ESP_LOGV(TAG, " Priority: %.1f", this->get_sta_priority(*this->selected_ap_.get_bssid()));
}
ESP_LOGCONFIG(TAG, " Channel: %d", WiFi.channel());
ESP_LOGCONFIG(TAG, " Subnet: %s", WiFi.subnetMask().toString().c_str());
ESP_LOGCONFIG(TAG, " Gateway: %s", WiFi.gatewayIP().toString().c_str());
@ -308,6 +311,10 @@ void WiFiComponent::check_scanning_finished() {
for (auto &ap : this->sta_) {
if (res.matches(ap)) {
res.set_matches(true);
if (!this->has_sta_priority(res.get_bssid())) {
this->set_sta_priority(res.get_bssid(), ap.get_priority());
}
res.set_priority(this->get_sta_priority(res.get_bssid()));
break;
}
}
@ -315,11 +322,18 @@ void WiFiComponent::check_scanning_finished() {
std::stable_sort(this->scan_result_.begin(), this->scan_result_.end(),
[](const WiFiScanResult &a, const WiFiScanResult &b) {
// return true if a is better than b
if (a.get_matches() && !b.get_matches())
return true;
if (!a.get_matches() && b.get_matches())
return false;
if (a.get_matches() && b.get_matches()) {
// if both match, check priority
if (a.get_priority() != b.get_priority())
return a.get_priority() > b.get_priority();
}
return a.get_rssi() > b.get_rssi();
});
@ -443,6 +457,12 @@ void WiFiComponent::check_connecting_finished() {
}
void WiFiComponent::retry_connect() {
if (this->selected_ap_.get_bssid()) {
auto bssid = *this->selected_ap_.get_bssid();
float priority = this->get_sta_priority(bssid);
this->set_sta_priority(bssid, priority - 1.0f);
}
delay(10);
if (!this->is_captive_portal_active_() && (this->num_retried_ > 5 || this->error_from_callback_)) {
// If retry failed for more than 5 times, let's restart STA

View file

@ -66,12 +66,14 @@ class WiFiAP {
void set_bssid(optional<bssid_t> bssid);
void set_password(const std::string &password);
void set_channel(optional<uint8_t> channel);
void set_priority(float priority) { priority_ = priority; }
void set_manual_ip(optional<ManualIP> manual_ip);
void set_hidden(bool hidden);
const std::string &get_ssid() const;
const optional<bssid_t> &get_bssid() const;
const std::string &get_password() const;
const optional<uint8_t> &get_channel() const;
float get_priority() const { return priority_; }
const optional<ManualIP> &get_manual_ip() const;
bool get_hidden() const;
@ -80,6 +82,7 @@ class WiFiAP {
optional<bssid_t> bssid_;
std::string password_;
optional<uint8_t> channel_;
float priority_{0};
optional<ManualIP> manual_ip_;
bool hidden_{false};
};
@ -99,6 +102,8 @@ class WiFiScanResult {
int8_t get_rssi() const;
bool get_with_auth() const;
bool get_is_hidden() const;
float get_priority() const { return priority_; }
void set_priority(float priority) { priority_ = priority; }
protected:
bool matches_{false};
@ -108,6 +113,12 @@ class WiFiScanResult {
int8_t rssi_;
bool with_auth_;
bool is_hidden_;
float priority_{0.0f};
};
struct WiFiSTAPriority {
bssid_t bssid;
float priority;
};
enum WiFiPowerSaveMode {
@ -175,6 +186,30 @@ class WiFiComponent : public Component {
IPAddress wifi_soft_ap_ip();
bool has_sta_priority(const bssid_t &bssid) {
for (auto &it : this->sta_priorities_)
if (it.bssid == bssid)
return true;
return false;
}
float get_sta_priority(const bssid_t bssid) {
for (auto &it : this->sta_priorities_)
if (it.bssid == bssid)
return it.priority;
return 0.0f;
}
void set_sta_priority(const bssid_t bssid, float priority) {
for (auto &it : this->sta_priorities_)
if (it.bssid == bssid) {
it.priority = priority;
return;
}
this->sta_priorities_.push_back(WiFiSTAPriority{
.bssid = bssid,
.priority = priority,
});
}
protected:
static std::string format_mac_addr(const uint8_t mac[6]);
void setup_ap_config_();
@ -209,6 +244,7 @@ class WiFiComponent : public Component {
std::string use_address_;
std::vector<WiFiAP> sta_;
std::vector<WiFiSTAPriority> sta_priorities_;
WiFiAP selected_ap_;
bool fast_connect_{false};