Compare commits

..

1 commit
main ... wip

Author SHA1 Message Date
Arne Dußin
7056149ff1 WIP: Redoing light modes 2024-12-07 13:32:31 +01:00
10 changed files with 314 additions and 3678 deletions

186
Cargo.lock generated
View file

@ -2,6 +2,21 @@
# It is not intended for manual editing. # It is not intended for manual editing.
version = 3 version = 3
[[package]]
name = "android-tzdata"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e999941b234f3131b00bc13c22d06e8c5ff726d1b6318ac7eb276997bbb4fef0"
[[package]]
name = "android_system_properties"
version = "0.1.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "819e7219dbd41043ac279b19830f2efc897156490d7fd6ea916720117ee66311"
dependencies = [
"libc",
]
[[package]] [[package]]
name = "anstream" name = "anstream"
version = "0.6.15" version = "0.6.15"
@ -51,6 +66,12 @@ dependencies = [
"windows-sys", "windows-sys",
] ]
[[package]]
name = "autocfg"
version = "1.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26"
[[package]] [[package]]
name = "bincode" name = "bincode"
version = "1.3.3" version = "1.3.3"
@ -60,6 +81,41 @@ dependencies = [
"serde", "serde",
] ]
[[package]]
name = "bumpalo"
version = "3.16.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "79296716171880943b8470b5f8d03aa55eb2e645a4874bdbb28adb49162e012c"
[[package]]
name = "cc"
version = "1.1.31"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c2e7962b54006dcfcc61cb72735f4d89bb97061dd6a7ed882ec6b8ee53714c6f"
dependencies = [
"shlex",
]
[[package]]
name = "cfg-if"
version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
[[package]]
name = "chrono"
version = "0.4.38"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a21f936df1771bf62b77f047b726c4625ff2e8aa607c01ec06e5a05bd8463401"
dependencies = [
"android-tzdata",
"iana-time-zone",
"js-sys",
"num-traits",
"wasm-bindgen",
"windows-targets",
]
[[package]] [[package]]
name = "clap" name = "clap"
version = "4.5.16" version = "4.5.16"
@ -106,24 +162,83 @@ version = "1.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d3fd119d74b830634cea2a0f58bbd0d54540518a14397557951e79340abc28c0" checksum = "d3fd119d74b830634cea2a0f58bbd0d54540518a14397557951e79340abc28c0"
[[package]]
name = "core-foundation-sys"
version = "0.8.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b"
[[package]] [[package]]
name = "heck" name = "heck"
version = "0.5.0" version = "0.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea"
[[package]]
name = "iana-time-zone"
version = "0.1.61"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "235e081f3925a06703c2d0117ea8b91f042756fd6e7a6e5d901e8ca1a996b220"
dependencies = [
"android_system_properties",
"core-foundation-sys",
"iana-time-zone-haiku",
"js-sys",
"wasm-bindgen",
"windows-core",
]
[[package]]
name = "iana-time-zone-haiku"
version = "0.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f31827a206f56af32e590ba56d5d2d085f558508192593743f16b2306495269f"
dependencies = [
"cc",
]
[[package]] [[package]]
name = "is_terminal_polyfill" name = "is_terminal_polyfill"
version = "1.70.1" version = "1.70.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7943c866cc5cd64cbc25b2e01621d07fa8eb2a1a23160ee81ce38704e97b8ecf" checksum = "7943c866cc5cd64cbc25b2e01621d07fa8eb2a1a23160ee81ce38704e97b8ecf"
[[package]]
name = "js-sys"
version = "0.3.72"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6a88f1bda2bd75b0452a14784937d796722fdebfe50df998aeb3f0b7603019a9"
dependencies = [
"wasm-bindgen",
]
[[package]] [[package]]
name = "libc" name = "libc"
version = "0.2.158" version = "0.2.158"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d8adc4bb1803a324070e64a98ae98f38934d91957a99cfb3a43dcbc01bc56439" checksum = "d8adc4bb1803a324070e64a98ae98f38934d91957a99cfb3a43dcbc01bc56439"
[[package]]
name = "log"
version = "0.4.22"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a7a70ba024b9dc04c27ea2f0c0548feb474ec5c54bba33a7f72f873a39d07b24"
[[package]]
name = "num-traits"
version = "0.2.19"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841"
dependencies = [
"autocfg",
]
[[package]]
name = "once_cell"
version = "1.20.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1261fe7e33c73b354eab43b1273a57c8f967d0391e80353e51f764ac02cf6775"
[[package]] [[package]]
name = "proc-macro2" name = "proc-macro2"
version = "1.0.86" version = "1.0.86"
@ -171,6 +286,12 @@ dependencies = [
"syn", "syn",
] ]
[[package]]
name = "shlex"
version = "1.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64"
[[package]] [[package]]
name = "strsim" name = "strsim"
version = "0.11.1" version = "0.11.1"
@ -200,6 +321,70 @@ version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821"
[[package]]
name = "wasm-bindgen"
version = "0.2.95"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "128d1e363af62632b8eb57219c8fd7877144af57558fb2ef0368d0087bddeb2e"
dependencies = [
"cfg-if",
"once_cell",
"wasm-bindgen-macro",
]
[[package]]
name = "wasm-bindgen-backend"
version = "0.2.95"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cb6dd4d3ca0ddffd1dd1c9c04f94b868c37ff5fac97c30b97cff2d74fce3a358"
dependencies = [
"bumpalo",
"log",
"once_cell",
"proc-macro2",
"quote",
"syn",
"wasm-bindgen-shared",
]
[[package]]
name = "wasm-bindgen-macro"
version = "0.2.95"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e79384be7f8f5a9dd5d7167216f022090cf1f9ec128e6e6a482a2cb5c5422c56"
dependencies = [
"quote",
"wasm-bindgen-macro-support",
]
[[package]]
name = "wasm-bindgen-macro-support"
version = "0.2.95"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "26c6ab57572f7a24a4985830b120de1594465e5d500f24afe89e16b4e833ef68"
dependencies = [
"proc-macro2",
"quote",
"syn",
"wasm-bindgen-backend",
"wasm-bindgen-shared",
]
[[package]]
name = "wasm-bindgen-shared"
version = "0.2.95"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "65fc09f10666a9f147042251e0dda9c18f166ff7de300607007e96bdebc1068d"
[[package]]
name = "windows-core"
version = "0.52.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "33ab640c8d7e35bf8ba19b884ba838ceb4fba93a4e8c65a9059d08afcfc683d9"
dependencies = [
"windows-targets",
]
[[package]] [[package]]
name = "windows-sys" name = "windows-sys"
version = "0.52.0" version = "0.52.0"
@ -278,6 +463,7 @@ name = "zwote_sonne"
version = "0.1.0" version = "0.1.0"
dependencies = [ dependencies = [
"bincode", "bincode",
"chrono",
"clap", "clap",
"clap_derive", "clap_derive",
"rppal", "rppal",

View file

@ -14,6 +14,7 @@ path = "src/client.rs"
[dependencies] [dependencies]
bincode = "1.3.3" bincode = "1.3.3"
chrono = "0.4.38"
clap = { version = "4.5.16", features = ["derive"] } clap = { version = "4.5.16", features = ["derive"] }
clap_derive = "4.5.13" clap_derive = "4.5.13"
rppal = "0.19.0" rppal = "0.19.0"

36
curve_description.adoc Normal file
View file

@ -0,0 +1,36 @@
= Description of curves for light purposes
Since the daily cycle is the main factor for plants whatever the periodicity of
the curve it will be restarted at midnight local time.
== Curve definition
To keep it simple, we will only consider linear change.
Because of this the light value can be described in required brightness at
a given time. The value that the light had before that will then be adjusted
smoothly, until it reaches the value intended at the next time point.
The brightness at midnight must always be declared.
For example: We want the light to be on off during the night, then turn on at
6:00 in the morning with 20% and gradually increase in brightness until it
reaches 100% at 8:00. Then, at 21:00 we want the light to start dimming until
it turns off at 23:00. The following graph shows this:
.Graph not yet available
[%collapsible]
====
====
The points should then be defined as follows:
[source]
----
0000 0.0
0600 0.0
0600 0.2
0800 1.0
2100 1.0
2300 0.0
----
You will notice that two entries are at the same time here. This will make sure
that the light stays at the same level during the duration from 0000 to 0600.
When multiple entries are at the same time, the furthest down will be chosen.

File diff suppressed because it is too large Load diff

View file

@ -4,6 +4,7 @@ use clap::Parser;
use clap_derive::Subcommand; use clap_derive::Subcommand;
use packet::Packet; use packet::Packet;
pub mod military_time;
mod packet; mod packet;
#[derive(Parser, Debug)] #[derive(Parser, Debug)]
@ -17,47 +18,14 @@ struct Args
} }
#[derive(Subcommand, Debug)] #[derive(Subcommand, Debug)]
enum Command enum Command {}
{
/// Set a constant brightness in Range 0.0..=1.0
Constant
{
brightness: f64
},
/// Sinusoidal curve with a period of 0.0.. seconds
Sine
{
period: f64
},
/// Triangle curve with a period of 0.0.. seconds
Triangle
{
period: f64
},
/// Sawtooth curve with a period of 0.0.. seconds
Sawtooth
{
period: f64
},
/// Square curve witha period of 0.0.. seconds and a duty cycle of 0.0..1.0
Square
{
period: f64, duty: f64
},
}
fn main() fn main()
{ {
let args = Args::parse(); let args = Args::parse();
let mut stream = TcpStream::connect(args.connect).expect("Unable to connect to server"); let mut stream = TcpStream::connect(args.connect).expect("Unable to connect to server");
let packet = match args.command { let packet = match args.command {};
Command::Constant { brightness } => Packet::Constant(brightness),
Command::Sine { period } => Packet::Sine(period),
Command::Triangle { period } => Packet::Triangle(period),
Command::Sawtooth { period } => Packet::Sawtooth(period),
Command::Square { period, duty } => Packet::Square { period, duty },
};
packet packet
.write_to_stream(&mut stream) .write_to_stream(&mut stream)

76
src/military_time.rs Normal file
View file

@ -0,0 +1,76 @@
use core::fmt;
use std::str::FromStr;
const NUM_CHARS: usize = 4;
/// Time of day representation in military time.
///
/// Time does not know about anything fancy shmancy like timezones. Just useful
/// for simple time of day comparisons.
#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord)]
pub struct MilitaryTime(u16);
#[derive(Debug)]
pub struct WrongFormat;
impl FromStr for MilitaryTime
{
type Err = WrongFormat;
fn from_str(s: &str) -> Result<Self, Self::Err>
{
if s.len() != NUM_CHARS {
return Err(WrongFormat);
}
let time = u16::from_str(s).map_err(|_| Err(WrongFormat))?;
if time >= 2400 || (time % 100) >= 60 {
Err(WrongFormat)
}
else {
Ok(Self(time))
}
}
}
impl fmt::Display for MilitaryTime
{
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { self.0.fmt(f) }
}
#[cfg(test)]
mod test
{
use std::str::FromStr;
use super::MilitaryTime;
#[test]
fn parse_valid()
{
let valid_times = ["0000", "1234", "2359", "2000"];
for t in valid_times {
let _mt = MilitaryTime::from_str(&t).expect("Failed to parse valid time");
}
}
#[test]
fn parse_wrong_len()
{
let times = ["", "1", "12", "123", "12345"];
for t in times {
let _err = MilitaryTime::from_str(&t).expect_err("Invalid time parsed");
}
}
#[test]
fn parse_invalid_times()
{
let times = ["-123", "0061", "2360", "2400", "-000", "060a"];
for t in times {
let _err = MilitaryTime::from_str(&t).expect_err("Invalid time parsed");
}
}
}

View file

@ -8,19 +8,12 @@ const MAX_PACKET_SIZE_BYTES: u64 = 1024;
#[derive(Serialize, Deserialize)] #[derive(Serialize, Deserialize)]
pub enum Packet pub enum Packet
{ {
/// Constant brightness in range 0.0..1.0 SetDefaultCurveFile(String),
Constant(f64), GetDefaultCurveFile(String),
/// Sinusoidal curve with a period of 0.0.. seconds SetCurve(String),
Sine(f64), SaveCurve(String),
/// Triangle curve with a period of 0.0.. seconds Ok(String),
Triangle(f64), Err(String),
/// Sawtooth curve with a period of 0.0.. seconds
Sawtooth(f64),
/// Square curve witha period of 0.0.. seconds and a duty cycle of 0.0..1.0
Square
{
period: f64, duty: f64
},
} }
#[inline] #[inline]

1
src/schedule.rs Normal file
View file

@ -0,0 +1 @@
pub struct Schedule {}

View file

@ -37,6 +37,7 @@ enum LightMode
Triangle(f64), Triangle(f64),
Sawtooth(f64), Sawtooth(f64),
Square(f64, f64), Square(f64, f64),
DaylightCycle(u32, u32),
} }
impl LightMode impl LightMode
{ {
@ -50,6 +51,9 @@ impl LightMode
Self::Triangle(p) => triangle_wave(t / p), Self::Triangle(p) => triangle_wave(t / p),
Self::Sawtooth(p) => sawtooth_wave(t / p), Self::Sawtooth(p) => sawtooth_wave(t / p),
Self::Square(period, duty) => square_wave(t / period, *duty), Self::Square(period, duty) => square_wave(t / period, *duty),
Self::DaylightCycle(day_start, night_start) => {
let night_after_day = night_start >= day_start;
},
} }
} }
} }

1
transfer.sh Normal file
View file

@ -0,0 +1 @@
scp target/debug/zwote_sonne kuchen:~/