diff --git a/backend/src/api/general.rs b/backend/src/api/general.rs index fd032d8..9cda1c2 100644 --- a/backend/src/api/general.rs +++ b/backend/src/api/general.rs @@ -321,3 +321,57 @@ pub fn force_apply( vec![true.into()] } } + +/// Generate get periodicals aggregate method +pub fn get_periodicals(sender: Sender) -> impl AsyncCallable { + let sender = Arc::new(Mutex::new(sender)); // Sender is not Sync; this is required for safety + let getter = move || { + let sender2 = sender.clone(); + move || { + let (rx_curr, callback_curr) = build_comms("battery current callback send failed"); + let (rx_charge_now, callback_charge_now) = build_comms("battery charge now callback send failed"); + let (rx_charge_full, callback_charge_full) = build_comms("battery charge full callback send failed"); + let (rx_charge_power, callback_charge_power) = build_comms("battery charge power callback send failed"); + + let (rx_path, callback_path) = build_comms("general get path (periodical) send failed"); + + let sender_locked = sender2 + .lock() + .unwrap(); + let curr = wait_for_response(&*sender_locked, rx_curr, + ApiMessage::Battery(super::handler::BatteryMessage::ReadCurrentNow(callback_curr)), "battery current"); + let charge_now = wait_for_response(&*sender_locked, rx_charge_now, + ApiMessage::Battery(super::handler::BatteryMessage::ReadChargeNow(callback_charge_now)), "battery charge now"); + let charge_full = wait_for_response(&*sender_locked, rx_charge_full, + ApiMessage::Battery(super::handler::BatteryMessage::ReadChargeFull(callback_charge_full)), "battery charge full"); + let charge_power = wait_for_response(&*sender_locked, rx_charge_power, + ApiMessage::Battery(super::handler::BatteryMessage::ReadChargePower(callback_charge_power)), "battery charge power"); + + let settings_path = wait_for_response(&*sender_locked, rx_path, + ApiMessage::General(GeneralMessage::GetPath(callback_path)), "general get path"); + vec![ + super::utility::map_optional(curr), + super::utility::map_optional(charge_now), + super::utility::map_optional(charge_full), + super::utility::map_optional(charge_power), + + super::utility::map_optional(settings_path.to_str()), + ] + } + }; + super::async_utils::AsyncIshGetter { + set_get: getter, + trans_getter: |result| result, + } +} + +fn build_comms<'a, T: Send + 'a>(msg: &'static str) -> (mpsc::Receiver, Box) { + let (tx, rx) = mpsc::channel(); + let callback = move |t: T| tx.send(t).expect(msg); + (rx, Box::new(callback)) +} + +fn wait_for_response(sender: &Sender, rx: mpsc::Receiver, api_msg: ApiMessage, op: &str) -> T { + sender.send(api_msg).expect(&format!("{} send failed", op)); + rx.recv().expect(&format!("{} callback recv failed", op)) +} diff --git a/backend/src/main.rs b/backend/src/main.rs index 41989d3..6eb6d99 100644 --- a/backend/src/main.rs +++ b/backend/src/main.rs @@ -287,6 +287,10 @@ fn main() -> Result<(), ()> { "GENERAL_on_unplugged", api::battery::on_unplugged(api_sender.clone()), ) + .register_async( + "GENERAL_get_periodicals", + api::general::get_periodicals(api_sender.clone()) + ) .register_async("MESSAGE_get", message_getter) .register_async("MESSAGE_dismiss", message_dismisser); diff --git a/src/backend.ts b/src/backend.ts index 17dac52..07fe9d8 100644 --- a/src/backend.ts +++ b/src/backend.ts @@ -325,3 +325,22 @@ export async function getMessages(since: number | null): Promise { export async function dismissMessage(id: number): Promise { return (await call_backend("MESSAGE_dismiss", [id]))[0]; } + +export type Periodicals = { + battery_current: number | null, + battery_charge_now: number | null, + battery_charge_full: number | null, + battery_charge_power: number | null, + settings_path: string | null, +}; + +export async function getPeriodicals(): Promise { + const result: any[] = await call_backend("GENERAL_get_periodicals", []); + return { + battery_current: result[0], + battery_charge_now: result[1], + battery_charge_full: result[2], + battery_charge_power: result[3], + settings_path: result[4], + }; +} diff --git a/src/index.tsx b/src/index.tsx index f13a69a..8d82d1d 100755 --- a/src/index.tsx +++ b/src/index.tsx @@ -206,19 +206,20 @@ const reload = function() { })(); const periodicals = function() { - backend.resolve(backend.getBatteryCurrent(), (rate: number) => { set_value(CURRENT_BATT, rate) }); - backend.resolve(backend.getBatteryChargeNow(), (rate: number) => { set_value(CHARGE_NOW_BATT, rate) }); - backend.resolve(backend.getBatteryChargeFull(), (rate: number) => { set_value(CHARGE_FULL_BATT, rate) }); - backend.resolve(backend.getBatteryChargePower(), (rate: number) => { set_value(CHARGE_POWER_BATT, rate) }); + backend.resolve(backend.getPeriodicals(), (periodicals) => { + set_value(CURRENT_BATT, periodicals.battery_current); + set_value(CHARGE_NOW_BATT, periodicals.battery_charge_now); + set_value(CHARGE_FULL_BATT, periodicals.battery_charge_full); + set_value(CHARGE_POWER_BATT, periodicals.battery_charge_power); - backend.resolve(backend.getGeneralSettingsPath(), (path: string) => { + const path = periodicals.settings_path; const oldValue = get_value(PATH_GEN); set_value(PATH_GEN, path); if (path != oldValue) { backend.log(backend.LogLevel.Info, "Frontend values reload triggered by path change: " + oldValue + " -> " + path); reload(); } - }); + }) }; const Content: VFC<{ serverAPI: ServerAPI }> = ({}) => {