Compare commits

...

36 Commits
v0.2.2 ... main

Author SHA1 Message Date
Paul van Tilburg 03c51e2a2c
Bump the version to 0.3.5
Check and lint using Cargo / Check and lint (push) Successful in 2m10s Details
Release / Release (push) Successful in 1m14s Details
Release / Release Rust crate (push) Successful in 2m53s Details
Release / Release Docker image (push) Successful in 8m41s Details
2024-02-27 15:37:56 +01:00
Paul van Tilburg cc1a0e4748
Update the changelog 2024-02-27 15:37:35 +01:00
Paul van Tilburg d2b90c16f6
Fix clippy issue 2024-02-27 15:37:05 +01:00
Paul van Tilburg d5eed08072
Bump the version to 0.3.4
Check and lint using Cargo / Check and lint (push) Has been cancelled Details
Release / Release (push) Has been cancelled Details
Release / Release Rust crate (push) Has been cancelled Details
Release / Release Docker image (push) Has been cancelled Details
2024-02-27 15:28:09 +01:00
Paul van Tilburg 247e9d51f5
Update the changelog 2024-02-27 15:27:21 +01:00
Paul van Tilburg 5241d90e79
Cargo update; fixes several security advisories
Fixes RUSTSEC-2024-0003 and RUSTSEC-2023-0072
2024-02-27 15:25:21 +01:00
Paul van Tilburg c61bbfef5b
Bump the version to 0.3.3
Check and lint using Cargo / Check and lint (push) Successful in 2m35s Details
Release / Release (push) Successful in 1m14s Details
Release / Release Rust crate (push) Successful in 3m28s Details
Release / Release Docker image (push) Successful in 11m19s Details
2023-11-03 21:25:03 +01:00
Paul van Tilburg f3ff02e4ff
Update the changelog 2023-11-03 21:24:22 +01:00
Paul van Tilburg f2be089fb9
Add missing dates 2023-11-03 21:16:26 +01:00
Paul van Tilburg 45b3f52e71
Cargo update; fixes RUSTSEC-2020-0071
Fix the usage of a deprecated method.
2023-11-03 21:12:04 +01:00
Paul van Tilburg ff12875a08
Bump the version to 0.3.2
Check and lint using Cargo / Check and lint (push) Successful in 2m41s Details
Release / Release (push) Successful in 1m20s Details
Release / Release Rust crate (push) Successful in 3m46s Details
Release / Release Docker image (push) Successful in 8m18s Details
2023-08-27 13:30:11 +02:00
Paul van Tilburg 1bf6a4e772
Update the changelog 2023-08-27 13:29:48 +02:00
Paul van Tilburg c6f7511fc7
Switch to Debian bookworm Docker image for runtime
The Rust Docker build image is also based on Bookworm and would lead to
a binary that is linked against OpenSSL 3 which would then not be
available in the bullseye runtime Docker image.
2023-08-27 13:28:28 +02:00
Paul van Tilburg 3fed86d36f
Bump the version to 0.3.1
Check and lint using Cargo / Check and lint (push) Successful in 3m15s Details
Release / Release (push) Successful in 1m26s Details
Release / Release Rust crate (push) Successful in 4m15s Details
Release / Release Docker image (push) Successful in 11m37s Details
2023-08-26 11:50:26 +02:00
Paul van Tilburg d3cc19524b
Update the changelog 2023-08-26 11:48:55 +02:00
Paul van Tilburg 92c75d09b9
Fix and improve the release workflow
Ad the relevant part of the changelog as release notes to the release
and fix some schema-related issues.
2023-08-26 11:47:31 +02:00
Paul van Tilburg e1319dcfc2
Cargo update 2023-08-26 11:44:56 +02:00
Paul van Tilburg 0f1bc9d83d
Fix typo in comment
Check and lint using Cargo / Check and lint (push) Successful in 5m4s Details
2023-07-17 21:50:13 +02:00
Paul van Tilburg 0068f6e9de
Cargo update
Check and lint using Cargo / Check and lint (push) Successful in 3m9s Details
2023-06-08 11:10:06 +02:00
Paul van Tilburg caad71389b
Also here no longer set sparse Cargo index for crates.io
Check and lint using Cargo / Check and lint (push) Failing after 26s Details
2023-06-08 11:01:13 +02:00
Paul van Tilburg 0b76db96f0
Use the personal Cargo token
Check and lint using Cargo / Check and lint (push) Successful in 2m57s Details
2023-06-08 10:58:33 +02:00
Paul van Tilburg 42a43cc83d
No longer configure using a sparse Cargo index for crates.io
Check and lint using Cargo / Check and lint (push) Successful in 2m53s Details
This is the default since Rust 1.70.
2023-06-06 07:47:23 +02:00
Paul van Tilburg 1aca61d3fd
Add a full release workflow
Check and lint using Cargo / Check and lint (push) Successful in 2m45s Details
2023-05-22 20:02:03 +02:00
Paul van Tilburg 35dda781a3
Tweak workflow step name 2023-05-22 19:56:52 +02:00
Paul van Tilburg 14bda61a9e
Fix name of Gitea Actions workflow
Check and lint using Cargo / Check and lint (push) Successful in 3m2s Details
2023-04-25 16:30:05 +02:00
Paul van Tilburg bc22fd2d70
Run cargo clippy right after check; install missing components
Check, test and lint using Cargo / Check and lint (push) Successful in 2m57s Details
2023-04-25 16:28:02 +02:00
Paul van Tilburg fd00ef0b4f
Simplify Gitea Actions check and lint workflow
Check, test and lint using Cargo / Check and lint (push) Failing after 2m50s Details
2023-04-25 16:23:32 +02:00
Paul van Tilburg c070877384
Bump the version to 0.3.0
Check, Test and Lint Using Cargo / Lints (push) Successful in 3m8s Details
Check, Test and Lint Using Cargo / Check (push) Successful in 2m39s Details
2023-04-15 12:16:30 +02:00
Paul van Tilburg 732d4b83f2
Update the changelog 2023-04-15 12:15:40 +02:00
Paul van Tilburg 12a797baa9
Cargo update
Check, Test and Lint Using Cargo / Check (push) Successful in 2m53s Details
Check, Test and Lint Using Cargo / Lints (push) Successful in 3m3s Details
2023-04-14 23:26:07 +02:00
Paul van Tilburg 5586ae4d70
Update build dependecy on the vergen crate to 8.1.1
This change allows for dropping the dependency on the `anyhow` crate.
2023-04-14 23:25:25 +02:00
Paul van Tilburg 59e3b53263
Implement backoff for login/update API calls (closes: #8)
Check, Test and Lint Using Cargo / Check (push) Successful in 3m45s Details
Check, Test and Lint Using Cargo / Lints (push) Successful in 3m35s Details
Start from an interval of 10 seconds, increase with a factor of 2.0 on
each failure up to a maximum of 320 seconds.

This commit also fixes an issue where the update loop would be aborted
if a relogin fails.
2023-04-14 23:02:21 +02:00
Paul van Tilburg f236499125
Fix login errors not being detected 2023-04-14 22:54:54 +02:00
Paul van Tilburg 02a4d1ca9b
Update to Rocket 0.5.0-rc.3
Check Details
Lints Details
2023-03-24 14:38:42 +01:00
Paul van Tilburg 3fff79a2cd
Fix missing build script/git repo during build
Check Details
Lints Details
When building the dependencies, the build script should not be
considered. When building the actual binary, the git repository needs to
be present and the build script should be run.
2023-03-22 15:27:12 +01:00
Paul van Tilburg 9200a10cef
Speed up build by using sparse Cargo index for crates.io 2023-03-22 15:26:45 +01:00
13 changed files with 931 additions and 958 deletions

View File

@ -5,9 +5,6 @@ target
Dockerfile*
docker-compose*
# Git folder
.git
# Dot files
.gitignore

View File

@ -1,83 +0,0 @@
name: "Check, Test and Lint Using Cargo"
on:
- push
- pull_request
- workflow_dispatch
jobs:
check:
name: Check
runs-on: debian-latest
steps:
- name: Checkout sources
uses: actions/checkout@v3
- name: Install stable toolchain
uses: https://github.com/actions-rs/toolchain@v1
with:
profile: minimal
toolchain: stable
override: true
- name: Use sparse Cargo index for crates.io
run: echo -e '[registries.crates-io]\nprotocol = "sparse"' >> /root/.cargo/config.toml
- name: Run cargo check
uses: https://github.com/actions-rs/cargo@v1
with:
command: check
# TODO: Add a test suite first!
# test:
# name: Test Suite
# runs-on: debian-latest
# steps:
# - name: Checkout sources
# uses: actions/checkout@v3
#
# - name: Install stable toolchain
# uses: https://github.com/actions-rs/toolchain@v1
# with:
# profile: minimal
# toolchain: stable
# override: true
#
# - name: Use sparse Cargo index for crates.io
# run: echo -e '[registries.crates-io]\nprotocol = "sparse"' >> /root/.cargo/config.toml
#
# - name: Run cargo test
# uses: https://github.com/actions-rs/cargo@v1
# with:
# command: test
# args: --all-features
lints:
name: Lints
runs-on: debian-latest
steps:
- name: Checkout sources
uses: actions/checkout@v3
- name: Install stable toolchain
uses: https://github.com/actions-rs/toolchain@v1
with:
profile: minimal
toolchain: stable
override: true
components: rustfmt, clippy
- name: Use sparse Cargo index for crates.io
run: echo -e '[registries.crates-io]\nprotocol = "sparse"' >> /root/.cargo/config.toml
- name: Run cargo fmt
uses: https://github.com/actions-rs/cargo@v1
with:
command: fmt
args: --all -- --check
- name: Run cargo clippy
uses: https://github.com/actions-rs/cargo@v1
with:
command: clippy
args: -- -D warnings

View File

@ -0,0 +1,46 @@
name: "Check and lint using Cargo"
on:
- pull_request
- push
- workflow_dispatch
jobs:
check_lint:
name: Check and lint
runs-on: debian-latest
steps:
- name: Checkout sources
uses: actions/checkout@v3
- name: Install Rust stable toolchain
uses: https://github.com/actions-rs/toolchain@v1
with:
profile: minimal
toolchain: stable
override: true
components: rustfmt, clippy
- name: Run cargo check
uses: https://github.com/actions-rs/cargo@v1
with:
command: check
- name: Run cargo clippy
uses: https://github.com/actions-rs/cargo@v1
with:
command: clippy
args: -- -D warnings
- name: Run cargo fmt
uses: https://github.com/actions-rs/cargo@v1
with:
command: fmt
args: --all -- --check
# TODO: Add a test suite first!
# - name: Run cargo test
# uses: https://github.com/actions-rs/cargo@v1
# with:
# command: test
# args: --all-features

View File

@ -0,0 +1,122 @@
name: "Release"
on:
push:
tags:
- "v*"
jobs:
release:
name: "Release"
runs-on: debian-latest
steps:
- name: Checkout sources
uses: actions/checkout@v3
with:
fetch-depth: 0
- name: Determine the version of the release
run: |
VERSION=${GITHUB_REF_NAME#v}
echo "Releasing version: $VERSION"
echo "VERSION=$VERSION" >> $GITHUB_ENV
- name: Get the release notes from the changelog
run: |
EOF=$(dd if=/dev/urandom bs=15 count=1 status=none | base64)
RELEASE_NOTES=$(sed -n -e "/^## \[$VERSION\]/,/^## \[/{//"'!'"p;}" CHANGELOG.md | sed -e '1d;$d')
echo "Release notes:"
echo
echo "$RELEASE_NOTES"
echo "RELEASE_NOTES<<$EOF" >> "$GITHUB_ENV"
echo "$RELEASE_NOTES" >> "$GITHUB_ENV"
echo "$EOF" >> "$GITHUB_ENV"
- name: Install Go
uses: actions/setup-go@v4
with:
go-version: '>=1.20.1'
- name: Release to Gitea
uses: actions/release-action@main
with:
# This is available by default.
api_key: '${{ secrets.RELEASE_TOKEN }}'
files: FIXME
title: 'Release ${{ env.VERSION }}'
body: '${{ env.RELEASE_NOTES }}'
release-crate:
name: "Release Rust crate"
runs-on: debian-latest
steps:
- name: Checkout sources
uses: actions/checkout@v3
with:
fetch-depth: 0
- name: Install Rust stable toolchain
uses: https://github.com/actions-rs/toolchain@v1
with:
profile: minimal
toolchain: stable
override: true
- name: Use sparse Cargo index for crates.io
run: echo -e '[registries.crates-io]\nprotocol = "sparse"' >> /root/.cargo/config.toml
- name: Register the Gitea crate registry with Cargo
run: echo -e '[registries.luon]\nindex = "https://git.luon.net/paul/_cargo-index.git"' >> /root/.cargo/config.toml
- name: Run cargo publish
uses: https://github.com/actions-rs/cargo@v1
env:
# This needs to be provided for the repository; no login necessary as a result.
CARGO_REGISTRIES_LUON_TOKEN: '${{ secrets.CARGO_TOKEN }}'
with:
command: publish
args: --registry luon
release-docker-image:
name: "Release Docker image"
runs-on: debian-latest
container:
image: ghcr.io/catthehacker/ubuntu:act-latest
steps:
- name: Checkout sources
uses: actions/checkout@v3
with:
fetch-depth: 0
- name: Docker metadata
id: meta
uses: https://github.com/docker/metadata-action@v4
with:
images: |
git.luon.net/paul/solar-grabber
tags: |
type=raw,value=latest,enable={{is_default_branch}}
type=semver,pattern={{version}}
type=semver,pattern={{major}}.{{minor}}
type=semver,pattern={{major}}
- name: Set up Docker Buildx
uses: https://github.com/docker/setup-buildx-action@v2
- name: Login to the Gitea Docker registry
uses: https://github.com/docker/login-action@v2
with:
registry: git.luon.net
username: ${{ github.repository_owner }}
# This needs to be provided by the repository owner and have the packages scopes enabled.
# Note that the default `GITEA_TOKEN` secret does not have this scope enabled.
password: ${{ secrets.DOCKER_REGISTRY_TOKEN }}
- name: Docker build and push
uses: https://github.com/docker/build-push-action@v4
env:
ACTIONS_RUNTIME_TOKEN: '' # See https://gitea.com/gitea/act_runner/issues/119
with:
context: .
push: true
tags: ${{ steps.meta.outputs.tags }}

View File

@ -7,6 +7,62 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
## [Unreleased]
## [0.3.5] - 2024-02-27
### Fixed
* Fix clippy issue
## [0.3.4] - 2024-02-27
### Security
* Updated dependencies, fixes security advisories:
* [RUSTSEC-2024-0003](https://rustsec.org/advisories/RUSTSEC-2024-0003)
* [RUSTSEC-2023-0072](https://rustsec.org/advisories/RUSTSEC-2024-0072)
## [0.3.3] - 2023-11-03
### Security
* Update dependencies ([RUSTSEC-2020-0071](https://rustsec.org/advisories/RUSTSEC-2020-0071.html))
### Changed
* Switch to Rocket 0.5 RC4
## [0.3.2] - 2023-08-27
### Fixed
* Switch to Debian bookworm Docker image for runtime; fixes Docker image
## [0.3.1] - 2023-08-26
### Changed
* Fix and improve Gitea Actions workflow
### Security
* Update dependencies ([RUSTSEC-2023-0044](https://rustsec.org/advisories/RUSTSEC-2023-0044))
## [0.3.0] - 2023-04-15
### Added
* Implement backoff for login/update API call failures (#8)
### Changed
* Update dependencies
* Speed up Docker image builds by using sparse Cargo index for crates.io
### Fixed
* Fix login errors not being detected for My Autarco
* Fix missing build script/git repository during Docker image build
## [0.2.2] - 2023-03-22
### Added
@ -65,7 +121,13 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
Rename Autarco Scraper project to Solar Grabber.
[Unreleased]: https://git.luon.net/paul/solar-grabber/compare/v0.2.2...HEAD
[Unreleased]: https://git.luon.net/paul/solar-grabber/compare/v0.3.5...HEAD
[0.3.5]: https://git.luon.net/paul/solar-grabber/compare/v0.3.4...v0.3.5
[0.3.4]: https://git.luon.net/paul/solar-grabber/compare/v0.3.3...v0.3.4
[0.3.3]: https://git.luon.net/paul/solar-grabber/compare/v0.3.2...v0.3.3
[0.3.2]: https://git.luon.net/paul/solar-grabber/compare/v0.3.1...v0.3.2
[0.3.1]: https://git.luon.net/paul/solar-grabber/compare/v0.3.0...v0.3.1
[0.3.0]: https://git.luon.net/paul/solar-grabber/compare/v0.2.2...v0.3.0
[0.2.2]: https://git.luon.net/paul/solar-grabber/compare/v0.2.1...v0.2.2
[0.2.1]: https://git.luon.net/paul/solar-grabber/compare/v0.2.0...v0.2.1
[0.2.0]: https://git.luon.net/paul/solar-grabber/compare/v0.1.1...v0.2.0

1490
Cargo.lock generated

File diff suppressed because it is too large Load Diff

View File

@ -1,6 +1,6 @@
[package]
name = "solar-grabber"
version = "0.2.2"
version = "0.3.5"
authors = ["Paul van Tilburg <paul@luon.net>"]
edition = "2021"
description = """"
@ -19,13 +19,12 @@ enum_dispatch = "0.3.9"
md-5 = "0.10.5"
once_cell = "1.9.0"
reqwest = { version = "0.11.6", features = ["cookies", "json"] }
rocket = { version = "0.5.0-rc.2", features = ["json"] }
rocket = { version = "0.5.0-rc.3", features = ["json"] }
thiserror = "1.0.38"
url = "2.2.2"
[build-dependencies]
anyhow = "1.0.68"
vergen = { version = "7.5.0", default_features = false, features = ["build", "git"] }
vergen = { version = "8.1.1", features = ["build", "git", "gitcl"] }
[package.metadata.deb]
maintainer = "Paul van Tilburg <paul@luon.net>"

View File

@ -10,10 +10,12 @@ FROM docker.io/rust:1 as builder
RUN USER=root cargo new --bin /usr/src/solar-grabber
WORKDIR /usr/src/solar-grabber
COPY ./Cargo.* ./
RUN sed -i -e 's/^build =/#build =/' Cargo.toml
RUN cargo build --release
RUN rm src/*.rs
# Add the real project files from current folder
COPY ./Cargo.toml ./
ADD . ./
# Build the actual binary from the copied local files
@ -22,7 +24,7 @@ RUN cargo build --release
########################## RUNTIME IMAGE ##########################
# Create new stage with a minimal image for the actual runtime image/container
FROM docker.io/debian:bullseye-slim
FROM docker.io/debian:bookworm-slim
# Install CA certificates
RUN apt-get update && \

View File

@ -1,7 +1,9 @@
use anyhow::Result;
use vergen::{vergen, Config};
use std::error::Error;
use vergen::EmitBuilder;
fn main() -> Result<()> {
fn main() -> Result<(), Box<dyn Error>> {
// Generate the `cargo:` instructions to fill the appropriate environment variables.
vergen(Config::default())
EmitBuilder::builder().all_build().all_git().emit()?;
Ok(())
}

View File

@ -97,7 +97,7 @@ impl VersionInfo {
/// Retrieves the version information from the environment variables.
fn new() -> Self {
Self {
version: String::from(env!("VERGEN_BUILD_SEMVER")),
version: String::from(env!("CARGO_PKG_VERSION")),
timestamp: String::from(env!("VERGEN_BUILD_TIMESTAMP")),
git_sha: String::from(&env!("VERGEN_GIT_SHA")[0..7]),
git_timestamp: String::from(env!("VERGEN_GIT_COMMIT_TIMESTAMP")),
@ -135,14 +135,14 @@ pub fn setup() -> Rocket<Build> {
.expect("Invalid configuration");
let service = services::get(config.service).expect("Invalid service");
// We don't care about the join handle nor error results?t
// We don't care about the join handle nor error results?
let _service = rocket::tokio::spawn(update_loop(service));
})
}))
.attach(AdHoc::on_liftoff("Version", |_| {
Box::pin(async move {
let name = env!("CARGO_PKG_NAME");
let version = env!("VERGEN_BUILD_SEMVER");
let version = env!("CARGO_PKG_VERSION");
let git_sha = &env!("VERGEN_GIT_SHA")[0..7];
println!("☀️ Started {name} v{version} (git @{git_sha})");

View File

@ -6,7 +6,7 @@
use std::sync::Arc;
use chrono::{DateTime, Local, TimeZone};
use chrono::{DateTime, Local, NaiveDateTime, TimeZone};
use md5::{Digest, Md5};
use reqwest::{cookie::Jar as CookieJar, Client, ClientBuilder, Url};
use rocket::{
@ -112,7 +112,7 @@ where
use rocket::serde::de::Error;
match <StringOrObject<'_, T>>::deserialize(deserializer) {
Ok(StringOrObject::String(s)) if s.is_empty() => Ok(None),
Ok(StringOrObject::String("")) => Ok(None),
Ok(StringOrObject::String(_)) => Err(Error::custom("Non-empty string not allowed here")),
Ok(StringOrObject::Object(t)) => Ok(Some(t)),
Ok(StringOrObject::Value(j)) => Err(Error::custom(&format!(
@ -133,9 +133,12 @@ where
use rocket::serde::de::Error;
let s = <&str>::deserialize(deserializer)?;
let dt = NaiveDateTime::parse_from_str(s, DATE_TIME_FORMAT).map_err(D::Error::custom)?;
Local
.datetime_from_str(s, DATE_TIME_FORMAT)
.map_err(D::Error::custom)
.from_local_datetime(&dt)
.latest()
.ok_or_else(|| D::Error::custom("time representation is invalid for server time zone"))
}
/// Deserializes a string ([`&str`]) into a float ([`f32`]).

View File

@ -92,14 +92,17 @@ impl super::Service for Service {
/// It mainly stores the acquired cookie in the client's cookie jar. The login credentials come
/// from the loaded configuration (see [`Config`]).
async fn login(&mut self) -> Result<()> {
let login_url = login_url().expect("valid login URL");
let params = [
("username", &self.config.username),
("password", &self.config.password),
];
let login_url = login_url().expect("valid login URL");
self.client.post(login_url).form(&params).send().await?;
Ok(())
let response = self.client.post(login_url).form(&params).send().await?;
match response.error_for_status() {
Ok(_) => Ok(()),
Err(e) if e.status() == Some(StatusCode::UNAUTHORIZED) => Err(Error::NotAuthorized),
Err(e) => Err(e.into()),
}
}
/// Retrieves a status update from the API of the My Autarco site.

View File

@ -9,6 +9,22 @@ use crate::{
STATUS,
};
/// The default sleep interval to use between checks.
const DEFAULT_SLEEP_INTERVAL: u64 = 10;
/// The sleep interval upper limit when applying exponential backoff.
const MAX_SLEEP_INTERVAL: u64 = 320;
/// The backoff factor.
const BACKOFF_FACTOR: f64 = 2.0;
/// Calculates the new interval by applying the backoff factor and taking the maximum into account.
fn back_off(interval: u64) -> u64 {
let new_interval = (interval as f64 * BACKOFF_FACTOR) as u64;
new_interval.min(MAX_SLEEP_INTERVAL)
}
/// Main update loop that logs in and periodically acquires updates from the API.
///
/// It updates the mutex-guarded current update [`Status`](crate::Status) struct which can be
@ -23,9 +39,10 @@ pub(super) async fn update_loop(service: Services) -> color_eyre::Result<()> {
let mut last_updated = 0;
let poll_interval = service.poll_interval();
let mut sleep_interval = DEFAULT_SLEEP_INTERVAL;
loop {
// Wake up every 10 seconds and check if an update is due.
sleep(Duration::from_secs(10)).await;
sleep(Duration::from_secs(sleep_interval)).await;
let timestamp = SystemTime::now()
.duration_since(SystemTime::UNIX_EPOCH)
@ -39,15 +56,24 @@ pub(super) async fn update_loop(service: Services) -> color_eyre::Result<()> {
Ok(status) => status,
Err(Error::NotAuthorized) => {
eprintln!("💥 Update unauthorized, trying to log in again...");
service.login().await?;
if let Err(e) = service.login().await {
eprintln!("💥 Login failed: {e}; will retry in {sleep_interval} seconds...");
sleep_interval = back_off(sleep_interval);
continue;
};
println!("⚡ Logged in successfully!");
sleep_interval = DEFAULT_SLEEP_INTERVAL;
continue;
}
Err(e) => {
eprintln!("💥 Failed to update status: {}", e);
eprintln!(
"💥 Failed to update status: {e}; will retry in {sleep_interval} seconds..."
);
sleep_interval = back_off(sleep_interval);
continue;
}
};
sleep_interval = DEFAULT_SLEEP_INTERVAL;
last_updated = timestamp;
println!("⚡ Updated status to: {:#?}", status);