Skip to content

Commit

Permalink
[RSDK-9887] get agent config from app (#417)
Browse files Browse the repository at this point in the history
  • Loading branch information
mattjperez authored Feb 20, 2025
1 parent 695fd5a commit 751e5c9
Show file tree
Hide file tree
Showing 4 changed files with 139 additions and 4 deletions.
52 changes: 49 additions & 3 deletions micro-rdk/src/common/app_client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,15 @@
use crate::proto::app::v1::CertificateRequest;
use crate::proto::app::v1::CertificateResponse;
use crate::proto::{
app::v1::{
AgentInfo, ConfigRequest, ConfigResponse, LogRequest, NeedsRestartRequest,
NeedsRestartResponse,
app::{
agent::v1::{
DeviceAgentConfigRequest, DeviceAgentConfigResponse, DeviceSubsystemConfig, HostInfo,
VersionInfo,
},
v1::{
AgentInfo, ConfigRequest, ConfigResponse, LogRequest, NeedsRestartRequest,
NeedsRestartResponse,
},
},
common::v1::LogEntry,
rpc::{
Expand Down Expand Up @@ -323,6 +329,46 @@ impl AppClient {
Ok((Box::new(cfg_response), datetime))
}

pub async fn get_agent_config(&self) -> Result<Box<DeviceAgentConfigResponse>, AppClientError> {
let host_info = Some(HostInfo {
platform: "micro-rdk/esp32".to_string(),
distro: "esp32".to_string(),
tags: Default::default(),
});

let version_info = Some(VersionInfo {
agent_running: "none".to_string(),
..Default::default()
});

let req = DeviceAgentConfigRequest {
id: self.robot_credentials.robot_id.clone(),
host_info,
version_info,
..Default::default()
};
let body = encode_request(req)?;

let r = self
.grpc_client
.build_request(
"/viam.app.agent.v1.AgentDeviceService/DeviceAgentConfig",
Some(&self.jwt),
"",
BodyExt::boxed(Full::new(body).map_err(|never| match never {})),
)
.map_err(AppClientError::AppGrpcClientError)?;

let (mut r, headers) = self.grpc_client.send_request(r).await?;

if r.is_empty() {
return Err(AppClientError::AppClientEmptyBody);
}
let cfg_response = DeviceAgentConfigResponse::decode(r.split_off(5))?;

Ok(Box::new(cfg_response))
}

pub async fn push_logs(&self, logs: Vec<LogEntry>) -> Result<(), AppClientError> {
let req = LogRequest {
id: self.robot_credentials.robot_id.clone(),
Expand Down
71 changes: 70 additions & 1 deletion micro-rdk/src/common/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,10 @@
#[cfg(feature = "data")]
use crate::common::data_collector::DataCollectorConfig;
use crate::google;
use crate::proto::{app::v1::ComponentConfig, common::v1::ResourceName};
use crate::proto::{
app::{agent::v1::DeviceAgentConfigResponse, v1::ComponentConfig},
common::v1::ResourceName,
};

use std::collections::HashMap;
use std::num::{ParseFloatError, ParseIntError};
Expand Down Expand Up @@ -404,6 +407,72 @@ impl Component for DynamicComponentConfig {
}
}

#[derive(Debug)]
pub struct AgentConfig {
pub network_settings: Vec<NetworkSetting>,
}

impl TryFrom<&DeviceAgentConfigResponse> for AgentConfig {
type Error = AttributeError;
fn try_from(value: &DeviceAgentConfigResponse) -> Result<Self, Self::Error> {
if let Some(additional_networks) = &value.additional_networks {
let network_settings = additional_networks
.fields
.iter()
.filter_map(|(_k, v)| {
let local_kind: Option<Kind> =
v.kind.clone().and_then(|v| Kind::try_from(v).ok());
local_kind
.as_ref()
.and_then(|v| NetworkSetting::try_from(v).ok())
})
.collect::<Vec<NetworkSetting>>();
Ok(Self { network_settings })
} else {
Err(AttributeError::ConversionImpossibleError)
}
}
}

pub struct NetworkSetting {
ssid: String,
password: String,
priority: i32,
}

impl TryFrom<&Kind> for NetworkSetting {
type Error = AttributeError;
fn try_from(value: &Kind) -> Result<Self, Self::Error> {
let ssid: String = value
.get("ssid")?
.ok_or(AttributeError::ConversionImpossibleError)?
.try_into()?;
let password: String = value
.get("psk")?
.ok_or(AttributeError::ConversionImpossibleError)?
.try_into()?;
let priority: i32 = value
.get("priority")?
.ok_or(AttributeError::ConversionImpossibleError)?
.try_into()?;
Ok(Self {
ssid,
password,
priority,
})
}
}

impl std::fmt::Debug for NetworkSetting {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(
f,
"NetworkSetting {{ ssid: {}, password: ***, priority: {} }}",
self.ssid, self.priority
)
}
}

#[cfg(test)]
mod tests {
use std::collections::HashMap;
Expand Down
15 changes: 15 additions & 0 deletions micro-rdk/src/common/conn/viam.rs
Original file line number Diff line number Diff line change
Expand Up @@ -558,6 +558,21 @@ where
None => None,
};

// TODO(RSDK-9887): remove after implementing agent NVS storage
if let Some(app) = app_client.as_ref() {
use crate::common::config::AgentConfig;
if let Ok(device_agent_config) = app.get_agent_config().await {
let agent_config: AgentConfig =
device_agent_config
.as_ref()
.try_into()
.unwrap_or(AgentConfig {
network_settings: Vec::new(),
});
log::debug!("agent config: {:?}", agent_config);
}
}

let (config, build_time) = config.map_or_else(
|| {
(
Expand Down
5 changes: 5 additions & 0 deletions micro-rdk/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,11 @@ pub mod proto {
pub mod v1 {
include!("gen/viam.app.v1.rs");
}
pub mod agent {
pub mod v1 {
include!("gen/viam.app.agent.v1.rs");
}
}
pub mod packages {
pub mod v1 {
include!("gen/viam.app.packages.v1.rs");
Expand Down

0 comments on commit 751e5c9

Please sign in to comment.