Update
This commit is contained in:
parent
76b43a0386
commit
220a446fb6
21 changed files with 677 additions and 111 deletions
|
@ -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"] }
|
||||
|
|
12
kdash_client/extensions/kdash/config.xml
Normal file
12
kdash_client/extensions/kdash/config.xml
Normal file
|
@ -0,0 +1,12 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<extension>
|
||||
<information>
|
||||
<name>kdash</name>
|
||||
<version>0.1.0</version>
|
||||
<author>dergrimm</author>
|
||||
<id>kdash</id>
|
||||
</information>
|
||||
<menus>
|
||||
<menu type="json" dynamic="false">menu.json</menu>
|
||||
</menus>
|
||||
</extension>
|
|
@ -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)
|
13
kdash_client/extensions/kdash/menu.json
Normal file
13
kdash_client/extensions/kdash/menu.json
Normal file
|
@ -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" }
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
4
kdash_client/extensions/kdash/startup.sh
Normal file
4
kdash_client/extensions/kdash/startup.sh
Normal file
|
@ -0,0 +1,4 @@
|
|||
#!/bin/sh
|
||||
|
||||
sleep 120
|
||||
/mnt/us/extensions/kdash/daemon.sh start
|
3
kdash_client/kite/onboot/kdash.sh
Normal file
3
kdash_client/kite/onboot/kdash.sh
Normal file
|
@ -0,0 +1,3 @@
|
|||
#!/bin/sh
|
||||
|
||||
/mnt/us/extensions/kdash/startup.sh &
|
|
@ -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<kdash_protocol::Config, reqwest::Error> {
|
||||
pub async fn fetch_config(&self) -> Result<kdash_protocol::Config> {
|
||||
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<kdash_protocol::Config> {
|
||||
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::<kdash_protocol::Config>()
|
||||
.await?;
|
||||
|
||||
Ok(config)
|
||||
}
|
||||
|
||||
pub async fn fetch_image<'a>(
|
||||
&self,
|
||||
size: (u32, u32),
|
||||
|
|
|
@ -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<Mutex<kdash_protocol::Config>>,
|
||||
pub config: Rc<tokio::sync::Mutex<kdash_protocol::Config>>,
|
||||
pub lipc: Rc<Mutex<Lipc>>,
|
||||
}
|
||||
|
||||
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)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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<BatteryStatus> {
|
||||
|
@ -23,10 +24,14 @@ pub fn get_battery_status() -> Result<BatteryStatus> {
|
|||
let charge_current_str = utils::exec_command("gasgauge-info", &["-l"])?;
|
||||
let charge_current = parse::parse_number_from_start_signed::<i16>(&charge_current_str)?;
|
||||
|
||||
let voltage_str = utils::exec_command("gasgauge-info", &["-v"])?;
|
||||
let voltage = parse::parse_number_from_start_signed::<i16>(&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 {
|
||||
|
|
|
@ -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,
|
||||
}
|
||||
|
|
|
@ -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<image::Luma<u8>, Vec<u8>>,
|
||||
) -> ImageRawBE<'a, Gray8> {
|
||||
pub fn image_buf_to_raw(
|
||||
buf: &image::ImageBuffer<image::Luma<u8>, Vec<u8>>,
|
||||
) -> 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)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -19,18 +19,18 @@ pub async fn run_once(
|
|||
state: &app::State,
|
||||
display: &mut fb::FramebufferDisplay,
|
||||
) -> Result<Option<kdash_protocol::Config>> {
|
||||
let config = state.config.lock().unwrap();
|
||||
let config = state.config.lock().await;
|
||||
|
||||
utils::set_cpu_powersaving()?;
|
||||
utils::prevent_screensaver(&state.lipc.lock().unwrap())?;
|
||||
|
||||
let battery = battery::get_battery_status()?;
|
||||
battery::restart_powerd_config_condition(&battery, &config.battery)?;
|
||||
if battery.percentage <= *config.battery.low {
|
||||
if battery.percentage <= config.battery.low.into_inner() {
|
||||
log::info!(
|
||||
"Battery low: {}% <= {}%",
|
||||
battery.percentage,
|
||||
*config.battery.low
|
||||
config.battery.low.into_inner()
|
||||
);
|
||||
|
||||
Image::new(&*assets::ERROR_BATTERY_LOW_IMAGE, Point::zero())
|
||||
|
@ -66,7 +66,11 @@ pub async fn run_once(
|
|||
|
||||
log::info!("Fetching config");
|
||||
|
||||
let fetch_succ = match state.api.fetch_config().await {
|
||||
let fetch_succ = match state
|
||||
.api
|
||||
.fetch_config_with_post_device_state(&battery)
|
||||
.await
|
||||
{
|
||||
Ok(value) => {
|
||||
new_config = Some(value);
|
||||
|
||||
|
@ -107,7 +111,7 @@ pub async fn run_once(
|
|||
.draw(display)?;
|
||||
}
|
||||
|
||||
if battery.percentage <= *config.battery.alert {
|
||||
if battery.percentage <= config.battery.alert.into_inner() {
|
||||
let now_str = Utc::now().to_rfc3339_opts(SecondsFormat::Secs, true);
|
||||
let text = format!("Battery at {}%, please charge!", battery.percentage);
|
||||
let status_box = fb::widgets::status_box::StatusBox::new_with_default_style(
|
||||
|
|
|
@ -4,8 +4,6 @@ use envconfig::Envconfig;
|
|||
use openlipc_dyn::Lipc;
|
||||
use std::{rc::Rc, sync::Mutex, thread, time};
|
||||
|
||||
use kdash_client;
|
||||
|
||||
#[tokio::main]
|
||||
async fn main() -> Result<()> {
|
||||
env_logger::init();
|
||||
|
@ -13,7 +11,9 @@ async fn main() -> Result<()> {
|
|||
let env_config = kdash_client::config::Config::init_from_env().unwrap();
|
||||
|
||||
let api = kdash_client::api::Api::new(env_config.kdash_jwt, env_config.kdash_url)?;
|
||||
let config = api.fetch_config().await?;
|
||||
|
||||
let battery = kdash_client::battery::get_battery_status()?;
|
||||
let config = api.fetch_config_with_post_device_state(&battery).await?;
|
||||
|
||||
let lipc = Lipc::load(None)?;
|
||||
|
||||
|
@ -22,15 +22,14 @@ async fn main() -> Result<()> {
|
|||
app_config: kdash_client::app::AppConfig {
|
||||
net: env_config.net,
|
||||
router_ip: env_config.router_ip,
|
||||
assets_path: env_config.assets,
|
||||
},
|
||||
config: Rc::new(Mutex::new(config)),
|
||||
config: Rc::new(tokio::sync::Mutex::new(config)),
|
||||
lipc: Rc::new(Mutex::new(lipc)),
|
||||
};
|
||||
|
||||
let mut display = kdash_client::fb::FramebufferDisplay::new(
|
||||
kdash_client::fb::DEFAULT_FB,
|
||||
state.config.lock().unwrap().device.orientation,
|
||||
state.config.lock().await.device.orientation,
|
||||
)?;
|
||||
|
||||
kdash_client::utils::kill_kindle()?;
|
||||
|
@ -44,7 +43,7 @@ async fn main() -> Result<()> {
|
|||
match kdash_client::run_once(&state, &mut display).await {
|
||||
Ok(Some(new_config)) => {
|
||||
log::info!("Updating config");
|
||||
let mut config = state.config.lock().unwrap();
|
||||
let mut config = state.config.lock().await;
|
||||
if display.fb_orientation.orientation != new_config.device.orientation {
|
||||
log::info!(
|
||||
"Updating orientation: {:?} -> {:?}",
|
||||
|
@ -65,7 +64,7 @@ async fn main() -> Result<()> {
|
|||
}
|
||||
}
|
||||
|
||||
let config = state.config.lock().unwrap();
|
||||
let config = state.config.lock().await;
|
||||
|
||||
thread::sleep(config.time.delay_before_suspend.to_std()?);
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue