diff --git a/Cargo.lock b/Cargo.lock
index 17bebc4..85d776f 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -548,6 +548,15 @@ version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6245d59a3e82a7fc217c5828a6692dbc6dfb63a0c8c90495621f7b9d79704a0e"
+[[package]]
+name = "convert_case"
+version = "0.6.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ec182b0ca2f35d8fc196cf3404988fd8b8c739a4d270ff118a398feb0cbec1ca"
+dependencies = [
+ "unicode-segmentation",
+]
+
[[package]]
name = "cookie"
version = "0.16.2"
@@ -666,7 +675,7 @@ version = "0.99.18"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5f33878137e4dafd7fa914ad4e259e18a4e8e532b9617a2d0150262bf53abfce"
dependencies = [
- "convert_case",
+ "convert_case 0.4.0",
"proc-macro2 1.0.89",
"quote 1.0.37",
"rustc_version",
@@ -884,6 +893,17 @@ dependencies = [
"num-traits",
]
+[[package]]
+name = "flume"
+version = "0.11.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "da0e4dd2a88388a1f4ccc7c9ce104604dab68d9f408dc34cd45823d5a9069095"
+dependencies = [
+ "futures-core",
+ "futures-sink",
+ "spin",
+]
+
[[package]]
name = "fnv"
version = "1.0.7"
@@ -1204,10 +1224,10 @@ dependencies = [
"http 1.1.0",
"hyper",
"hyper-util",
- "rustls",
+ "rustls 0.23.16",
"rustls-pki-types",
"tokio",
- "tokio-rustls",
+ "tokio-rustls 0.26.0",
"tower-service",
"webpki-roots",
]
@@ -1537,9 +1557,9 @@ dependencies = [
"chrono",
"chrono-tz",
"cron",
+ "nutype",
"serde",
"serde_with",
- "validated_newtype",
]
[[package]]
@@ -1553,16 +1573,42 @@ dependencies = [
"clap",
"cron",
"env_logger",
+ "envconfig",
+ "futures",
+ "futures-util",
"jsonwebtoken",
"kdash_protocol",
"reqwest",
+ "rumqttc",
"serde",
"serde_json",
"serde_with",
+ "tokio",
"url",
"uuid",
]
+[[package]]
+name = "kinded"
+version = "0.3.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ce4bdbb2f423660b19f0e9f7115182214732d8dd5f840cd0a3aee3e22562f34c"
+dependencies = [
+ "kinded_macros",
+]
+
+[[package]]
+name = "kinded_macros"
+version = "0.3.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a13b4ddc5dcb32f45dac3d6f606da2a52fdb9964a18427e63cd5ef6c0d13288d"
+dependencies = [
+ "convert_case 0.6.0",
+ "proc-macro2 1.0.89",
+ "quote 1.0.37",
+ "syn 2.0.87",
+]
+
[[package]]
name = "language-tags"
version = "0.3.2"
@@ -1744,6 +1790,29 @@ dependencies = [
"autocfg",
]
+[[package]]
+name = "nutype"
+version = "0.5.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d8789358e2d6cdffb0cb170c7802ee7548beb8067ed643f3122fa36c335f3c64"
+dependencies = [
+ "nutype_macros",
+]
+
+[[package]]
+name = "nutype_macros"
+version = "0.5.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "93a3e222ba1f06a03552910fe89a232a1661dcf8ad4c837531fb199828d0916b"
+dependencies = [
+ "cfg-if",
+ "kinded",
+ "proc-macro2 1.0.89",
+ "quote 1.0.37",
+ "syn 2.0.87",
+ "urlencoding",
+]
+
[[package]]
name = "object"
version = "0.36.5"
@@ -1980,7 +2049,7 @@ dependencies = [
"quinn-proto",
"quinn-udp",
"rustc-hash",
- "rustls",
+ "rustls 0.23.16",
"socket2",
"thiserror",
"tokio",
@@ -1997,7 +2066,7 @@ dependencies = [
"rand",
"ring",
"rustc-hash",
- "rustls",
+ "rustls 0.23.16",
"slab",
"thiserror",
"tinyvec",
@@ -2138,7 +2207,7 @@ dependencies = [
"percent-encoding",
"pin-project-lite",
"quinn",
- "rustls",
+ "rustls 0.23.16",
"rustls-pemfile",
"rustls-pki-types",
"serde",
@@ -2148,7 +2217,7 @@ dependencies = [
"system-configuration",
"tokio",
"tokio-native-tls",
- "tokio-rustls",
+ "tokio-rustls 0.26.0",
"tokio-util",
"tower-service",
"url",
@@ -2175,6 +2244,24 @@ dependencies = [
"windows-sys 0.52.0",
]
+[[package]]
+name = "rumqttc"
+version = "0.24.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e1568e15fab2d546f940ed3a21f48bbbd1c494c90c99c4481339364a497f94a9"
+dependencies = [
+ "bytes",
+ "flume",
+ "futures-util",
+ "log",
+ "rustls-native-certs",
+ "rustls-pemfile",
+ "rustls-webpki",
+ "thiserror",
+ "tokio",
+ "tokio-rustls 0.25.0",
+]
+
[[package]]
name = "rustc-demangle"
version = "0.1.24"
@@ -2209,6 +2296,20 @@ dependencies = [
"windows-sys 0.52.0",
]
+[[package]]
+name = "rustls"
+version = "0.22.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "bf4ef73721ac7bcd79b2b315da7779d8fc09718c6b3d2d1b2d94850eb8c18432"
+dependencies = [
+ "log",
+ "ring",
+ "rustls-pki-types",
+ "rustls-webpki",
+ "subtle",
+ "zeroize",
+]
+
[[package]]
name = "rustls"
version = "0.23.16"
@@ -2223,6 +2324,19 @@ dependencies = [
"zeroize",
]
+[[package]]
+name = "rustls-native-certs"
+version = "0.7.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e5bfb394eeed242e909609f56089eecfe5fda225042e8b171791b9c95f5931e5"
+dependencies = [
+ "openssl-probe",
+ "rustls-pemfile",
+ "rustls-pki-types",
+ "schannel",
+ "security-framework",
+]
+
[[package]]
name = "rustls-pemfile"
version = "2.2.0"
@@ -2453,6 +2567,9 @@ name = "spin"
version = "0.9.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67"
+dependencies = [
+ "lock_api",
+]
[[package]]
name = "stable_deref_trait"
@@ -2672,13 +2789,24 @@ dependencies = [
"tokio",
]
+[[package]]
+name = "tokio-rustls"
+version = "0.25.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "775e0c0f0adb3a2f22a00c4745d728b479985fc15ee7ca6a2608388c5569860f"
+dependencies = [
+ "rustls 0.22.4",
+ "rustls-pki-types",
+ "tokio",
+]
+
[[package]]
name = "tokio-rustls"
version = "0.26.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0c7bc40d0e5a97695bb96e27995cd3a08538541b0a846f65bba7a359f36700d4"
dependencies = [
- "rustls",
+ "rustls 0.23.16",
"rustls-pki-types",
"tokio",
]
@@ -2740,6 +2868,12 @@ version = "1.0.13"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e91b56cd4cadaeb79bbf1a5645f6b4f8dc5bde8834ad5894a8db35fda9efa1fe"
+[[package]]
+name = "unicode-segmentation"
+version = "1.12.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f6ccf251212114b54433ec949fd6a7841275f9ada20dddd2f29e9ceea4501493"
+
[[package]]
name = "unicode-xid"
version = "0.1.0"
@@ -2764,6 +2898,12 @@ dependencies = [
"serde",
]
+[[package]]
+name = "urlencoding"
+version = "2.1.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "daf8dba3b7eb870caf1ddeed7bc9d2a049f3cfdfae7cb521b087cc33ae4c49da"
+
[[package]]
name = "utf16_iter"
version = "1.0.5"
@@ -2791,15 +2931,6 @@ dependencies = [
"serde",
]
-[[package]]
-name = "validated_newtype"
-version = "0.1.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "160f1ca3dc12c9e48f60b5b7a56092e372bda4ee2805f6c84ae337dd582fe12f"
-dependencies = [
- "serde",
-]
-
[[package]]
name = "vcpkg"
version = "0.2.15"
diff --git a/kdash_client/Cargo.toml b/kdash_client/Cargo.toml
index 6caf854..b0f83bd 100644
--- a/kdash_client/Cargo.toml
+++ b/kdash_client/Cargo.toml
@@ -25,6 +25,8 @@ reqwest = { version = "0.12.9", default-features = false, features = [
"json",
"rustls-tls",
"stream",
+ "http2",
+ "charset",
] }
tinybmp = "0.6.0"
tokio = { version = "1.41.0", features = ["full"] }
diff --git a/kdash_client/extensions/kdash/config.xml b/kdash_client/extensions/kdash/config.xml
new file mode 100644
index 0000000..ca62583
--- /dev/null
+++ b/kdash_client/extensions/kdash/config.xml
@@ -0,0 +1,12 @@
+
+
+
+ kdash
+ 0.1.0
+ dergrimm
+ kdash
+
+
+
+
+
\ No newline at end of file
diff --git a/kdash_client/daemon.sh b/kdash_client/extensions/kdash/daemon.sh
similarity index 57%
rename from kdash_client/daemon.sh
rename to kdash_client/extensions/kdash/daemon.sh
index 24e59f9..e2a815f 100644
--- a/kdash_client/daemon.sh
+++ b/kdash_client/extensions/kdash/daemon.sh
@@ -1,8 +1,9 @@
-#!/usr/bin/env sh
+#!/bin/sh
-DAEMON_PATH="/mnt/us/kdash"
+DAEMON_PATH="/mnt/us/extensions/kdash"
DAEMON_ENV_FILE="${DAEMON_PATH}/kdash.env"
+DAEMON_ENABLED_FILE="${DAEMON_PATH}/ENABLED"
DAEMON="./kdash_client"
DAEMONOPTS=""
@@ -13,20 +14,30 @@ PIDFILE="${DAEMON_PATH}/${DAEMON}.pid"
# SCRIPTNAME="/etc/init.d/${NAME}"
case "$1" in
+enable)
+ touch "$DAEMON_ENABLED_FILE"
+ ;;
+disable)
+ rm -f "$DAEMON_ENABLED_FILE"
+ ;;
start)
- printf "%-50s" "Starting $NAME..."
- cd "$DAEMON_PATH" || exit
- . "$DAEMON_ENV_FILE"
- PID=$(
- RUST_BACKTRACE=full RUST_LOG=debug $DAEMON "$DAEMONOPTS" >/dev/null 2>&1 &
- echo $!
- )
- #echo "Saving PID" $PID " to " $PIDFILE
- if [ -z "$PID" ]; then
- printf "%s\n" "Fail"
+ if [ -e "$DAEMON_ENABLED_FILE" ]; then
+ printf "%-50s" "Starting $NAME..."
+ cd "$DAEMON_PATH" || exit
+ . "$DAEMON_ENV_FILE"
+ PID=$(
+ RUST_BACKTRACE=full RUST_LOG=debug $DAEMON "$DAEMONOPTS" >/dev/null 2>&1 &
+ echo $!
+ )
+ #echo "Saving PID" $PID " to " $PIDFILE
+ if [ -z "$PID" ]; then
+ printf "%s\n" "Fail"
+ else
+ echo "$PID" >"$PIDFILE"
+ printf "%s\n" "Ok"
+ fi
else
- echo "$PID" >"$PIDFILE"
- printf "%s\n" "Ok"
+ echo "Service not enabled. ENABLED file not found"
fi
;;
status)
diff --git a/kdash_client/extensions/kdash/menu.json b/kdash_client/extensions/kdash/menu.json
new file mode 100644
index 0000000..1d7f18c
--- /dev/null
+++ b/kdash_client/extensions/kdash/menu.json
@@ -0,0 +1,13 @@
+{
+ "items": [
+ {
+ "name": "kdash",
+ "items": [
+ { "name": "Enable", "priority": 0, "action": "./daemon.sh enable" },
+ { "name": "Disable", "priority": 0, "action": "./daemon.sh disable" },
+ { "name": "Start", "priority": 0, "action": "./daemon.sh start" },
+ { "name": "Stop", "priority": 0, "action": "./daemon.sh stop" }
+ ]
+ }
+ ]
+}
diff --git a/kdash_client/extensions/kdash/startup.sh b/kdash_client/extensions/kdash/startup.sh
new file mode 100644
index 0000000..08994c0
--- /dev/null
+++ b/kdash_client/extensions/kdash/startup.sh
@@ -0,0 +1,4 @@
+#!/bin/sh
+
+sleep 120
+/mnt/us/extensions/kdash/daemon.sh start
diff --git a/kdash_client/kite/onboot/kdash.sh b/kdash_client/kite/onboot/kdash.sh
new file mode 100644
index 0000000..853ac9f
--- /dev/null
+++ b/kdash_client/kite/onboot/kdash.sh
@@ -0,0 +1,3 @@
+#!/bin/sh
+
+/mnt/us/extensions/kdash/startup.sh &
diff --git a/kdash_client/src/api.rs b/kdash_client/src/api.rs
index c435d16..d0d2a5f 100644
--- a/kdash_client/src/api.rs
+++ b/kdash_client/src/api.rs
@@ -2,6 +2,8 @@ use anyhow::{bail, Result};
use kdash_protocol::Orientation;
use url::Url;
+use crate::battery::BatteryStatus;
+
#[derive(Debug)]
pub struct Api {
pub jwt: String,
@@ -22,7 +24,7 @@ impl Api {
format!("Bearer {}", bearer)
}
- pub async fn fetch_config(&self) -> Result {
+ pub async fn fetch_config(&self) -> Result {
let config = reqwest::Client::new()
.get(self.config_url.to_owned())
.header(
@@ -37,6 +39,30 @@ impl Api {
Ok(config)
}
+ pub async fn fetch_config_with_post_device_state(
+ &self,
+ battery: &BatteryStatus,
+ ) -> Result {
+ let config = reqwest::Client::new()
+ .post(self.config_url.to_owned())
+ .header(
+ reqwest::header::AUTHORIZATION,
+ Self::authorization_bearer(&self.jwt),
+ )
+ .json(&kdash_protocol::DeviceStatePost {
+ battery_charging: battery.is_charging,
+ battery_level: kdash_protocol::Percent::try_new(battery.percentage)?,
+ battery_current: battery.current,
+ battery_voltage: battery.voltage,
+ })
+ .send()
+ .await?
+ .json::()
+ .await?;
+
+ Ok(config)
+ }
+
pub async fn fetch_image<'a>(
&self,
size: (u32, u32),
diff --git a/kdash_client/src/app.rs b/kdash_client/src/app.rs
index c8a9e82..488439d 100644
--- a/kdash_client/src/app.rs
+++ b/kdash_client/src/app.rs
@@ -1,4 +1,4 @@
-use std::{net::IpAddr, path::PathBuf, rc::Rc, sync::Mutex};
+use std::{net::IpAddr, rc::Rc, sync::Mutex};
use openlipc_dyn::Lipc;
@@ -7,18 +7,11 @@ use crate::api;
pub struct State {
pub api: api::Api,
pub app_config: AppConfig,
- pub config: Rc>,
+ pub config: Rc>,
pub lipc: Rc>,
}
pub struct AppConfig {
pub net: String,
pub router_ip: IpAddr,
- pub assets_path: PathBuf,
-}
-
-impl AppConfig {
- pub fn asset(&self, path: &str) -> PathBuf {
- self.assets_path.join(path)
- }
}
diff --git a/kdash_client/src/battery.rs b/kdash_client/src/battery.rs
index e2b3c3f..080fee7 100644
--- a/kdash_client/src/battery.rs
+++ b/kdash_client/src/battery.rs
@@ -8,6 +8,7 @@ pub struct BatteryStatus {
pub is_charging: bool,
pub percentage: u8,
pub current: i16,
+ pub voltage: i16,
}
pub fn get_battery_status() -> Result {
@@ -23,10 +24,14 @@ pub fn get_battery_status() -> Result {
let charge_current_str = utils::exec_command("gasgauge-info", &["-l"])?;
let charge_current = parse::parse_number_from_start_signed::(&charge_current_str)?;
+ let voltage_str = utils::exec_command("gasgauge-info", &["-v"])?;
+ let voltage = parse::parse_number_from_start_signed::(&voltage_str)?;
+
let battery = BatteryStatus {
is_charging,
percentage: charge,
current: charge_current,
+ voltage,
};
log::info!("Got battery status: {:?}", battery);
@@ -44,13 +49,13 @@ pub fn restart_powerd_config_condition(
battery_config: &kdash_protocol::BatteryConfig,
) -> Result<()> {
if battery.is_charging
- && battery.percentage <= *battery_config.restart_powerd_threshold
+ && battery.percentage <= battery_config.restart_powerd_threshold.into_inner()
&& battery.current <= 0
{
log::info!(
"Battery charge below threshold ({} <= {}): restarting powerd",
battery.percentage,
- *battery_config.restart_powerd_threshold
+ battery_config.restart_powerd_threshold.into_inner()
);
restart_powerd()
} else {
diff --git a/kdash_client/src/config.rs b/kdash_client/src/config.rs
index f58b93f..002d8fa 100644
--- a/kdash_client/src/config.rs
+++ b/kdash_client/src/config.rs
@@ -1,5 +1,5 @@
use envconfig::Envconfig;
-use std::{net, path::PathBuf};
+use std::net;
use url::Url;
#[derive(Envconfig, Debug)]
@@ -15,7 +15,4 @@ pub struct Config {
#[envconfig(from = "NET")]
pub net: String,
-
- #[envconfig(from = "ASSETS")]
- pub assets: PathBuf,
}
diff --git a/kdash_client/src/fb/mod.rs b/kdash_client/src/fb/mod.rs
index 12f8d7f..b88808a 100644
--- a/kdash_client/src/fb/mod.rs
+++ b/kdash_client/src/fb/mod.rs
@@ -18,9 +18,9 @@ pub fn eips_clear() -> Result<()> {
utils::exec_command_discard("eips", &["-c"])
}
-pub fn image_buf_to_raw<'a>(
- buf: &'a image::ImageBuffer, Vec>,
-) -> ImageRawBE<'a, Gray8> {
+pub fn image_buf_to_raw(
+ buf: &image::ImageBuffer, Vec>,
+) -> ImageRawBE<'_, Gray8> {
ImageRaw::new(buf.as_raw(), buf.dimensions().0)
}
@@ -186,10 +186,7 @@ impl DrawTarget for FramebufferDisplay {
impl OriginDimensions for FramebufferDisplay {
fn size(&self) -> Size {
- Size::new(
- self.fb_orientation.virtual_x as u32,
- self.fb_orientation.virtual_y as u32,
- )
+ Size::new(self.fb_orientation.virtual_x, self.fb_orientation.virtual_y)
}
}
diff --git a/kdash_client/src/lib.rs b/kdash_client/src/lib.rs
index 9858007..138ef19 100644
--- a/kdash_client/src/lib.rs
+++ b/kdash_client/src/lib.rs
@@ -19,18 +19,18 @@ pub async fn run_once(
state: &app::State,
display: &mut fb::FramebufferDisplay,
) -> Result