Can set device desired version
This commit is contained in:
parent
2f971c0055
commit
2feb3f6490
@ -9,7 +9,7 @@ use std::collections::{HashMap, HashSet};
|
|||||||
#[derive(Clone, Debug, serde::Serialize, serde::Deserialize)]
|
#[derive(Clone, Debug, serde::Serialize, serde::Deserialize)]
|
||||||
pub struct DeviceInfo {
|
pub struct DeviceInfo {
|
||||||
/// Device reference
|
/// Device reference
|
||||||
reference: String,
|
pub reference: String,
|
||||||
/// Device firmware / software version
|
/// Device firmware / software version
|
||||||
version: semver::Version,
|
version: semver::Version,
|
||||||
/// Maximum number of relay that the device can support
|
/// Maximum number of relay that the device can support
|
||||||
@ -62,6 +62,9 @@ pub struct Device {
|
|||||||
///
|
///
|
||||||
/// There cannot be more than [info.max_relays] relays
|
/// There cannot be more than [info.max_relays] relays
|
||||||
pub relays: Vec<DeviceRelay>,
|
pub relays: Vec<DeviceRelay>,
|
||||||
|
/// Desired version, ie. the version of the software we would to seen run on the device
|
||||||
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
|
pub desired_version: Option<semver::Version>,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Structure that contains information about the minimal expected execution
|
/// Structure that contains information about the minimal expected execution
|
||||||
|
@ -84,6 +84,7 @@ impl DevicesList {
|
|||||||
validated: false,
|
validated: false,
|
||||||
enabled: false,
|
enabled: false,
|
||||||
relays: vec![],
|
relays: vec![],
|
||||||
|
desired_version: None,
|
||||||
};
|
};
|
||||||
|
|
||||||
// First, write CSR
|
// First, write CSR
|
||||||
@ -186,6 +187,24 @@ impl DevicesList {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Set a device desired version
|
||||||
|
pub fn set_desired_version(
|
||||||
|
&mut self,
|
||||||
|
id: &DeviceId,
|
||||||
|
version: Option<semver::Version>,
|
||||||
|
) -> anyhow::Result<()> {
|
||||||
|
let dev = self
|
||||||
|
.0
|
||||||
|
.get_mut(id)
|
||||||
|
.ok_or(DevicesListError::UpdateDeviceFailedDeviceNotFound)?;
|
||||||
|
|
||||||
|
dev.desired_version = version;
|
||||||
|
|
||||||
|
self.persist_dev_config(id)?;
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
/// Get single certificate information
|
/// Get single certificate information
|
||||||
fn get_cert(&self, id: &DeviceId) -> anyhow::Result<X509> {
|
fn get_cert(&self, id: &DeviceId) -> anyhow::Result<X509> {
|
||||||
let dev = self
|
let dev = self
|
||||||
|
@ -195,6 +195,27 @@ impl Handler<UpdateDeviceGeneralInfo> for EnergyActor {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Set device desired version
|
||||||
|
#[derive(Message)]
|
||||||
|
#[rtype(result = "anyhow::Result<()>")]
|
||||||
|
pub struct SetDesiredVersion(pub DeviceId, pub Option<semver::Version>);
|
||||||
|
|
||||||
|
impl Handler<SetDesiredVersion> for EnergyActor {
|
||||||
|
type Result = anyhow::Result<()>;
|
||||||
|
|
||||||
|
fn handle(&mut self, msg: SetDesiredVersion, _ctx: &mut Context<Self>) -> Self::Result {
|
||||||
|
log::info!(
|
||||||
|
"Requested to update device desired version {:?} => {:#?}",
|
||||||
|
&msg.0,
|
||||||
|
&msg.1
|
||||||
|
);
|
||||||
|
|
||||||
|
self.devices.set_desired_version(&msg.0, msg.1)?;
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Delete a device
|
/// Delete a device
|
||||||
#[derive(Message)]
|
#[derive(Message)]
|
||||||
#[rtype(result = "anyhow::Result<()>")]
|
#[rtype(result = "anyhow::Result<()>")]
|
||||||
|
@ -189,11 +189,13 @@ pub async fn secure_server(energy_actor: EnergyActorAddr) -> anyhow::Result<()>
|
|||||||
"/web_api/ota/{platform}/{version}",
|
"/web_api/ota/{platform}/{version}",
|
||||||
web::post().to(ota_controller::upload_firmware),
|
web::post().to(ota_controller::upload_firmware),
|
||||||
)
|
)
|
||||||
// TODO : upload a new software update
|
|
||||||
// TODO : list ota software update per platform
|
// TODO : list ota software update per platform
|
||||||
// TODO : download a OTA file
|
// TODO : download a OTA file
|
||||||
// TODO : delete an OTA file
|
// TODO : delete an OTA file
|
||||||
// TODO : deploy an update to a device
|
.route(
|
||||||
|
"/web_api/ota/set_desired_version",
|
||||||
|
web::post().to(ota_controller::set_desired_version),
|
||||||
|
)
|
||||||
// Logging controller API
|
// Logging controller API
|
||||||
.route(
|
.route(
|
||||||
"/web_api/logging/logs",
|
"/web_api/logging/logs",
|
||||||
|
@ -1,7 +1,10 @@
|
|||||||
use crate::constants;
|
use crate::constants;
|
||||||
|
use crate::devices::device::DeviceId;
|
||||||
|
use crate::energy::energy_actor;
|
||||||
use crate::ota::ota_manager;
|
use crate::ota::ota_manager;
|
||||||
use crate::ota::ota_update::OTAPlatform;
|
use crate::ota::ota_update::OTAPlatform;
|
||||||
use crate::server::custom_error::HttpResult;
|
use crate::server::custom_error::HttpResult;
|
||||||
|
use crate::server::WebEnergyActor;
|
||||||
use actix_multipart::form::tempfile::TempFile;
|
use actix_multipart::form::tempfile::TempFile;
|
||||||
use actix_multipart::form::MultipartForm;
|
use actix_multipart::form::MultipartForm;
|
||||||
use actix_web::{web, HttpResponse};
|
use actix_web::{web, HttpResponse};
|
||||||
@ -49,3 +52,48 @@ pub async fn upload_firmware(
|
|||||||
|
|
||||||
Ok(HttpResponse::Accepted().body("OTA update successfully saved."))
|
Ok(HttpResponse::Accepted().body("OTA update successfully saved."))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(serde::Deserialize)]
|
||||||
|
pub struct SetDesiredDeviceVersion {
|
||||||
|
devices: Option<Vec<DeviceId>>,
|
||||||
|
platform: Option<OTAPlatform>,
|
||||||
|
version: semver::Version,
|
||||||
|
}
|
||||||
|
|
||||||
|
pub async fn set_desired_version(
|
||||||
|
actor: WebEnergyActor,
|
||||||
|
body: web::Json<SetDesiredDeviceVersion>,
|
||||||
|
) -> HttpResult {
|
||||||
|
if body.devices.is_none() && body.platform.is_none() {
|
||||||
|
return Ok(
|
||||||
|
HttpResponse::BadRequest().json("Must specify one filter to select target devices!")
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
let devices = actor.send(energy_actor::GetDeviceLists).await?;
|
||||||
|
|
||||||
|
for d in devices {
|
||||||
|
// Filter per platform
|
||||||
|
if let Some(p) = body.platform {
|
||||||
|
if d.info.reference != p.to_string() {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Filter per device
|
||||||
|
if let Some(ids) = &body.devices {
|
||||||
|
if !ids.contains(&d.id) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
actor
|
||||||
|
.send(energy_actor::SetDesiredVersion(
|
||||||
|
d.id,
|
||||||
|
Some(body.version.clone()),
|
||||||
|
))
|
||||||
|
.await??;
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(HttpResponse::Ok().finish())
|
||||||
|
}
|
||||||
|
@ -37,6 +37,7 @@ export interface Device {
|
|||||||
validated: boolean;
|
validated: boolean;
|
||||||
enabled: boolean;
|
enabled: boolean;
|
||||||
relays: DeviceRelay[];
|
relays: DeviceRelay[];
|
||||||
|
desired_version?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface UpdatedInfo {
|
export interface UpdatedInfo {
|
||||||
|
@ -41,6 +41,10 @@ export function GeneralDeviceInfo(p: {
|
|||||||
value={p.device.info.reference}
|
value={p.device.info.reference}
|
||||||
/>
|
/>
|
||||||
<DeviceInfoProperty label="Version" value={p.device.info.version} />
|
<DeviceInfoProperty label="Version" value={p.device.info.version} />
|
||||||
|
<DeviceInfoProperty
|
||||||
|
label="Desired version"
|
||||||
|
value={p.device.desired_version ?? "None"}
|
||||||
|
/>
|
||||||
<DeviceInfoProperty label="Name" value={p.device.name} />
|
<DeviceInfoProperty label="Name" value={p.device.name} />
|
||||||
<DeviceInfoProperty
|
<DeviceInfoProperty
|
||||||
label="Description"
|
label="Description"
|
||||||
|
@ -14,4 +14,5 @@ Upload firmware to central backend, in dev mode:
|
|||||||
|
|
||||||
```bash
|
```bash
|
||||||
curl -k -X POST https://localhost:8443/web_api/ota/Wt32-Eth01/$(cat version.txt) --form firmware="@build/main.bin"
|
curl -k -X POST https://localhost:8443/web_api/ota/Wt32-Eth01/$(cat version.txt) --form firmware="@build/main.bin"
|
||||||
|
curl -k -X POST https://localhost:8443/web_api/ota/set_desired_version --header "Content-Type: application/json" --data "{\"platform\": \"Wt32-Eth01\", \"version\": \"$(cat version.txt)\"}"
|
||||||
```
|
```
|
5
esp32_device/build_upload_dev.sh
Executable file
5
esp32_device/build_upload_dev.sh
Executable file
@ -0,0 +1,5 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
idf.py build && \
|
||||||
|
curl -k -X POST https://localhost:8443/web_api/ota/Wt32-Eth01/$(cat version.txt) --form firmware="@build/main.bin" && \
|
||||||
|
curl -k -X POST https://localhost:8443/web_api/ota/set_desired_version --header "Content-Type: application/json" --data "{\"platform\": \"Wt32-Eth01\", \"version\": \"$(cat version.txt)\"}"
|
Loading…
Reference in New Issue
Block a user