feat(net): add {linkSpeed} format replacement
Adds an ethernet link speed ({linkSpeed}) read from
/sys/class/net/<iface>/speed, plus a skip-decimal option on pow_format
to drop a trailing .0. Rebased onto master's store-based network
formatting; existing compact bandwidth args updated for the new
pow_format signature.
This commit is contained in:
@@ -54,6 +54,7 @@ class Network : public ALabel {
|
|||||||
const std::string getNetworkState() const;
|
const std::string getNetworkState() const;
|
||||||
void clearIface();
|
void clearIface();
|
||||||
std::optional<std::pair<unsigned long long, unsigned long long>> readBandwidthUsage();
|
std::optional<std::pair<unsigned long long, unsigned long long>> readBandwidthUsage();
|
||||||
|
uint32_t readLinkSpeed() const;
|
||||||
|
|
||||||
int ifid_{-1};
|
int ifid_{-1};
|
||||||
ip_addr_pref addr_pref_{ip_addr_pref::IPV4};
|
ip_addr_pref addr_pref_{ip_addr_pref::IPV4};
|
||||||
@@ -94,6 +95,7 @@ class Network : public ALabel {
|
|||||||
uint8_t signal_strength_;
|
uint8_t signal_strength_;
|
||||||
std::string signal_strength_app_;
|
std::string signal_strength_app_;
|
||||||
uint32_t route_priority;
|
uint32_t route_priority;
|
||||||
|
uint32_t link_speed_{0};
|
||||||
|
|
||||||
util::SleeperThread thread_;
|
util::SleeperThread thread_;
|
||||||
util::SleeperThread thread_timer_;
|
util::SleeperThread thread_timer_;
|
||||||
|
|||||||
+19
-9
@@ -5,12 +5,18 @@
|
|||||||
|
|
||||||
class pow_format {
|
class pow_format {
|
||||||
public:
|
public:
|
||||||
pow_format(long long val, std::string&& unit, bool binary = false, int min_pow_for_decimal = 0)
|
pow_format(long long val, std::string&& unit, bool binary = false, bool skip_decimal = false,
|
||||||
: val_(val), unit_(unit), binary_(binary), min_pow_for_decimal_(min_pow_for_decimal) {};
|
int min_pow_for_decimal = 0)
|
||||||
|
: val_(val),
|
||||||
|
unit_(unit),
|
||||||
|
binary_(binary),
|
||||||
|
skip_decimal_(skip_decimal),
|
||||||
|
min_pow_for_decimal_(min_pow_for_decimal) {};
|
||||||
|
|
||||||
long long val_;
|
long long val_;
|
||||||
std::string unit_;
|
std::string unit_;
|
||||||
bool binary_;
|
bool binary_;
|
||||||
|
bool skip_decimal_;
|
||||||
int min_pow_for_decimal_;
|
int min_pow_for_decimal_;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -50,17 +56,21 @@ struct formatter<pow_format> {
|
|||||||
const char* units[] = {"", "k", "M", "G", "T", "P", nullptr};
|
const char* units[] = {"", "k", "M", "G", "T", "P", nullptr};
|
||||||
|
|
||||||
auto base = s.binary_ ? 1024ull : 1000ll;
|
auto base = s.binary_ ? 1024ull : 1000ll;
|
||||||
|
auto div = 1ll;
|
||||||
auto fraction = (double)s.val_;
|
auto fraction = (double)s.val_;
|
||||||
|
|
||||||
int pow;
|
int pow;
|
||||||
for (pow = 0; units[pow + 1] != nullptr && fraction / base >= 1; ++pow) {
|
for (pow = 0; units[pow + 1] != nullptr && fraction / base >= 1; ++pow) {
|
||||||
fraction /= base;
|
fraction /= base;
|
||||||
|
div *= base;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto number_width = 5 // coeff in {:.1f} format
|
auto fixed_precision = (s.skip_decimal_ && ((s.val_ % div) == 0)) ? 0 : 1;
|
||||||
+ s.binary_; // potential 4th digit before the decimal point
|
auto number_width = 3 + fixed_precision // coeff in {:.{fixed_precision}f} format
|
||||||
auto max_width = number_width + 1 // prefix from units array
|
+ (fixed_precision != 0) // float dot
|
||||||
+ s.binary_ // for the 'i' in GiB.
|
+ s.binary_; // potential digit before the decimal point
|
||||||
|
auto max_width = number_width + 1 // prefix from units array
|
||||||
|
+ s.binary_ // for the 'i' in GiB.
|
||||||
+ s.unit_.length();
|
+ s.unit_.length();
|
||||||
|
|
||||||
const char* format;
|
const char* format;
|
||||||
@@ -71,17 +81,17 @@ struct formatter<pow_format> {
|
|||||||
case '<':
|
case '<':
|
||||||
return fmt::format_to(ctx.out(), "{:<{}}", fmt::format("{}", s), max_width);
|
return fmt::format_to(ctx.out(), "{:<{}}", fmt::format("{}", s), max_width);
|
||||||
case '=':
|
case '=':
|
||||||
format = "{coefficient:<{number_width}.1f}{padding}{prefix}{unit}";
|
format = "{coefficient:<{number_width}.{fixed_precision}f}{padding}{prefix}{unit}";
|
||||||
break;
|
break;
|
||||||
case 0:
|
case 0:
|
||||||
default:
|
default:
|
||||||
format = pow < s.min_pow_for_decimal_ ? "{coefficient:.0f}{prefix}{unit}"
|
format = pow < s.min_pow_for_decimal_ ? "{coefficient:.0f}{prefix}{unit}"
|
||||||
: "{coefficient:.1f}{prefix}{unit}";
|
: "{coefficient:.{fixed_precision}f}{prefix}{unit}";
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
return fmt::format_to(
|
return fmt::format_to(
|
||||||
ctx.out(), fmt::runtime(format), fmt::arg("coefficient", fraction),
|
ctx.out(), fmt::runtime(format), fmt::arg("coefficient", fraction),
|
||||||
fmt::arg("number_width", number_width),
|
fmt::arg("fixed_precision", fixed_precision), fmt::arg("number_width", number_width),
|
||||||
fmt::arg("prefix", std::string() + units[pow] + ((s.binary_ && pow) ? "i" : "")),
|
fmt::arg("prefix", std::string() + units[pow] + ((s.binary_ && pow) ? "i" : "")),
|
||||||
fmt::arg("unit", s.unit_),
|
fmt::arg("unit", s.unit_),
|
||||||
fmt::arg("padding", pow ? ""
|
fmt::arg("padding", pow ? ""
|
||||||
|
|||||||
@@ -200,6 +200,8 @@ Addressed by *network*
|
|||||||
|
|
||||||
*{rx_bitrate}*: Link receive bitrate (e.g., 866.7 Mb/s).
|
*{rx_bitrate}*: Link receive bitrate (e.g., 866.7 Mb/s).
|
||||||
|
|
||||||
|
*{linkSpeed}*: Ethernet link speed.
|
||||||
|
|
||||||
*{icon}*: Icon, as defined in *format-icons*.
|
*{icon}*: Icon, as defined in *format-icons*.
|
||||||
|
|
||||||
# EXAMPLES
|
# EXAMPLES
|
||||||
|
|||||||
+20
-2
@@ -83,6 +83,21 @@ waybar::modules::Network::readBandwidthUsage() {
|
|||||||
return {{receivedBytes, transmittedBytes}};
|
return {{receivedBytes, transmittedBytes}};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint32_t waybar::modules::Network::readLinkSpeed() const {
|
||||||
|
auto path = fmt::format("/sys/class/net/{}/speed", ifname_);
|
||||||
|
std::ifstream sysfs_speed(path);
|
||||||
|
|
||||||
|
if (!sysfs_speed) return 0;
|
||||||
|
|
||||||
|
uint32_t speed;
|
||||||
|
sysfs_speed >> speed;
|
||||||
|
|
||||||
|
if (sysfs_speed.bad()) // read fails on incompatible devices
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
return speed;
|
||||||
|
}
|
||||||
|
|
||||||
waybar::modules::Network::Network(const std::string& id, const Json::Value& config)
|
waybar::modules::Network::Network(const std::string& id, const Json::Value& config)
|
||||||
: ALabel(config, "network", id, DEFAULT_FORMAT, 60) {
|
: ALabel(config, "network", id, DEFAULT_FORMAT, 60) {
|
||||||
// Start with some "text" in the module's label_. update() will then
|
// Start with some "text" in the module's label_. update() will then
|
||||||
@@ -329,6 +344,7 @@ auto waybar::modules::Network::update() -> void {
|
|||||||
elapsed_seconds = std::chrono::duration<double>(interval_).count();
|
elapsed_seconds = std::chrono::duration<double>(interval_).count();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
link_speed_ = readLinkSpeed();
|
||||||
auto threshold_state = getState(signal_strength_);
|
auto threshold_state = getState(signal_strength_);
|
||||||
|
|
||||||
if (!alt_) {
|
if (!alt_) {
|
||||||
@@ -401,13 +417,14 @@ auto waybar::modules::Network::update() -> void {
|
|||||||
fmt::arg("bandwidthDownBytes", pow_format(bandwidth_down / elapsed_seconds, "B/s")));
|
fmt::arg("bandwidthDownBytes", pow_format(bandwidth_down / elapsed_seconds, "B/s")));
|
||||||
store.push_back(fmt::arg("bandwidthUpBytes", pow_format(bandwidth_up / elapsed_seconds, "B/s")));
|
store.push_back(fmt::arg("bandwidthUpBytes", pow_format(bandwidth_up / elapsed_seconds, "B/s")));
|
||||||
store.push_back(fmt::arg("bandwidthDownBytesCompact",
|
store.push_back(fmt::arg("bandwidthDownBytesCompact",
|
||||||
pow_format(bandwidth_down / elapsed_seconds, "B", false, 2)));
|
pow_format(bandwidth_down / elapsed_seconds, "B", false, false, 2)));
|
||||||
store.push_back(fmt::arg("bandwidthUpBytesCompact",
|
store.push_back(fmt::arg("bandwidthUpBytesCompact",
|
||||||
pow_format(bandwidth_up / elapsed_seconds, "B", false, 2)));
|
pow_format(bandwidth_up / elapsed_seconds, "B", false, false, 2)));
|
||||||
store.push_back(fmt::arg("bandwidthTotalBytes",
|
store.push_back(fmt::arg("bandwidthTotalBytes",
|
||||||
pow_format((bandwidth_up + bandwidth_down) / elapsed_seconds, "B/s")));
|
pow_format((bandwidth_up + bandwidth_down) / elapsed_seconds, "B/s")));
|
||||||
store.push_back(fmt::arg("rxBitrate", pow_format(rx_bitrate_, "b/s")));
|
store.push_back(fmt::arg("rxBitrate", pow_format(rx_bitrate_, "b/s")));
|
||||||
store.push_back(fmt::arg("txBitrate", pow_format(tx_bitrate_, "b/s")));
|
store.push_back(fmt::arg("txBitrate", pow_format(tx_bitrate_, "b/s")));
|
||||||
|
store.push_back(fmt::arg("linkSpeed", pow_format(link_speed_ * 1000000ull, "b/s", false, true)));
|
||||||
|
|
||||||
auto text = fmt::vformat(format_, store);
|
auto text = fmt::vformat(format_, store);
|
||||||
if (setLabelMarkup(text)) {
|
if (setLabelMarkup(text)) {
|
||||||
@@ -511,6 +528,7 @@ void waybar::modules::Network::clearIface() {
|
|||||||
signal_strength_dbm_ = 0;
|
signal_strength_dbm_ = 0;
|
||||||
signal_strength_ = 0;
|
signal_strength_ = 0;
|
||||||
signal_strength_app_.clear();
|
signal_strength_app_.clear();
|
||||||
|
link_speed_ = 0;
|
||||||
frequency_ = 0.0;
|
frequency_ = 0.0;
|
||||||
rx_bitrate_ = 0;
|
rx_bitrate_ = 0;
|
||||||
tx_bitrate_ = 0;
|
tx_bitrate_ = 0;
|
||||||
|
|||||||
Reference in New Issue
Block a user