mirror of
https://github.com/esphome/esphome.git
synced 2024-11-23 23:48:11 +01:00
signal strength text sensor
This commit is contained in:
parent
2c9c6aea30
commit
24a4845991
6 changed files with 170 additions and 67 deletions
|
@ -49,6 +49,142 @@ std::string state_to_string(ModemComponentState state) {
|
||||||
return str;
|
return str;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::string network_system_mode_to_string(int mode) {
|
||||||
|
std::string network_type = "Not available";
|
||||||
|
// Access Technology from AT+CNSMOD?
|
||||||
|
// see https://www.waveshare.com/w/upload/a/af/SIM7500_SIM7600_Series_AT_Command_Manual_V3.00.pdf, page 109
|
||||||
|
switch (mode) {
|
||||||
|
case 0:
|
||||||
|
network_type = "No service";
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
network_type = "GSM";
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
network_type = "GPRS";
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
network_type = "EGPRS (EDGE)";
|
||||||
|
break;
|
||||||
|
case 4:
|
||||||
|
network_type = "WCDMA";
|
||||||
|
break;
|
||||||
|
case 5:
|
||||||
|
network_type = "HSDPA only (WCDMA)";
|
||||||
|
break;
|
||||||
|
case 6:
|
||||||
|
network_type = "HSUPA only (WCDMA)";
|
||||||
|
break;
|
||||||
|
case 7:
|
||||||
|
network_type = "HSPA (HSDPA and HSUPA, WCDMA)";
|
||||||
|
break;
|
||||||
|
case 8:
|
||||||
|
network_type = "LTE";
|
||||||
|
break;
|
||||||
|
case 9:
|
||||||
|
network_type = "TDS-CDMA";
|
||||||
|
break;
|
||||||
|
case 10:
|
||||||
|
network_type = "TDS-HSDPA only";
|
||||||
|
break;
|
||||||
|
case 11:
|
||||||
|
network_type = "TDS-HSUPA only";
|
||||||
|
break;
|
||||||
|
case 12:
|
||||||
|
network_type = "TDS-HSPA (HSDPA and HSUPA)";
|
||||||
|
break;
|
||||||
|
case 13:
|
||||||
|
network_type = "CDMA";
|
||||||
|
break;
|
||||||
|
case 14:
|
||||||
|
network_type = "EVDO";
|
||||||
|
break;
|
||||||
|
case 15:
|
||||||
|
network_type = "HYBRID (CDMA and EVDO)";
|
||||||
|
break;
|
||||||
|
case 16:
|
||||||
|
network_type = "1XLTE (CDMA and LTE)";
|
||||||
|
break;
|
||||||
|
case 23:
|
||||||
|
network_type = "EHRPD";
|
||||||
|
break;
|
||||||
|
case 24:
|
||||||
|
network_type = "HYBRID (CDMA and EHRPD)";
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
network_type = "Unknown";
|
||||||
|
}
|
||||||
|
return network_type;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string get_signal_bars(float rssi) { return get_signal_bars(rssi, true); }
|
||||||
|
std::string get_signal_bars(float rssi, bool color) {
|
||||||
|
// adapted from wifi_component.cpp
|
||||||
|
// LOWER ONE QUARTER BLOCK
|
||||||
|
// Unicode: U+2582, UTF-8: E2 96 82
|
||||||
|
// LOWER HALF BLOCK
|
||||||
|
// Unicode: U+2584, UTF-8: E2 96 84
|
||||||
|
// LOWER THREE QUARTERS BLOCK
|
||||||
|
// Unicode: U+2586, UTF-8: E2 96 86
|
||||||
|
// FULL BLOCK
|
||||||
|
// Unicode: U+2588, UTF-8: E2 96 88
|
||||||
|
|
||||||
|
if (!color) {
|
||||||
|
if (std::isnan(rssi)) {
|
||||||
|
return {};
|
||||||
|
} else if (rssi >= -50) {
|
||||||
|
return "High";
|
||||||
|
} else if (rssi >= -65) {
|
||||||
|
return "Good";
|
||||||
|
} else if (rssi >= -85) {
|
||||||
|
return "Medium";
|
||||||
|
} else {
|
||||||
|
return "Low";
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (std::isnan(rssi)) {
|
||||||
|
return "\033[0;31m" // red
|
||||||
|
"!"
|
||||||
|
"\033[0;37m"
|
||||||
|
"\xe2\x96\x84"
|
||||||
|
"\xe2\x96\x86"
|
||||||
|
"\xe2\x96\x88"
|
||||||
|
"\033[0m";
|
||||||
|
} else if (rssi >= -50) {
|
||||||
|
return "\033[0;32m" // green
|
||||||
|
"\xe2\x96\x82"
|
||||||
|
"\xe2\x96\x84"
|
||||||
|
"\xe2\x96\x86"
|
||||||
|
"\xe2\x96\x88"
|
||||||
|
"\033[0m";
|
||||||
|
} else if (rssi >= -65) {
|
||||||
|
return "\033[0;33m" // yellow
|
||||||
|
"\xe2\x96\x82"
|
||||||
|
"\xe2\x96\x84"
|
||||||
|
"\xe2\x96\x86"
|
||||||
|
"\033[0;37m"
|
||||||
|
"\xe2\x96\x88"
|
||||||
|
"\033[0m";
|
||||||
|
} else if (rssi >= -85) {
|
||||||
|
return "\033[0;33m" // yellow
|
||||||
|
"\xe2\x96\x82"
|
||||||
|
"\xe2\x96\x84"
|
||||||
|
"\033[0;37m"
|
||||||
|
"\xe2\x96\x86"
|
||||||
|
"\xe2\x96\x88"
|
||||||
|
"\033[0m";
|
||||||
|
} else {
|
||||||
|
return "\033[0;31m" // red
|
||||||
|
"\xe2\x96\x82"
|
||||||
|
"\033[0;37m"
|
||||||
|
"\xe2\x96\x84"
|
||||||
|
"\xe2\x96\x86"
|
||||||
|
"\xe2\x96\x88"
|
||||||
|
"\033[0m";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace modem
|
} // namespace modem
|
||||||
} // namespace esphome
|
} // namespace esphome
|
||||||
#endif // USE_ESP_IDF
|
#endif // USE_ESP_IDF
|
||||||
|
|
|
@ -10,8 +10,10 @@ namespace esphome {
|
||||||
namespace modem {
|
namespace modem {
|
||||||
|
|
||||||
std::string command_result_to_string(command_result err);
|
std::string command_result_to_string(command_result err);
|
||||||
|
|
||||||
std::string state_to_string(ModemComponentState state);
|
std::string state_to_string(ModemComponentState state);
|
||||||
|
std::string network_system_mode_to_string(int mode);
|
||||||
|
std::string get_signal_bars(float rssi);
|
||||||
|
std::string get_signal_bars(float rssi, bool color);
|
||||||
|
|
||||||
} // namespace modem
|
} // namespace modem
|
||||||
} // namespace esphome
|
} // namespace esphome
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
import esphome.codegen as cg
|
import esphome.codegen as cg
|
||||||
from esphome.components import text_sensor
|
from esphome.components import text_sensor
|
||||||
import esphome.config_validation as cv
|
import esphome.config_validation as cv
|
||||||
from esphome.const import CONF_ID, DEVICE_CLASS_EMPTY
|
from esphome.const import CONF_ID, CONF_SIGNAL_STRENGTH, DEVICE_CLASS_EMPTY
|
||||||
|
|
||||||
from .. import MODEM_COMPONENT_SCHEMA, final_validate_platform, modem_ns
|
from .. import MODEM_COMPONENT_SCHEMA, final_validate_platform, modem_ns
|
||||||
|
|
||||||
|
@ -24,6 +24,9 @@ CONFIG_SCHEMA = cv.All(
|
||||||
cv.Optional(CONF_NETWORK_TYPE): text_sensor.text_sensor_schema(
|
cv.Optional(CONF_NETWORK_TYPE): text_sensor.text_sensor_schema(
|
||||||
device_class=DEVICE_CLASS_EMPTY,
|
device_class=DEVICE_CLASS_EMPTY,
|
||||||
),
|
),
|
||||||
|
cv.Optional(CONF_SIGNAL_STRENGTH): text_sensor.text_sensor_schema(
|
||||||
|
device_class=DEVICE_CLASS_EMPTY,
|
||||||
|
),
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
.extend(MODEM_COMPONENT_SCHEMA)
|
.extend(MODEM_COMPONENT_SCHEMA)
|
||||||
|
@ -40,4 +43,8 @@ async def to_code(config):
|
||||||
network_type_text_sensor = await text_sensor.new_text_sensor(network_type)
|
network_type_text_sensor = await text_sensor.new_text_sensor(network_type)
|
||||||
cg.add(var.set_network_type_text_sensor(network_type_text_sensor))
|
cg.add(var.set_network_type_text_sensor(network_type_text_sensor))
|
||||||
|
|
||||||
|
if signal_strength := config.get(CONF_SIGNAL_STRENGTH, None):
|
||||||
|
signal_strength_text_sensor = await text_sensor.new_text_sensor(signal_strength)
|
||||||
|
cg.add(var.set_signal_strength_text_sensor(signal_strength_text_sensor))
|
||||||
|
|
||||||
await cg.register_component(var, config)
|
await cg.register_component(var, config)
|
||||||
|
|
|
@ -11,6 +11,7 @@
|
||||||
#include "esphome/core/application.h"
|
#include "esphome/core/application.h"
|
||||||
|
|
||||||
#include "../modem_component.h"
|
#include "../modem_component.h"
|
||||||
|
#include "../helpers.h"
|
||||||
|
|
||||||
#define ESPHL_ERROR_CHECK(err, message) \
|
#define ESPHL_ERROR_CHECK(err, message) \
|
||||||
if ((err) != ESP_OK) { \
|
if ((err) != ESP_OK) { \
|
||||||
|
@ -38,6 +39,7 @@ void ModemTextSensor::update() {
|
||||||
ESP_LOGD(TAG, "Modem text_sensor update");
|
ESP_LOGD(TAG, "Modem text_sensor update");
|
||||||
if (modem::global_modem_component->dce && modem::global_modem_component->modem_ready()) {
|
if (modem::global_modem_component->dce && modem::global_modem_component->modem_ready()) {
|
||||||
this->update_network_type_text_sensor_();
|
this->update_network_type_text_sensor_();
|
||||||
|
this->update_signal_strength_text_sensor_();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -46,74 +48,22 @@ void ModemTextSensor::update_network_type_text_sensor_() {
|
||||||
int act;
|
int act;
|
||||||
std::string network_type = "Not available";
|
std::string network_type = "Not available";
|
||||||
if (modem::global_modem_component->dce->get_network_system_mode(act) == command_result::OK) {
|
if (modem::global_modem_component->dce->get_network_system_mode(act) == command_result::OK) {
|
||||||
// Access Technology from AT+CNSMOD?
|
network_type = network_system_mode_to_string(act);
|
||||||
// see https://www.waveshare.com/w/upload/a/af/SIM7500_SIM7600_Series_AT_Command_Manual_V3.00.pdf, page 109
|
|
||||||
switch (act) {
|
|
||||||
case 0:
|
|
||||||
network_type = "No service";
|
|
||||||
break;
|
|
||||||
case 1:
|
|
||||||
network_type = "GSM";
|
|
||||||
break;
|
|
||||||
case 2:
|
|
||||||
network_type = "GPRS";
|
|
||||||
break;
|
|
||||||
case 3:
|
|
||||||
network_type = "EGPRS (EDGE)";
|
|
||||||
break;
|
|
||||||
case 4:
|
|
||||||
network_type = "WCDMA";
|
|
||||||
break;
|
|
||||||
case 5:
|
|
||||||
network_type = "HSDPA only (WCDMA)";
|
|
||||||
break;
|
|
||||||
case 6:
|
|
||||||
network_type = "HSUPA only (WCDMA)";
|
|
||||||
break;
|
|
||||||
case 7:
|
|
||||||
network_type = "HSPA (HSDPA and HSUPA, WCDMA)";
|
|
||||||
break;
|
|
||||||
case 8:
|
|
||||||
network_type = "LTE";
|
|
||||||
break;
|
|
||||||
case 9:
|
|
||||||
network_type = "TDS-CDMA";
|
|
||||||
break;
|
|
||||||
case 10:
|
|
||||||
network_type = "TDS-HSDPA only";
|
|
||||||
break;
|
|
||||||
case 11:
|
|
||||||
network_type = "TDS-HSUPA only";
|
|
||||||
break;
|
|
||||||
case 12:
|
|
||||||
network_type = "TDS-HSPA (HSDPA and HSUPA)";
|
|
||||||
break;
|
|
||||||
case 13:
|
|
||||||
network_type = "CDMA";
|
|
||||||
break;
|
|
||||||
case 14:
|
|
||||||
network_type = "EVDO";
|
|
||||||
break;
|
|
||||||
case 15:
|
|
||||||
network_type = "HYBRID (CDMA and EVDO)";
|
|
||||||
break;
|
|
||||||
case 16:
|
|
||||||
network_type = "1XLTE (CDMA and LTE)";
|
|
||||||
break;
|
|
||||||
case 23:
|
|
||||||
network_type = "EHRPD";
|
|
||||||
break;
|
|
||||||
case 24:
|
|
||||||
network_type = "HYBRID (CDMA and EHRPD)";
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
network_type = "Unknown";
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
this->network_type_text_sensor_->publish_state(network_type);
|
this->network_type_text_sensor_->publish_state(network_type);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ModemTextSensor::update_signal_strength_text_sensor_() {
|
||||||
|
if (modem::global_modem_component->modem_ready() && this->network_type_text_sensor_) {
|
||||||
|
float rssi, ber;
|
||||||
|
if (modem::global_modem_component->get_signal_quality(rssi, ber)) {
|
||||||
|
std::string bars = get_signal_bars(rssi, false);
|
||||||
|
this->signal_strength_text_sensor_->publish_state(bars);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace modem
|
} // namespace modem
|
||||||
} // namespace esphome
|
} // namespace esphome
|
||||||
|
|
||||||
|
|
|
@ -18,6 +18,9 @@ class ModemTextSensor : public PollingComponent {
|
||||||
void set_network_type_text_sensor(text_sensor::TextSensor *network_type_text_sensor) {
|
void set_network_type_text_sensor(text_sensor::TextSensor *network_type_text_sensor) {
|
||||||
this->network_type_text_sensor_ = network_type_text_sensor;
|
this->network_type_text_sensor_ = network_type_text_sensor;
|
||||||
}
|
}
|
||||||
|
void set_signal_strength_text_sensor(text_sensor::TextSensor *signal_strength_text_sensor) {
|
||||||
|
this->signal_strength_text_sensor_ = signal_strength_text_sensor;
|
||||||
|
}
|
||||||
// ========== INTERNAL METHODS ==========
|
// ========== INTERNAL METHODS ==========
|
||||||
// (In most use cases you won't need these)
|
// (In most use cases you won't need these)
|
||||||
|
|
||||||
|
@ -28,7 +31,9 @@ class ModemTextSensor : public PollingComponent {
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
text_sensor::TextSensor *network_type_text_sensor_{nullptr};
|
text_sensor::TextSensor *network_type_text_sensor_{nullptr};
|
||||||
|
text_sensor::TextSensor *signal_strength_text_sensor_{nullptr};
|
||||||
void update_network_type_text_sensor_();
|
void update_network_type_text_sensor_();
|
||||||
|
void update_signal_strength_text_sensor_();
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace modem
|
} // namespace modem
|
||||||
|
|
|
@ -12,19 +12,22 @@ modem:
|
||||||
pin_code: "0000"
|
pin_code: "0000"
|
||||||
enable_on_boot: True
|
enable_on_boot: True
|
||||||
enable_cmux: True
|
enable_cmux: True
|
||||||
|
reboot_timeout: 5min
|
||||||
init_at:
|
init_at:
|
||||||
- AT
|
- AT
|
||||||
on_not_responding:
|
on_not_responding:
|
||||||
logger.log: "modem not responding"
|
logger.log: "modem not responding"
|
||||||
on_connect:
|
on_connect:
|
||||||
logger.log: "got IP"
|
logger.log: "modem connected"
|
||||||
on_disconnect:
|
on_disconnect:
|
||||||
logger.log: "lost IP"
|
logger.log: "modem disconnected"
|
||||||
|
|
||||||
text_sensor:
|
text_sensor:
|
||||||
- platform: modem
|
- platform: modem
|
||||||
network_type:
|
network_type:
|
||||||
name: network type
|
name: network type
|
||||||
|
signal_strength:
|
||||||
|
name: Signal strength
|
||||||
|
|
||||||
sensor:
|
sensor:
|
||||||
- platform: modem
|
- platform: modem
|
||||||
|
|
Loading…
Reference in a new issue