@@ -5,20 +5,14 @@ jobs:
|
||||
test:
|
||||
runs-on: ubuntu-latest
|
||||
container:
|
||||
image: rust:bullseye
|
||||
|
||||
# Service containers to run with `container-job`
|
||||
image: rust:latest
|
||||
services:
|
||||
# Label used to access the service container
|
||||
db:
|
||||
# Docker Hub image
|
||||
image: postgres:latest
|
||||
# Provide the password for postgres
|
||||
env:
|
||||
POSTGRES_USER: dev
|
||||
POSTGRES_PASSWORD: dev
|
||||
POSTGRES_DB: iot
|
||||
# Set health checks to wait until postgres has started
|
||||
options: >-
|
||||
--health-cmd pg_isready
|
||||
--health-interval 10s
|
||||
@@ -43,14 +37,22 @@ jobs:
|
||||
- name: Log in to Docker Registry
|
||||
uses: docker/login-action@v1
|
||||
with:
|
||||
registry: gitea.maiertobi.de # Replace with your Docker registry URL
|
||||
registry: gitea.maiertobi.de
|
||||
username: tobimai
|
||||
password: ${{ secrets.docker_registry_key }}
|
||||
- name: Extract Version from Cargo.toml
|
||||
id: cargo_version
|
||||
run: |
|
||||
VERSION=$(grep '^version' Cargo.toml | head -n 1 | cut -d ' ' -f 3 | tr -d '"')
|
||||
echo "VERSION=$VERSION" >> $GITEA_ENV
|
||||
- name: Test
|
||||
run: echo $VERSION
|
||||
- name: Build and Push Docker Image
|
||||
uses: docker/build-push-action@v2
|
||||
with:
|
||||
context: .
|
||||
push: true
|
||||
tags: gitea.maiertobi.de/tobimai/iot # Replace with your Docker image's details
|
||||
tags: gitea.maiertobi.de/tobimai/iot:$VERSION
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -6,19 +6,13 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
container:
|
||||
image: rust:latest
|
||||
|
||||
# Service containers to run with `container-job`
|
||||
services:
|
||||
# Label used to access the service container
|
||||
db:
|
||||
# Docker Hub image
|
||||
image: postgres:latest
|
||||
# Provide the password for postgres
|
||||
env:
|
||||
POSTGRES_USER: dev
|
||||
POSTGRES_PASSWORD: dev
|
||||
POSTGRES_DB: iot
|
||||
# Set health checks to wait until postgres has started
|
||||
options: >-
|
||||
--health-cmd pg_isready
|
||||
--health-interval 10s
|
||||
|
||||
@@ -17,3 +17,7 @@ sqlx-cli = "0.8"
|
||||
strum = { version = "0.26.3", features = ["derive"] }
|
||||
thiserror = "1.0"
|
||||
tokio = { version = "1", features = ["fs", "rt-multi-thread"] }
|
||||
|
||||
|
||||
[lints.clippy]
|
||||
pedantic = "warn"
|
||||
@@ -41,7 +41,7 @@ impl Database {
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
pub async fn init_from_pool(pool: Pool<Postgres>) -> Database {
|
||||
pub fn init_from_pool(pool: Pool<Postgres>) -> Database {
|
||||
Database { conn_pool: pool }
|
||||
}
|
||||
|
||||
@@ -49,7 +49,7 @@ impl Database {
|
||||
pub async fn init_db(&self) {
|
||||
info!("Checking if required tables exist");
|
||||
match migrate!().run(&self.conn_pool).await {
|
||||
Ok(_) => {}
|
||||
Ok(()) => {}
|
||||
Err(e) => {
|
||||
error!("Error when running migrations {}", e);
|
||||
std::process::exit(1);
|
||||
@@ -142,7 +142,7 @@ impl Database {
|
||||
|
||||
pub async fn add_value(
|
||||
&self,
|
||||
msg: &web::Json<ValueMessageFromDevice>,
|
||||
msg: &ValueMessageFromDevice,
|
||||
device_id: &MacAddress,
|
||||
) -> Result<(), DatabaseError> {
|
||||
info!("Adding value to DB");
|
||||
@@ -201,8 +201,8 @@ mod tests {
|
||||
use sqlx::PgPool;
|
||||
|
||||
#[sqlx::test]
|
||||
async fn add_device(pool: PgPool) {
|
||||
let db = Database::init_from_pool(pool).await;
|
||||
async fn add_device_and_display_name(pool: PgPool) {
|
||||
let db = Database::init_from_pool(pool);
|
||||
|
||||
let test_device = Device {
|
||||
display_name: Some("Waterlevel daheim".to_owned()),
|
||||
@@ -211,7 +211,7 @@ mod tests {
|
||||
db.add_device(&MacAddress::from([0x1A, 0x2B, 0x3C, 0x4D, 0x5E, 0x6F]))
|
||||
.await
|
||||
.unwrap();
|
||||
db.add_display_name(
|
||||
db.update_display_name(
|
||||
&MacAddress::from([0x1A, 0x2B, 0x3C, 0x4D, 0x5E, 0x6F]),
|
||||
"Waterlevel daheim",
|
||||
)
|
||||
@@ -221,4 +221,27 @@ mod tests {
|
||||
let devices = db.get_devices().await.unwrap();
|
||||
assert_eq!(test_device, devices[0]);
|
||||
}
|
||||
|
||||
#[sqlx::test]
|
||||
async fn add_value(pool: PgPool) {
|
||||
let db = Database::init_from_pool(pool);
|
||||
let device_id = MacAddress::from([0x1A, 0x2B, 0x3C, 0x4D, 0x5E, 0x6F]);
|
||||
|
||||
db.add_device(&device_id)
|
||||
.await
|
||||
.unwrap();
|
||||
let msg = ValueMessageFromDevice{
|
||||
active_errors: 0,
|
||||
value: 112.0,
|
||||
value_id: 1
|
||||
};
|
||||
db.add_value(&msg, &device_id).await.unwrap();
|
||||
|
||||
let values = db.get_values_for_id(&device_id).await.unwrap();
|
||||
|
||||
assert!((values[0].value - msg.value).abs() < 1e-5);
|
||||
assert_eq!(values[0].value_id, msg.value_id);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -17,7 +17,7 @@ async fn receive_telemetry(
|
||||
};
|
||||
let mac_converted = MacAddress::from(mac_converted);
|
||||
match data.db.create_device_if_not_exists(&mac_converted).await {
|
||||
Ok(_) => {}
|
||||
Ok(()) => {}
|
||||
Err(e) => {
|
||||
error!("Error creating new device: {}", e);
|
||||
return HttpResponse::InternalServerError();
|
||||
@@ -29,7 +29,7 @@ async fn receive_telemetry(
|
||||
.add_telemetry(&telemetry_message, &mac_converted)
|
||||
.await
|
||||
{
|
||||
Ok(_) => HttpResponse::Created(),
|
||||
Ok(()) => HttpResponse::Created(),
|
||||
Err(e) => {
|
||||
error!("adding Telemetry message to DB failed \n{}", e);
|
||||
HttpResponse::InternalServerError()
|
||||
@@ -66,7 +66,7 @@ async fn receive_value(
|
||||
};
|
||||
let mac_converted = MacAddress::from(mac_converted);
|
||||
match data.db.create_device_if_not_exists(&mac_converted).await {
|
||||
Ok(_) => {}
|
||||
Ok(()) => {}
|
||||
Err(e) => {
|
||||
error!("Error creating new device: {}", e);
|
||||
return HttpResponse::InternalServerError();
|
||||
@@ -74,7 +74,7 @@ async fn receive_value(
|
||||
};
|
||||
|
||||
match data.db.add_value(&value_message, &mac_converted).await {
|
||||
Ok(_) => HttpResponse::Created(),
|
||||
Ok(()) => HttpResponse::Created(),
|
||||
Err(e) => {
|
||||
error!("adding Telemetry message to DB failed \n{}", e);
|
||||
HttpResponse::InternalServerError()
|
||||
@@ -122,12 +122,9 @@ async fn set_display_name(data: web::Data<AppState>, device_id: web::Path<String
|
||||
return HttpResponse::InternalServerError().finish();
|
||||
};
|
||||
let mac_converted = MacAddress::from(mac_converted);
|
||||
match db.update_display_name(&mac_converted, &display_name).await {
|
||||
Ok(_) => HttpResponse::Ok().finish(),
|
||||
Err(_) => {
|
||||
error!("Failed to update/set displayName for device");
|
||||
HttpResponse::InternalServerError().finish()
|
||||
}
|
||||
if let Ok(()) = db.update_display_name(&mac_converted, &display_name).await { HttpResponse::Ok().finish() } else {
|
||||
error!("Failed to update/set displayName for device");
|
||||
HttpResponse::InternalServerError().finish()
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -13,7 +13,7 @@ async fn upload_firmware(
|
||||
body: web::Bytes,
|
||||
) -> impl Responder {
|
||||
let (device, config, version) = path.into_inner();
|
||||
let version = version.replace(".", "-");
|
||||
let version = version.replace('.', "-");
|
||||
|
||||
let firmware_root_path = &data.firmwares_path;
|
||||
|
||||
@@ -34,8 +34,7 @@ async fn upload_firmware(
|
||||
debug!("{x:?}");
|
||||
|
||||
HttpResponse::Ok().body(format!(
|
||||
"Firmware version {} uploaded successfully",
|
||||
version
|
||||
"Firmware version {version} uploaded successfully"
|
||||
))
|
||||
}
|
||||
|
||||
@@ -63,7 +62,7 @@ async fn serve_firmware(
|
||||
data: web::Data<AppState>,
|
||||
) -> impl Responder {
|
||||
let (product, config, version) = path.into_inner();
|
||||
let version = version.replace(".", "-").replace("_", "-");
|
||||
let version = version.replace(['.', '_'], "-");
|
||||
let fw_root_path = &data.firmwares_path;
|
||||
let file_path = PathBuf::from(format!("{product}/firmware_{config}_{version}.bin"));
|
||||
let file_path = fw_root_path.join(&file_path);
|
||||
|
||||
@@ -24,14 +24,14 @@ pub struct TelemetryMessageFromDevice {
|
||||
pub software_version: i32,
|
||||
}
|
||||
|
||||
#[derive(Deserialize, Debug, Serialize)]
|
||||
#[derive(Deserialize, Debug, Serialize, PartialEq)]
|
||||
pub struct ValueMessageFromDevice {
|
||||
pub value: f64,
|
||||
pub value_id: i32,
|
||||
pub active_errors: i32,
|
||||
}
|
||||
|
||||
#[derive(Deserialize, Debug, Serialize)]
|
||||
#[derive(Deserialize, Debug, Serialize, PartialEq)]
|
||||
pub struct ValueMessage {
|
||||
pub value: f64,
|
||||
pub value_id: i32,
|
||||
|
||||
@@ -63,15 +63,15 @@ pub fn get_files(
|
||||
.ok_or(GetFilesError::Filename)?
|
||||
.to_str()
|
||||
.ok_or(GetFilesError::Filename)?
|
||||
.split("_")
|
||||
.split('_')
|
||||
.collect();
|
||||
let version = split_name[2]
|
||||
.strip_suffix(".bin")
|
||||
.ok_or(GetFilesError::Extension)?
|
||||
.replace("-", ".");
|
||||
.replace('-', ".");
|
||||
let board_config = BoardConfig::from_str(split_name[1])?;
|
||||
let board_type = BoardType::from_str(&product_name).unwrap();
|
||||
let version_replaced = version.replace(".", "_");
|
||||
let version_replaced = version.replace('.', "_");
|
||||
let fw_url =
|
||||
format!("{hostname}/firmware/{board_type}/{board_config}/{version_replaced}.bin");
|
||||
let cfg = OTAConfiguration {
|
||||
@@ -82,7 +82,7 @@ pub fn get_files(
|
||||
};
|
||||
configs.push(cfg);
|
||||
} else if path.is_dir() {
|
||||
println!("Directory: {:?}", path);
|
||||
println!("Directory: {path:?}");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user