Can manually download an OTA update
This commit is contained in:
parent
6cf7c2cae1
commit
2e4a2b68dd
@ -191,13 +191,16 @@ 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),
|
||||||
)
|
)
|
||||||
|
.route(
|
||||||
|
"/web_api/ota/{platform}/{version}",
|
||||||
|
web::get().to(ota_controller::download_firmware),
|
||||||
|
)
|
||||||
|
// TODO : delete an OTA file
|
||||||
.route("/web_api/ota", web::get().to(ota_controller::list_all_ota))
|
.route("/web_api/ota", web::get().to(ota_controller::list_all_ota))
|
||||||
.route(
|
.route(
|
||||||
"/web_api/ota/{platform}",
|
"/web_api/ota/{platform}",
|
||||||
web::get().to(ota_controller::list_updates_platform),
|
web::get().to(ota_controller::list_updates_platform),
|
||||||
)
|
)
|
||||||
// TODO : download a OTA file
|
|
||||||
// TODO : delete an OTA file
|
|
||||||
.route(
|
.route(
|
||||||
"/web_api/ota/set_desired_version",
|
"/web_api/ota/set_desired_version",
|
||||||
web::post().to(ota_controller::set_desired_version),
|
web::post().to(ota_controller::set_desired_version),
|
||||||
|
@ -20,14 +20,15 @@ pub struct UploadForm {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[derive(serde::Deserialize)]
|
#[derive(serde::Deserialize)]
|
||||||
pub struct UploadPath {
|
pub struct SpecificOTAVersionPath {
|
||||||
platform: OTAPlatform,
|
platform: OTAPlatform,
|
||||||
version: semver::Version,
|
version: semver::Version,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Upload a new firmware update
|
||||||
pub async fn upload_firmware(
|
pub async fn upload_firmware(
|
||||||
MultipartForm(form): MultipartForm<UploadForm>,
|
MultipartForm(form): MultipartForm<UploadForm>,
|
||||||
path: web::Path<UploadPath>,
|
path: web::Path<SpecificOTAVersionPath>,
|
||||||
) -> HttpResult {
|
) -> HttpResult {
|
||||||
if ota_manager::update_exists(path.platform, &path.version)? {
|
if ota_manager::update_exists(path.platform, &path.version)? {
|
||||||
return Ok(HttpResponse::Conflict()
|
return Ok(HttpResponse::Conflict()
|
||||||
@ -53,6 +54,26 @@ pub async fn upload_firmware(
|
|||||||
Ok(HttpResponse::Accepted().body("OTA update successfully saved."))
|
Ok(HttpResponse::Accepted().body("OTA update successfully saved."))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Download a firmware update
|
||||||
|
pub async fn download_firmware(path: web::Path<SpecificOTAVersionPath>) -> HttpResult {
|
||||||
|
if !ota_manager::update_exists(path.platform, &path.version)? {
|
||||||
|
return Ok(HttpResponse::NotFound().json("The requested firmware was not found!"));
|
||||||
|
}
|
||||||
|
|
||||||
|
let firmware = ota_manager::get_ota_update(path.platform, &path.version)?;
|
||||||
|
|
||||||
|
Ok(HttpResponse::Ok()
|
||||||
|
.content_type("application/octet-stream")
|
||||||
|
.append_header((
|
||||||
|
"content-disposition",
|
||||||
|
format!(
|
||||||
|
"attachment; filename=\"{}-{}.bin\"",
|
||||||
|
path.platform, path.version
|
||||||
|
),
|
||||||
|
))
|
||||||
|
.body(firmware))
|
||||||
|
}
|
||||||
|
|
||||||
/// Get the list of all OTA updates
|
/// Get the list of all OTA updates
|
||||||
pub async fn list_all_ota() -> HttpResult {
|
pub async fn list_all_ota() -> HttpResult {
|
||||||
Ok(HttpResponse::Ok().json(ota_manager::get_all_ota_updates()?))
|
Ok(HttpResponse::Ok().json(ota_manager::get_all_ota_updates()?))
|
||||||
|
@ -37,6 +37,13 @@ export class OTAAPI {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the link to download an OTA update
|
||||||
|
*/
|
||||||
|
static DownloadOTAUpdateURL(platform: string, version: string): string {
|
||||||
|
return APIClient.backendURL() + `/ota/${platform}/${version}`;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the list of OTA updates
|
* Get the list of OTA updates
|
||||||
*/
|
*/
|
||||||
|
@ -1,3 +1,5 @@
|
|||||||
|
import DownloadIcon from "@mui/icons-material/Download";
|
||||||
|
import FileUploadIcon from "@mui/icons-material/FileUpload";
|
||||||
import {
|
import {
|
||||||
IconButton,
|
IconButton,
|
||||||
Paper,
|
Paper,
|
||||||
@ -9,13 +11,13 @@ import {
|
|||||||
TableRow,
|
TableRow,
|
||||||
Tooltip,
|
Tooltip,
|
||||||
} from "@mui/material";
|
} from "@mui/material";
|
||||||
import { SolarEnergyRouteContainer } from "../widgets/SolarEnergyRouteContainer";
|
import { filesize } from "filesize";
|
||||||
import FileUploadIcon from "@mui/icons-material/FileUpload";
|
|
||||||
import { UploadUpdateDialog } from "../dialogs/UploadUpdateDialog";
|
|
||||||
import React from "react";
|
import React from "react";
|
||||||
import { OTAAPI, OTAUpdate } from "../api/OTAApi";
|
import { OTAAPI, OTAUpdate } from "../api/OTAApi";
|
||||||
|
import { UploadUpdateDialog } from "../dialogs/UploadUpdateDialog";
|
||||||
import { AsyncWidget } from "../widgets/AsyncWidget";
|
import { AsyncWidget } from "../widgets/AsyncWidget";
|
||||||
import { filesize } from "filesize";
|
import { RouterLink } from "../widgets/RouterLink";
|
||||||
|
import { SolarEnergyRouteContainer } from "../widgets/SolarEnergyRouteContainer";
|
||||||
|
|
||||||
export function OTARoute(): React.ReactElement {
|
export function OTARoute(): React.ReactElement {
|
||||||
const [list, setList] = React.useState<string[] | undefined>();
|
const [list, setList] = React.useState<string[] | undefined>();
|
||||||
@ -97,6 +99,7 @@ function _OTAList(p: { list: OTAUpdate[] }): React.ReactElement {
|
|||||||
<TableCell align="center">Platform</TableCell>
|
<TableCell align="center">Platform</TableCell>
|
||||||
<TableCell align="center">Version</TableCell>
|
<TableCell align="center">Version</TableCell>
|
||||||
<TableCell align="center">File size</TableCell>
|
<TableCell align="center">File size</TableCell>
|
||||||
|
<TableCell align="center"></TableCell>
|
||||||
</TableRow>
|
</TableRow>
|
||||||
</TableHead>
|
</TableHead>
|
||||||
<TableBody>
|
<TableBody>
|
||||||
@ -105,6 +108,17 @@ function _OTAList(p: { list: OTAUpdate[] }): React.ReactElement {
|
|||||||
<TableCell align="center">{row.platform}</TableCell>
|
<TableCell align="center">{row.platform}</TableCell>
|
||||||
<TableCell align="center">{row.version}</TableCell>
|
<TableCell align="center">{row.version}</TableCell>
|
||||||
<TableCell align="center">{filesize(row.file_size)}</TableCell>
|
<TableCell align="center">{filesize(row.file_size)}</TableCell>
|
||||||
|
<TableCell align="center">
|
||||||
|
<Tooltip title="Download a copy of the firmware">
|
||||||
|
<RouterLink
|
||||||
|
to={OTAAPI.DownloadOTAUpdateURL(row.platform, row.version)}
|
||||||
|
>
|
||||||
|
<IconButton>
|
||||||
|
<DownloadIcon />
|
||||||
|
</IconButton>
|
||||||
|
</RouterLink>
|
||||||
|
</Tooltip>
|
||||||
|
</TableCell>
|
||||||
</TableRow>
|
</TableRow>
|
||||||
))}
|
))}
|
||||||
</TableBody>
|
</TableBody>
|
||||||
|
Loading…
Reference in New Issue
Block a user