Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[RSDK-9887] get agent config from app #417

Merged
merged 12 commits into from
Feb 20, 2025
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(),
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What happens if we just don't set agent_running?

..Default::default()
});

let req = DeviceAgentConfigRequest {
id: self.robot_credentials.robot_id.clone(),
host_info,
version_info,
subsystem_versions: Default::default(),
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you eliminate even namign this field in favor of ..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 All @@ -20,6 +23,72 @@ pub enum AttributeError {
ValidationError(String),
}

impl TryFrom<&DeviceAgentConfigResponse> for AgentConfig {
type Error = AttributeError;
fn try_from(value: &DeviceAgentConfigResponse) -> Result<Self, Self::Error> {
if let Some(ref additional_networks) = value.additional_networks {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Instead of ref, could you do value.additional_networks.as_ref() or &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)
}
}
}

#[derive(Debug)]
pub struct AgentConfig {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have a slight preference for having the struct be introduced before any impl blocks for it. Could you move this up above line 26 please?

pub network_settings: Vec<NetworkSetting>,
}

pub struct NetworkSetting {
ssid: String,
password: String,
priority: usize,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I believe priority is permitted to be negative, so I don't think a usize is the right type.

}

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: usize = 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
)
}
}

impl From<ParseIntError> for AttributeError {
fn from(_: ParseIntError) -> AttributeError {
AttributeError::ParseNumError
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