From 422221d97eda0b3532c801e8a5620a8b125cff55 Mon Sep 17 00:00:00 2001 From: FliegendeWurst <2012gdwu+github@posteo.de> Date: Thu, 28 Apr 2022 21:14:26 +0200 Subject: [PATCH] Refactor everything + RGB --- Cargo.lock | 1028 ++++++++++++++++++++++++++++++++--- Cargo.toml | 12 +- src/bin/display_all.rs | 422 ++++++++++++++ src/bin/display_off.rs | 33 ++ src/bin/rgb_test.rs | 102 ++++ src/bin/take_measurement.rs | 53 ++ src/main.rs | 118 +++- 7 files changed, 1678 insertions(+), 90 deletions(-) create mode 100644 src/bin/display_all.rs create mode 100644 src/bin/display_off.rs create mode 100644 src/bin/rgb_test.rs create mode 100644 src/bin/take_measurement.rs diff --git a/Cargo.lock b/Cargo.lock index 884bc34..498fdb0 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3,10 +3,22 @@ version = 3 [[package]] -name = "ahash" -version = "0.7.4" +name = "adler" +version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "43bb833f0bf979d8475d38fbf09ed3b8a55e1885fe93ad3f93239fc6a4f17b98" +checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" + +[[package]] +name = "adler32" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aae1277d39aeec15cb388266ecc24b11c80469deae6067e17a1a7aa9e5c1f234" + +[[package]] +name = "ahash" +version = "0.7.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fcb51a0695d8f838b1ee009b3fbf66bda078cd64590202a864a8f3e8c4315c47" dependencies = [ "getrandom", "once_cell", @@ -15,21 +27,33 @@ dependencies = [ [[package]] name = "autocfg" -version = "1.0.1" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cdb031dd78e28731d87d56cc8ffef4a8f36ca26c38fe2de700543e627f8a464a" +checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" [[package]] name = "az" -version = "1.1.1" +version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "822d7d63e0c0260a050f6b1f0d316f5c79b9eab830aca526ed904e1011bd64ca" +checksum = "f771a5d1f5503f7f4279a30f3643d3421ba149848b89ecaaec0ea2acf04a5ac4" + +[[package]] +name = "bit_field" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dcb6dd1c2376d2e096796e234a70e17e94cc2d5d54ff8ce42b28cef1d0d359a4" [[package]] name = "bitflags" -version = "1.2.1" +version = "1.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693" +checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" + +[[package]] +name = "bumpalo" +version = "3.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a4a45a46ab1f2412e53d3a0ade76ffad2025804294569aae387231a0cd6e0899" [[package]] name = "byte-slice-cast" @@ -37,6 +61,12 @@ version = "0.3.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b0a5e3906bcbf133e33c1d4d95afc664ad37fbdb9f6568d8043e7ea8c27d93d3" +[[package]] +name = "bytemuck" +version = "1.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cdead85bdec19c194affaeeb670c0e41fe23de31459efd1c174d049269cf02cc" + [[package]] name = "byteorder" version = "1.4.3" @@ -45,15 +75,15 @@ checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610" [[package]] name = "cast" -version = "0.2.2" +version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "926013f2860c46252efceabb19f4a6b308197505082c609025aa6706c011d427" +checksum = "37b2a672a2cb129a2e41c10b1224bb368f9f37a2b16b612598138befd7b37eb5" [[package]] name = "cc" -version = "1.0.47" +version = "1.0.73" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aa87058dce70a3ff5621797f1506cb837edd02ac4c0ae642b4542dce802908b8" +checksum = "2fff2a6927b3bb87f9595d67196a70493f627687a71d87a0d692242c33f58c11" [[package]] name = "cfg-if" @@ -67,13 +97,95 @@ version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" +[[package]] +name = "chrono" +version = "0.4.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "670ad68c9088c2a963aaa298cb369688cf3f9465ce5e2d4ca10e6e0098a1ce73" +dependencies = [ + "libc", + "num-integer", + "num-traits", + "time 0.1.43", + "winapi", +] + +[[package]] +name = "color_quant" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3d7b894f5411737b7867f4827955924d7c254fc9f4d91a6aad6b097804b1018b" + +[[package]] +name = "crc32fast" +version = "1.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b540bd8bc810d3885c6ea91e2018302f68baba2129ab3e88f32389ee9370880d" +dependencies = [ + "cfg-if 1.0.0", +] + +[[package]] +name = "crossbeam-channel" +version = "0.5.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5aaa7bd5fb665c6864b5f963dd9097905c54125909c7aa94c9e18507cdbe6c53" +dependencies = [ + "cfg-if 1.0.0", + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-deque" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6455c0ca19f0d2fbf751b908d5c55c1f5cbc65e03c4225427254b46890bdde1e" +dependencies = [ + "cfg-if 1.0.0", + "crossbeam-epoch", + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-epoch" +version = "0.9.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1145cf131a2c6ba0615079ab6a638f7e1973ac9c2634fcbeaaad6114246efe8c" +dependencies = [ + "autocfg", + "cfg-if 1.0.0", + "crossbeam-utils", + "lazy_static", + "memoffset", + "scopeguard", +] + +[[package]] +name = "crossbeam-utils" +version = "0.8.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0bf124c720b7686e3c2663cf54062ab0f68a88af2fb6a030e87e30bf721fcb38" +dependencies = [ + "cfg-if 1.0.0", + "lazy_static", +] + +[[package]] +name = "deflate" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c86f7e25f518f4b81808a2cf1c50996a61f5c2eb394b2393bd87f2a4780a432f" +dependencies = [ + "adler32", +] + [[package]] name = "dht-hal" version = "0.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "eb5423e6132fe67189d1aeac8a7412e7d09816a7374e22201a49a2d5081c8549" dependencies = [ - "embedded-hal", + "embedded-hal 0.2.7", ] [[package]] @@ -82,16 +194,6 @@ version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7517c040926d7b02b111884aa089177db80878533127f7c1b480d852c5fb4112" -[[package]] -name = "display-interface-i2c" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4895cd4e54e5536ef370d7f1eec787aad8275dd8ad15815aebfa71dd847b4ebf" -dependencies = [ - "display-interface", - "embedded-hal", -] - [[package]] name = "display-interface-spi" version = "0.4.1" @@ -100,9 +202,15 @@ checksum = "489378ad054862146fbd1f09f51d585ccbe4bd1e2feadcda2a13ac33f840e1a5" dependencies = [ "byte-slice-cast", "display-interface", - "embedded-hal", + "embedded-hal 0.2.7", ] +[[package]] +name = "either" +version = "1.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e78d4f1cc4ae33bbfc157ed5d5a5ef3bc29227303d595861deb238fcec4e9457" + [[package]] name = "embedded-graphics" version = "0.7.1" @@ -118,9 +226,9 @@ dependencies = [ [[package]] name = "embedded-graphics-core" -version = "0.3.2" +version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7e3902d8d4422aa9ac75556f8cfb2e02c8ba22eb3f1993aec8bc113e6299b2da" +checksum = "b8b1239db5f3eeb7e33e35bd10bd014e7b2537b17e071f726a09351431337cfa" dependencies = [ "az", "byteorder", @@ -128,14 +236,39 @@ dependencies = [ [[package]] name = "embedded-hal" -version = "0.2.5" +version = "0.2.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "db184d3fa27bc7a2344250394c0264144dfe0bc81a4401801dcb964b8dd172ad" +checksum = "35949884794ad573cf46071e41c9b60efb0cb311e3ca01f7af807af1debc66ff" dependencies = [ "nb 0.1.3", "void", ] +[[package]] +name = "embedded-hal" +version = "1.0.0-alpha.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a554c04648665230499563ccdfd1fcd719ef2d5a0af54bdc81c5d877fb556db4" +dependencies = [ + "nb 1.0.0", +] + +[[package]] +name = "exr" +version = "1.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "14cc0e06fb5f67e5d6beadf3a382fec9baca1aa751c6d5368fdeee7e5932c215" +dependencies = [ + "bit_field", + "deflate", + "flume", + "half", + "inflate", + "lebe", + "smallvec", + "threadpool", +] + [[package]] name = "fallible-iterator" version = "0.2.0" @@ -148,6 +281,18 @@ version = "0.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7360491ce676a36bf9bb3c56c1aa791658183a54d2744120f27285738d90465a" +[[package]] +name = "flate2" +version = "1.0.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b39522e96686d38f4bc984b9198e3a0613264abaebaff2c5c918bfa6b6da09af" +dependencies = [ + "cfg-if 1.0.0", + "crc32fast", + "libc", + "miniz_oxide", +] + [[package]] name = "float-cmp" version = "0.8.0" @@ -158,24 +303,51 @@ dependencies = [ ] [[package]] -name = "generic-array" -version = "0.14.4" +name = "flume" +version = "0.10.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "501466ecc8a30d1d3b7fc9229b122b2ce8ed6e9d9223f1138d4babb253e51817" +checksum = "843c03199d0c0ca54bc1ea90ac0d507274c28abcc4f691ae8b4eaa375087c76a" dependencies = [ - "typenum", - "version_check", + "futures-core", + "futures-sink", + "nanorand", + "pin-project", + "spin", ] [[package]] -name = "getrandom" -version = "0.2.3" +name = "futures-core" +version = "0.3.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7fcd999463524c52659517fe2cea98493cfe485d10565e7b0fb07dbba7ad2753" +checksum = "0c09fd04b7e4073ac7156a9539b57a484a8ea920f79c7c675d05d289ab6110d3" + +[[package]] +name = "futures-sink" +version = "0.3.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "21163e139fa306126e6eedaf49ecdb4588f939600f0b1e770f4205ee4b7fa868" + +[[package]] +name = "getrandom" +version = "0.2.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9be70c98951c83b8d2f8f60d7065fa6d5146873094452a1008da8c2f1e4205ad" dependencies = [ "cfg-if 1.0.0", + "js-sys", "libc", "wasi", + "wasm-bindgen", +] + +[[package]] +name = "gif" +version = "0.11.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c3a7187e78088aead22ceedeee99779455b23fc231fe13ec443f99bb71694e5b" +dependencies = [ + "color_quant", + "weezl", ] [[package]] @@ -186,9 +358,26 @@ checksum = "da59d440ef8c26208b3960ed58b71b896db7dfd6bb138622bba733b66d978c3a" dependencies = [ "bitflags", "libc", - "nix", + "nix 0.14.1", ] +[[package]] +name = "gpio-cdev" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "409296415b8abc7b47e5b77096faae14595c53724972da227434fc8f4b05ec8b" +dependencies = [ + "bitflags", + "libc", + "nix 0.23.1", +] + +[[package]] +name = "half" +version = "1.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eabb4a44450da02c90444cf74558da904edde8fb4e9035a9a6a4e15445af0bd7" + [[package]] name = "hashbrown" version = "0.11.2" @@ -208,15 +397,53 @@ dependencies = [ ] [[package]] -name = "i2cdev" -version = "0.4.4" +name = "hermit-abi" +version = "0.1.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3c0eb3d9b6b02dc2508ee23439170004e44344bab9d53a490eb1f64c885b5003" +checksum = "62b467343b94ba476dcb2500d242dadbb39557df889310ac77c5d99100aaac33" +dependencies = [ + "libc", +] + +[[package]] +name = "i2cdev" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b8fe61341e9ce588ede54fd131bf0df63eed3c6e45fcc7fa0e548ea176f39358" dependencies = [ "bitflags", "byteorder", "libc", - "nix", + "nix 0.23.1", +] + +[[package]] +name = "image" +version = "0.24.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "db207d030ae38f1eb6f240d5a1c1c88ff422aa005d10f8c6c6fc5e75286ab30e" +dependencies = [ + "bytemuck", + "byteorder", + "color_quant", + "exr", + "gif", + "jpeg-decoder", + "num-iter", + "num-rational", + "num-traits", + "png", + "scoped_threadpool", + "tiff", +] + +[[package]] +name = "inflate" +version = "0.4.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1cdb29978cc5797bd8dcc8e5bf7de604891df2a8dc576973d71a281e916db2ff" +dependencies = [ + "adler32", ] [[package]] @@ -229,10 +456,46 @@ dependencies = [ ] [[package]] -name = "libc" -version = "0.2.98" +name = "itoa" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "320cfe77175da3a483efed4bc0adc1968ca050b098ce4f2f1c13a56626128790" +checksum = "1aab8fc367588b89dcee83ab0fd66b72b50b72fa1904d7095045ace2b0c81c35" + +[[package]] +name = "jpeg-decoder" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "744c24117572563a98a7e9168a5ac1ee4a1ca7f702211258797bbe0ed0346c3c" +dependencies = [ + "rayon", +] + +[[package]] +name = "js-sys" +version = "0.3.57" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "671a26f820db17c2a2750743f1dd03bafd15b98c9f30c7c2628c024c05d73397" +dependencies = [ + "wasm-bindgen", +] + +[[package]] +name = "lazy_static" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" + +[[package]] +name = "lebe" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7efd1d698db0759e6ef11a7cd44407407399a910c774dd804c64c032da7826ff" + +[[package]] +name = "libc" +version = "0.2.124" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "21a41fed9d98f27ab1c6d161da622a4fa35e8a54a8adc24bbf3ddd0ef70b0e50" [[package]] name = "libsqlite3-sys" @@ -246,18 +509,39 @@ dependencies = [ [[package]] name = "linux-embedded-hal" -version = "0.3.0" +version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e04b2d8e29bb2d949bc9f0ed8acee5033833166731c7e479d0c74d7ef2ab042d" +checksum = "61861762ac50cb746e6137f1aeb2ca9812e1b1f2b923cfc83550befdc0b9915d" dependencies = [ "cast", - "embedded-hal", + "embedded-hal 0.2.7", + "gpio-cdev 0.5.1", "i2cdev", "nb 0.1.3", "serial-core", "serial-unix", "spidev", "sysfs_gpio", + "void", +] + +[[package]] +name = "lock_api" +version = "0.4.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "327fa5b6a6940e4699ec49a9beae1ea4845c6bab9314e4f84ac68742139d8c53" +dependencies = [ + "autocfg", + "scopeguard", +] + +[[package]] +name = "log" +version = "0.4.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6389c490849ff5bc16be905ae24bc913a9c8892e19b2341dbc175e14c341c2b8" +dependencies = [ + "cfg-if 1.0.0", ] [[package]] @@ -272,12 +556,39 @@ version = "2.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "308cc39be01b73d0d18f82a0e7b2a3df85245f84af96fdddc5d202d27e47b86a" +[[package]] +name = "memoffset" +version = "0.6.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5aa361d4faea93603064a027415f07bd8e1d5c88c9fbf68bf56a285428fd79ce" +dependencies = [ + "autocfg", +] + [[package]] name = "micromath" version = "1.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bc4010833aea396656c2f91ee704d51a6f1329ec2ab56ffd00bfd56f7481ea94" +[[package]] +name = "miniz_oxide" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d2b29bd4bc3f33391105ebee3589c19197c4271e3e5a9ec9bfe8127eeff8f082" +dependencies = [ + "adler", +] + +[[package]] +name = "nanorand" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6a51313c5820b0b02bd422f4b44776fbf47961755c74ce64afc73bfad10226c3" +dependencies = [ + "getrandom", +] + [[package]] name = "nb" version = "0.1.3" @@ -306,6 +617,51 @@ dependencies = [ "void", ] +[[package]] +name = "nix" +version = "0.23.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9f866317acbd3a240710c63f065ffb1e4fd466259045ccb504130b7f668f35c6" +dependencies = [ + "bitflags", + "cc", + "cfg-if 1.0.0", + "libc", + "memoffset", +] + +[[package]] +name = "num-integer" +version = "0.1.44" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d2cc698a63b549a70bc047073d2949cce27cd1c7b0a4a862d08a8031bc2801db" +dependencies = [ + "autocfg", + "num-traits", +] + +[[package]] +name = "num-iter" +version = "0.1.42" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b2021c8337a54d21aca0d59a92577a029af9431cb59b909b03252b9c164fad59" +dependencies = [ + "autocfg", + "num-integer", + "num-traits", +] + +[[package]] +name = "num-rational" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d41702bd167c2df5520b384281bc111a4b5efcf7fbc4c9c222c815b07e0a6a6a" +dependencies = [ + "autocfg", + "num-integer", + "num-traits", +] + [[package]] name = "num-traits" version = "0.2.14" @@ -316,37 +672,264 @@ dependencies = [ ] [[package]] -name = "once_cell" -version = "1.8.0" +name = "num_cpus" +version = "1.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "692fcb63b64b1758029e0a96ee63e049ce8c5948587f2f7208df04625e5f6b56" +checksum = "19e64526ebdee182341572e50e9ad03965aa510cd94427a4549448f285e957a1" +dependencies = [ + "hermit-abi", + "libc", +] + +[[package]] +name = "num_threads" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aba1801fb138d8e85e11d0fc70baf4fe1cdfffda7c6cd34a854905df588e5ed0" +dependencies = [ + "libc", +] + +[[package]] +name = "once_cell" +version = "1.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "87f3e037eac156d1775da914196f0f37741a274155e34a0b7e427c35d2a2ecb9" + +[[package]] +name = "parse-zoneinfo" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c705f256449c60da65e11ff6626e0c16a0a0b96aaa348de61376b249bc340f41" +dependencies = [ + "regex", +] + +[[package]] +name = "phf" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fabbf1ead8a5bcbc20f5f8b939ee3f5b0f6f281b6ad3468b84656b658b455259" +dependencies = [ + "phf_shared", +] + +[[package]] +name = "phf_codegen" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4fb1c3a8bc4dd4e5cfce29b44ffc14bedd2ee294559a294e2a4d4c9e9a6a13cd" +dependencies = [ + "phf_generator", + "phf_shared", +] + +[[package]] +name = "phf_generator" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5d5285893bb5eb82e6aaf5d59ee909a06a16737a8970984dd7746ba9283498d6" +dependencies = [ + "phf_shared", + "rand", +] + +[[package]] +name = "phf_shared" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6796ad771acdc0123d2a88dc428b5e38ef24456743ddb1744ed628f9815c096" +dependencies = [ + "siphasher", +] + +[[package]] +name = "pin-project" +version = "1.0.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "58ad3879ad3baf4e44784bc6a718a8698867bb991f8ce24d1bcbe2cfb4c3a75e" +dependencies = [ + "pin-project-internal", +] + +[[package]] +name = "pin-project-internal" +version = "1.0.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "744b6f092ba29c3650faf274db506afd39944f48420f6c86b17cfe0ee1cb36bb" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] [[package]] name = "pkg-config" -version = "0.3.19" +version = "0.3.25" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3831453b3449ceb48b6d9c7ad7c96d5ea673e9b470a1dc578c2ce6521230884c" +checksum = "1df8c4ec4b0627e53bdf214615ad287367e482558cf84b109250b37464dc03ae" + +[[package]] +name = "png" +version = "0.17.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc38c0ad57efb786dd57b9864e5b18bae478c00c824dc55a38bbc9da95dde3ba" +dependencies = [ + "bitflags", + "crc32fast", + "deflate", + "miniz_oxide", +] + +[[package]] +name = "ppv-lite86" +version = "0.2.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eb9f9e6e233e5c4a35559a617bf40a4ec447db2e84c20b55a6f83167b7e57872" + +[[package]] +name = "proc-macro2" +version = "1.0.37" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec757218438d5fda206afc041538b2f6d889286160d649a86a24d37e1235afd1" +dependencies = [ + "unicode-xid", +] + +[[package]] +name = "quote" +version = "1.0.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1feb54ed693b93a84e14094943b84b7c4eae204c512b7ccb95ab0c66d278ad1" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "rand" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" +dependencies = [ + "libc", + "rand_chacha", + "rand_core", +] + +[[package]] +name = "rand_chacha" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" +dependencies = [ + "ppv-lite86", + "rand_core", +] + +[[package]] +name = "rand_core" +version = "0.6.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d34f1408f55294453790c48b2f1ebbb1c5b4b7563eb1f418bcfcfdbb06ebb4e7" +dependencies = [ + "getrandom", +] [[package]] name = "raspi-oled" version = "0.1.0" dependencies = [ "dht-hal", + "display-interface-spi", "embedded-graphics", - "embedded-hal", - "gpio-cdev", + "embedded-hal 0.2.7", + "gpio-cdev 0.4.0", + "image", "libc", "linux-embedded-hal", "machine-ip", + "rppal 0.13.1", "rusqlite", - "ssd1306", + "serde", + "serde_derive", + "serde_json", + "ssd1351", + "time 0.3.9", + "time-tz", +] + +[[package]] +name = "rayon" +version = "1.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fd249e82c21598a9a426a4e00dd7adc1d640b22445ec8545feef801d1a74c221" +dependencies = [ + "autocfg", + "crossbeam-deque", + "either", + "rayon-core", +] + +[[package]] +name = "rayon-core" +version = "1.9.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9f51245e1e62e1f1629cbfec37b5793bbabcaeb90f30e94d2ba03564687353e4" +dependencies = [ + "crossbeam-channel", + "crossbeam-deque", + "crossbeam-utils", + "num_cpus", +] + +[[package]] +name = "regex" +version = "1.5.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1a11647b6b25ff05a515cb92c365cec08801e83423a235b51e231e1808747286" +dependencies = [ + "regex-syntax", +] + +[[package]] +name = "regex-syntax" +version = "0.6.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f497285884f3fcff424ffc933e56d7cbca511def0c9831a7f9b5f6153e3cc89b" + +[[package]] +name = "rppal" +version = "0.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eb26758c881b4837b2f4aef569e4251f75388e36b37204e1804ef429c220121c" +dependencies = [ + "embedded-hal 0.2.7", + "lazy_static", + "libc", + "nb 0.1.3", + "void", +] + +[[package]] +name = "rppal" +version = "0.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c88c9c6248de4d337747b619d8f671055ef48a87dc21b97998833f189a0bbd4f" +dependencies = [ + "embedded-hal 0.2.7", + "embedded-hal 1.0.0-alpha.5", + "lazy_static", + "libc", + "nb 0.1.3", + "spin_sleep", + "void", ] [[package]] name = "rusqlite" -version = "0.25.3" +version = "0.25.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "57adcf67c8faaf96f3248c2a7b419a0dbc52ebe36ba83dd57fe83827c1ea4eb3" +checksum = "5c4b1eaf239b47034fb450ee9cdedd7d0226571689d8823030c4b6c2cb407152" dependencies = [ "bitflags", "fallible-iterator", @@ -357,6 +940,67 @@ dependencies = [ "smallvec", ] +[[package]] +name = "ryu" +version = "1.0.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "73b4b750c782965c211b42f022f59af1fbceabdd026623714f104152f1ec149f" + +[[package]] +name = "scoped_threadpool" +version = "0.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d51f5df5af43ab3f1360b429fa5e0152ac5ce8c0bd6485cae490332e96846a8" + +[[package]] +name = "scopeguard" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd" + +[[package]] +name = "serde" +version = "1.0.136" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ce31e24b01e1e524df96f1c2fdd054405f8d7376249a5110886fb4b658484789" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde-xml-rs" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "65162e9059be2f6a3421ebbb4fef3e74b7d9e7c60c50a0e292c6239f19f1edfa" +dependencies = [ + "log", + "serde", + "thiserror", + "xml-rs", +] + +[[package]] +name = "serde_derive" +version = "1.0.136" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "08597e7152fcd306f41838ed3e37be9eaeed2b61c42e2117266a554fab4662f9" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "serde_json" +version = "1.0.79" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e8d9fa5c3b304765ce1fd9c4c8a3de2c8db365a5b91be52f186efc675681d95" +dependencies = [ + "itoa", + "ryu", + "serde", +] + [[package]] name = "serial-core" version = "0.4.0" @@ -379,43 +1023,89 @@ dependencies = [ ] [[package]] -name = "smallvec" -version = "1.6.1" +name = "simple-signal" +version = "1.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fe0f37c9e8f3c5a4a66ad655a93c74daac4ad00c441533bf5c6e7990bb42604e" - -[[package]] -name = "spidev" -version = "0.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "83d6d2546cfabc5769643fc2a430d6ef811342329a338d1a892c7d52c587890e" +checksum = "53f7da44adcc42667d57483bd93f81295f27d66897804b757573b61b6f13288b" dependencies = [ - "bitflags", + "lazy_static", "libc", - "nix", ] [[package]] -name = "ssd1306" -version = "0.6.0" +name = "siphasher" +version = "0.3.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "32dfc9d17ad1c006fbcd9150b92573a3801b079de234760e545f60981a56f691" +checksum = "7bd3e3206899af3f8b12af284fafc038cc1dc2b41d1b89dd17297221c5d225de" + +[[package]] +name = "smallvec" +version = "1.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f2dd574626839106c320a323308629dcb1acfc96e32a8cba364ddc61ac23ee83" + +[[package]] +name = "spidev" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c43e891adf1abc1e09b10f80c8d91959ee20ec28425c6dadac78844ba4c709f" dependencies = [ + "bitflags", + "libc", + "nix 0.23.1", +] + +[[package]] +name = "spin" +version = "0.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c530c2b0d0bf8b69304b39fe2001993e267461948b890cd037d8ad4293fa1a0d" +dependencies = [ + "lock_api", +] + +[[package]] +name = "spin_sleep" +version = "1.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cafa7900db085f4354dbc7025e25d7a839a14360ea13b5fc4fd717f2d3b23134" +dependencies = [ + "once_cell", + "winapi", +] + +[[package]] +name = "ssd1351" +version = "0.3.0" +dependencies = [ + "chrono", "display-interface", - "display-interface-i2c", "display-interface-spi", - "embedded-graphics-core", - "embedded-hal", - "generic-array", + "embedded-graphics", + "embedded-hal 0.2.7", + "linux-embedded-hal", + "rppal 0.12.0", + "simple-signal", +] + +[[package]] +name = "syn" +version = "1.0.91" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b683b2b825c8eef438b77c36a06dc262294da3d5a5813fac20da149241dcd44d" +dependencies = [ + "proc-macro2", + "quote", + "unicode-xid", ] [[package]] name = "sysfs_gpio" -version = "0.5.4" +version = "0.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "24961a55846623d8e4f6cec38718945116fed8d6970336a7110710a07aa9b5d1" +checksum = "9ef9c9bcbfeb596ce4da59b2c59736235f35dcd516f03958ea10834473224157" dependencies = [ - "nix", + "nix 0.23.1", ] [[package]] @@ -428,10 +1118,92 @@ dependencies = [ ] [[package]] -name = "typenum" -version = "1.13.0" +name = "thiserror" +version = "1.0.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "879f6906492a7cd215bfa4cf595b600146ccfac0c79bcbd1f3000162af5e8b06" +checksum = "854babe52e4df1653706b98fcfc05843010039b406875930a70e4d9644e5c417" +dependencies = [ + "thiserror-impl", +] + +[[package]] +name = "thiserror-impl" +version = "1.0.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aa32fd3f627f367fe16f893e2597ae3c05020f8bba2666a4e6ea73d377e5714b" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "threadpool" +version = "1.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d050e60b33d41c19108b32cea32164033a9013fe3b46cbd4457559bfbf77afaa" +dependencies = [ + "num_cpus", +] + +[[package]] +name = "tiff" +version = "0.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7cfada0986f446a770eca461e8c6566cb879682f7d687c8348aa0c857bd52286" +dependencies = [ + "flate2", + "jpeg-decoder", + "weezl", +] + +[[package]] +name = "time" +version = "0.1.43" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ca8a50ef2360fbd1eeb0ecd46795a87a19024eb4b53c5dc916ca1fd95fe62438" +dependencies = [ + "libc", + "winapi", +] + +[[package]] +name = "time" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c2702e08a7a860f005826c6815dcac101b19b5eb330c27fe4a5928fec1d20ddd" +dependencies = [ + "libc", + "num_threads", + "time-macros", +] + +[[package]] +name = "time-macros" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "42657b1a6f4d817cda8e7a0ace261fe0cc946cf3a80314390b22cc61ae080792" + +[[package]] +name = "time-tz" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5daf6de3ceeb9c81bf15d7f44280da5fe4bb0fa2c55a8d7c781011c33e5ffc2b" +dependencies = [ + "cfg-if 1.0.0", + "parse-zoneinfo", + "phf", + "phf_codegen", + "serde", + "serde-xml-rs", + "time 0.3.9", +] + +[[package]] +name = "unicode-xid" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ccb82d61f80a663efe1f787a51b16b5a51e3314d6ac365b08639f52387b33f3" [[package]] name = "vcpkg" @@ -441,9 +1213,9 @@ checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426" [[package]] name = "version_check" -version = "0.9.3" +version = "0.9.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5fecdca9a5291cc2b8dcf7dc02453fee791a280f3743cb0905f8822ae463b3fe" +checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" [[package]] name = "void" @@ -456,3 +1228,91 @@ name = "wasi" version = "0.10.2+wasi-snapshot-preview1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fd6fbd9a79829dd1ad0cc20627bf1ed606756a7f77edff7b66b7064f9cb327c6" + +[[package]] +name = "wasm-bindgen" +version = "0.2.80" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "27370197c907c55e3f1a9fbe26f44e937fe6451368324e009cba39e139dc08ad" +dependencies = [ + "cfg-if 1.0.0", + "wasm-bindgen-macro", +] + +[[package]] +name = "wasm-bindgen-backend" +version = "0.2.80" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "53e04185bfa3a779273da532f5025e33398409573f348985af9a1cbf3774d3f4" +dependencies = [ + "bumpalo", + "lazy_static", + "log", + "proc-macro2", + "quote", + "syn", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-macro" +version = "0.2.80" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "17cae7ff784d7e83a2fe7611cfe766ecf034111b49deb850a3dc7699c08251f5" +dependencies = [ + "quote", + "wasm-bindgen-macro-support", +] + +[[package]] +name = "wasm-bindgen-macro-support" +version = "0.2.80" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "99ec0dc7a4756fffc231aab1b9f2f578d23cd391390ab27f952ae0c9b3ece20b" +dependencies = [ + "proc-macro2", + "quote", + "syn", + "wasm-bindgen-backend", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-shared" +version = "0.2.80" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d554b7f530dee5964d9a9468d95c1f8b8acae4f282807e7d27d4b03099a46744" + +[[package]] +name = "weezl" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c97e489d8f836838d497091de568cf16b117486d529ec5579233521065bd5e4" + +[[package]] +name = "winapi" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" +dependencies = [ + "winapi-i686-pc-windows-gnu", + "winapi-x86_64-pc-windows-gnu", +] + +[[package]] +name = "winapi-i686-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" + +[[package]] +name = "winapi-x86_64-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" + +[[package]] +name = "xml-rs" +version = "0.8.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d2d7d3948613f75c98fd9328cfdcc45acc4d360655289d0a7d4ec931392200a3" diff --git a/Cargo.toml b/Cargo.toml index 269e1f2..1cd4082 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -11,11 +11,21 @@ embedded-graphics = "0.7.1" linux-embedded-hal = "0.3.0" embedded-hal = "0.2.5" machine-ip = "0.2.1" -ssd1306 = "0.6.0" +#ssd1306 = "0.6.0" libc = "0.2.98" gpio-cdev = "0.4" dht-hal = "0.0.1" rusqlite = "0.25.3" +time = { version = "0.3.9", features = ["parsing"] } +time-tz = "1.0.1" +image = "0.24.1" +serde_json = "1.0.79" +serde_derive = "1.0.136" +serde = "1.0.136" +rppal = { version = "0.13.1", features = ["hal"] } +#ssd1351 = "0.4.0" +ssd1351 = { path = "../ssd1351-rust" } +display-interface-spi = "0.4.1" [profile.release] codegen-units = 1 diff --git a/src/bin/display_all.rs b/src/bin/display_all.rs new file mode 100644 index 0000000..7410ac7 --- /dev/null +++ b/src/bin/display_all.rs @@ -0,0 +1,422 @@ +use std::fs; + +use display_interface_spi::SPIInterfaceNoCS; +use embedded_graphics::{ + draw_target::DrawTarget, + mono_font::{ + ascii::{FONT_10X20, FONT_5X8, FONT_6X9, FONT_9X15}, + MonoTextStyleBuilder, + }, + pixelcolor::{BinaryColor, Rgb565}, + prelude::{OriginDimensions, Point, Primitive, Size}, + primitives::{PrimitiveStyleBuilder, Rectangle}, + text::Text, + Drawable, +}; +use image::{ImageBuffer, Rgb}; +use linux_embedded_hal::I2cdev; +use rppal::{ + gpio::Gpio, + hal::Delay, + spi::{Bus, Mode, SlaveSelect, Spi}, +}; +use rusqlite::Connection; +use serde_derive::Deserialize; +//use ssd1306::{I2CDisplayInterface, Ssd1306, size::DisplaySize128x64, rotation::DisplayRotation, mode::DisplayConfig}; +use time::{format_description, OffsetDateTime, PrimitiveDateTime}; +use time_tz::{timezones::db::europe::BERLIN, OffsetDateTimeExt, PrimitiveDateTimeExt}; + +#[derive(Deserialize)] +struct Events { + events: Vec, + weekly: Vec, +} + +#[derive(Deserialize)] +#[serde(rename_all = "camelCase")] +struct Event { + name: String, + start_time: String, +} + +#[derive(Deserialize)] +struct Weekly { + name: String, + day: i32, + hour: i32, + minute: i32, + duration: i32, +} + +fn main() { + let args = std::env::args().collect::>(); + if args.len() < 4 { + panic!("missing argument: database path, event JSON data file, events / temps"); + } + let database = Connection::open(&args[1]).expect("failed to open database"); + let events = fs::read_to_string(&args[2]).expect("failed to read events.json"); + let events: Events = serde_json::from_str(&events).unwrap(); + + let (rh, temp): (i64, i64) = database + .query_row( + "SELECT humidity, celsius FROM sensor_readings ORDER BY sensor_readings.time DESC LIMIT 1", + [], + |row| Ok((row.get(0).unwrap(), row.get(1).unwrap())), + ) + .unwrap(); + + let time = OffsetDateTime::now_utc().to_timezone(BERLIN); + + let mut query = database + .prepare("SELECT celsius FROM sensor_readings ORDER BY sensor_readings.time DESC LIMIT 288") + .unwrap(); + let mut temps: Vec = query + .query_map([], |r| Ok(r.get(0))) + .unwrap() + .map(Result::unwrap) + .map(Result::unwrap) + .collect(); + let mut global_min = 1000; + let mut global_max = 0; + let mut vals: Vec<(i32, i32)> = vec![]; + for hour in temps.chunks_mut(6) { + hour.sort(); + let mut min = hour[1]; + let mut max = hour[hour.len() - 2]; + println!("min {} max {}", min, max); + // sanity check value + if max > 300 { + if vals.is_empty() { + max = min; + } else { + max = vals.last().unwrap().1; + } + min = min.min(max); + } + + global_min = min.min(global_min); + global_max = max.max(global_max); + vals.push((min, max)); + } + println!("global {} | {}", global_min, global_max); + + let hour = time.hour(); + let minute = time.minute(); + //let i2c = I2cdev::new("/dev/i2c-1").unwrap(); + //let interface = I2CDisplayInterface::new(i2c); + //let mut disp = Ssd1306::new(interface, DisplaySize128x64, DisplayRotation::Rotate0).into_buffered_graphics_mode(); + //disp.init().unwrap(); + //let mut disp = FrameOutput { buffer: ImageBuffer::new(128, 64) }; + let spi = Spi::new(Bus::Spi0, SlaveSelect::Ss0, 19660800, Mode::Mode0).unwrap(); + let gpio = Gpio::new().unwrap(); + let dc = gpio.get(25).unwrap().into_output(); + let mut rst = gpio.get(27).unwrap().into_output(); + + // Init SPI + let spii = SPIInterfaceNoCS::new(spi, dc); + let mut disp = ssd1351::display::display::Ssd1351::new(spii); + + // Reset & init + //disp.reset(&mut rst, &mut Delay).unwrap(); + //disp.turn_on().unwrap(); + + let text_style_clock = MonoTextStyleBuilder::new() + .font(&FONT_10X20) + .text_color(Rgb565::new(0xff, 0xff, 0xff)) + .build(); + let text_style2 = MonoTextStyleBuilder::new() + .font(&FONT_9X15) + .text_color(Rgb565::new(0xff, 0xff, 0xff)) + .build(); + let text_style3 = MonoTextStyleBuilder::new() + .font(&FONT_6X9) + .text_color(Rgb565::new(0xff, 0xff, 0xff)) + .build(); + let text_style4 = MonoTextStyleBuilder::new() + .font(&FONT_5X8) + .text_color(Rgb565::new(0xff, 0xff, 0xff)) + .build(); + let rect_style = PrimitiveStyleBuilder::new() + .fill_color(Rgb565::new(0xff, 0xff, 0xff)) + .build(); + + //let text = format!("{}.{}% {}.{}°C", rh / 10, rh % 10, temp / 10, temp % 10); + //Text::new(&text, Point::new(0, 10), text_style).draw(&mut disp).unwrap(); + let hour = format!("{:02}", hour); + Text::new(&hour, Point::new(64 + 10, 6 + 20), text_style_clock) + .draw(&mut disp) + .unwrap(); + let minute = format!("{:02}", minute); + Text::new(&minute, Point::new(64 + 10 + 20 + 4, 6 + 20), text_style_clock) + .draw(&mut disp) + .unwrap(); + Rectangle::new((95, 17).into(), (2, 2).into()) + .into_styled(rect_style) + .draw(&mut disp) + .unwrap(); + Rectangle::new((95, 22).into(), (2, 2).into()) + .into_styled(rect_style) + .draw(&mut disp) + .unwrap(); + + let rh = format!("{:02}", rh / 10); + Text::new(&rh, Point::new(64 + 3, 64 - 4), text_style2) + .draw(&mut disp) + .unwrap(); + Text::new("%", Point::new(64 + 3 + 18, 64 - 4), text_style3) + .draw(&mut disp) + .unwrap(); + let temp_int = format!("{:02}", temp / 10); + Text::new(&temp_int, Point::new(64 + 32 + 3, 64 - 4), text_style2) + .draw(&mut disp) + .unwrap(); + Rectangle::new((64 + 32 + 3 + 18, 64 - 4).into(), (1, 1).into()) + .into_styled(rect_style) + .draw(&mut disp) + .unwrap(); + let temp_fract = format!("{}", temp % 10); + Text::new(&temp_fract, Point::new(64 + 32 + 3 + 18 + 2, 64 - 4), text_style3) + .draw(&mut disp) + .unwrap(); + + for (x, y) in [ + (118, 49), + (119, 49), + (117, 50), + (117, 51), + (120, 50), + (120, 51), + (118, 52), + (119, 52), + (122, 50), + (122, 51), + (122, 52), + (123, 49), + (124, 49), + (123, 53), + (124, 53), + ] { + Rectangle::new((x, y).into(), (1, 1).into()) + .into_styled(rect_style) + .draw(&mut disp) + .unwrap(); + } + + let x = 0; + let y = 0; + Rectangle::new((x + 2, y + 8).into(), (1, 24).into()) + .into_styled(rect_style) + .draw(&mut disp) + .unwrap(); + Rectangle::new((x + 1, y + 16).into(), (1, 1).into()) + .into_styled(rect_style) + .draw(&mut disp) + .unwrap(); + Rectangle::new((x + 1, y + 28).into(), (1, 1).into()) + .into_styled(rect_style) + .draw(&mut disp) + .unwrap(); + let mut day = time.weekday().number_days_from_monday() as usize; + let days = [ + ("M", "o"), + ("D", "i"), + ("M", "i"), + ("D", "o"), + ("F", "r"), + ("S", "a"), + ("S", "o"), + ]; + for i in 0..5 { + Text::new(days[day].0, (x + 12 * i + 4, y + 6).into(), text_style3) + .draw(&mut disp) + .unwrap(); + Text::new(days[day].1, (x + 12 * i + 10, y + 6).into(), text_style4) + .draw(&mut disp) + .unwrap(); + day += 1; + day %= days.len(); + } + let mut bits = vec![]; + // events + let mut all_events = vec![]; + for event in events.weekly { + all_events.push((event.day, event.hour, event.minute, event.duration, event.name)); + } + let today = time.date().to_julian_day(); + let format = format_description::parse("[year]-[month]-[day]T[hour]:[minute]:[second]").unwrap(); + for event in events.events { + let dt = PrimitiveDateTime::parse(&event.start_time, &format) + .unwrap() + .assume_timezone(BERLIN) + .unwrap(); + let julian_day = dt.to_julian_day(); + if dt < time || julian_day - today > 4 { + continue; + } + all_events.push(( + dt.weekday().number_days_from_monday() as _, + dt.hour() as _, + dt.minute() as _, + 30, + event.name, + )); // TODO length + } + let weekday = time.weekday().number_days_from_monday() as i32; + all_events.sort_by_key(|x| (((x.0 + 7) - weekday) % 7, x.1, x.2)); + println!("{:?}", all_events); + let mut time_until_first = None; + for i in 0..5 { + let day = (weekday + i) % 7; + for hour in 0..24 { + for minute in 0..60 { + if minute % 6 != 0 { + continue; + } + + if i == 0 && hour == time.hour() as i32 && minute == (time.minute() as i32 / 6) * 6 { + bits.push((i, hour, minute / 6, Rgb565::new(0xff, 0x00, 0xff))); + } + + for event in &all_events { + if event.0 != day { + continue; + } + let event_start = event.1 * 60 + event.2; + let event_end = event_start + event.3; + let now = hour * 60 + minute; + let now2 = hour * 60 + minute + 6; + if now2 > event_start && now < event_end { + bits.push((i, hour, minute / 6, Rgb565::new(0xff, 0xff, 0x10))); + } + if time_until_first.is_none() { + time_until_first = Some( + ((i * 24 + event.1) * 60 + event.2) * 60 + - (time.hour() as i32 * 60 + time.minute() as i32) * 60, + ); + } + } + } + } + } + for (d, h, m, color) in bits { + // calculate position + let x = x + 4 + d * 12 + m; + let y = y + 8 + h; + disp.fill_solid(&Rectangle::new((x, y).into(), (1, 1).into()), color) + .unwrap(); + //Rectangle::new((x, y).into(), (1, 1).into()).into_styled(rect_style).draw(&mut disp).unwrap(); + } + if args[3] == "events" { + for (i, event) in all_events.iter().take(7).enumerate() { + let text = if event.4.len() > 10 { &event.4[0..10] } else { &event.4 }; + Text::new(text, (x + 2, y + 64 + 9 * i as i32 + 5).into(), text_style3) + .draw(&mut disp) + .unwrap(); + } + } else { + let diff = global_max - global_min; + let x = 0; + let y = 64; + let scaley = 63; + let scalex = 2; + vals.reverse(); + for (i, (a, b)) in vals.into_iter().enumerate() { + let x = x + i as i32 * scalex; + let y1 = y + (global_max - b) * scaley / diff; + let y2 = y + (global_max - a) * scaley / diff; + let height = y2 - y1 + 1; + let rect = Rectangle::new((x, y1).into(), (scalex as u32, height as u32).into()); + disp.fill_solid(&rect, Rgb565::new(0xff, 0xff, 0xff)).unwrap(); + } + Text::new( + &format!("{}", global_max as f32 / 10.0), + (100, 64 + 10).into(), + text_style3, + ) + .draw(&mut disp) + .unwrap(); + Text::new( + &format!("{}", global_min as f32 / 10.0), + (100, 64 + 50).into(), + text_style3, + ) + .draw(&mut disp) + .unwrap(); + } + if let Some(secs) = time_until_first { + let days = secs / (24 * 60 * 60); + let hours = secs / (60 * 60) % 24; + let minutes = secs / 60 % 60; + let text = if days > 0 { + String::new() + } else if hours > 0 { + format!("{}h{}m", hours, minutes) + } else if minutes > 0 { + format!("{}m", minutes) + } else { + "?".into() + }; + Text::new(&text, (x + 2, y + 60).into(), text_style2) + .draw(&mut disp) + .unwrap(); + } + /* + sleep(Duration::from_secs(2)); + disp.clear(); + + let base_y = 0.0; + let max_dy = 32.0; + let mut tick = 0; + loop { + let y = if tick % 32 < 16 { + base_y + (tick % 16) as f32 / 16.0 * max_dy + } else { + base_y + max_dy - (tick % 16) as f32 / 16.0 * max_dy + } as i32; + tick += 1; + Line::new(Point::new(8, y + 16), Point::new(8 + 16, y + 16)) + .into_styled(PrimitiveStyle::with_stroke(BinaryColor::On, 1)) + .draw(&mut disp).unwrap(); + Line::new(Point::new(8, y + 16), Point::new(8 + 8, y)) + .into_styled(PrimitiveStyle::with_stroke(BinaryColor::On, 1)) + .draw(&mut disp).unwrap(); + + Line::new(Point::new(8 + 16, y + 16), Point::new(8 + 8, y)) + .into_styled(PrimitiveStyle::with_stroke(BinaryColor::On, 1)) + .draw(&mut disp).unwrap(); + + Rectangle::new(Point::new(48, y), Size::new(16, 16)) + .into_styled(PrimitiveStyle::with_stroke(BinaryColor::On, 1)) + .draw(&mut disp).unwrap(); + + + Circle::new(Point::new(88, y), 16) + .into_styled(PrimitiveStyle::with_stroke(BinaryColor::On, 1)) + .draw(&mut disp).unwrap(); + + /* + Text::new(&format!("Hello from frame {}", tick), Point::new(0, 56), text_style) + .draw(&mut disp) + .unwrap(); + */ + disp.flush().unwrap(); + + sleep(Duration::from_millis(10)); + + disp.clear(); + + /* + let im: ImageRaw = ImageRaw::new(IMG_DATA, 64); + let img = Image::new(&im, Point::new(32, 0)); + img.draw(&mut disp).unwrap(); + disp.flush().unwrap(); + + sleep(Duration::from_secs(2)); + disp.clear(); + */ + } + */ + + let _ = disp.flush(); + //disp.buffer.save("/tmp/frame.png").unwrap(); +} diff --git a/src/bin/display_off.rs b/src/bin/display_off.rs new file mode 100644 index 0000000..d209aa9 --- /dev/null +++ b/src/bin/display_off.rs @@ -0,0 +1,33 @@ +use display_interface_spi::SPIInterfaceNoCS; +use rppal::{ + gpio::Gpio, + hal::Delay, + spi::{Bus, Mode, SlaveSelect, Spi}, +}; + +fn main() { + let args = std::env::args().collect::>(); + if args.len() < 2 { + panic!("missing argument: on/off"); + } + display_on_ssd1306(args[1] == "on"); +} + +fn display_on_ssd1306(on: bool) { + let spi = Spi::new(Bus::Spi0, SlaveSelect::Ss0, 19660800, Mode::Mode0).unwrap(); + let gpio = Gpio::new().unwrap(); + let dc = gpio.get(25).unwrap().into_output(); + let mut rst = gpio.get(27).unwrap().into_output(); + + // Init SPI + let spii = SPIInterfaceNoCS::new(spi, dc); + let mut disp = ssd1351::display::display::Ssd1351::new(spii); + + // Reset & init + disp.reset(&mut rst, &mut Delay).unwrap(); + if on { + disp.turn_on().unwrap(); + } else { + disp.turn_off().unwrap(); + } +} diff --git a/src/bin/rgb_test.rs b/src/bin/rgb_test.rs new file mode 100644 index 0000000..155dcf4 --- /dev/null +++ b/src/bin/rgb_test.rs @@ -0,0 +1,102 @@ +use std::{ + fs, thread, + time::{Duration, Instant}, +}; + +use display_interface_spi::SPIInterfaceNoCS; +use embedded_graphics::{ + draw_target::DrawTarget, + mono_font::{ + ascii::{FONT_10X20, FONT_5X8, FONT_6X9, FONT_9X15}, + MonoTextStyleBuilder, + }, + pixelcolor::{BinaryColor, Rgb565}, + prelude::{OriginDimensions, Point, Primitive, Size}, + primitives::{PrimitiveStyleBuilder, Rectangle}, + text::Text, + Drawable, +}; +use embedded_hal::digital::v2::OutputPin; +use gpio_cdev::{Chip, LineHandle, LineRequestFlags}; +use image::{ImageBuffer, Rgb}; +use linux_embedded_hal::I2cdev; +use rppal::{ + gpio::Gpio, + hal::Delay, + spi::{Bus, Mode, SlaveSelect, Spi}, +}; +//use ssd1351::{properties::DisplaySize, mode::{GraphicsMode, displaymode::DisplayModeTrait}}; +use time::{format_description, OffsetDateTime, PrimitiveDateTime}; +//use time_tz::{timezones::db::europe::BERLIN, OffsetDateTimeExt, PrimitiveDateTimeExt}; + +fn main() { + //let i2c = I2cdev::new("/dev/i2c-1").unwrap(); + //let interface = I2CDisplayInterface::new(i2c); + //let mut disp = Ssd1306::new(interface, DisplaySize128x64, DisplayRotation::Rotate0).into_buffered_graphics_mode(); + //disp.init().unwrap(); + // Configure gpio + let spi = Spi::new(Bus::Spi0, SlaveSelect::Ss0, 19660800, Mode::Mode0).unwrap(); + let gpio = Gpio::new().unwrap(); + let dc = gpio.get(25).unwrap().into_output(); + let mut rst = gpio.get(27).unwrap().into_output(); + + // Init SPI + let spii = SPIInterfaceNoCS::new(spi, dc); + let mut disp = ssd1351::display::display::Ssd1351::new(spii); + + // Reset & init + disp.reset(&mut rst, &mut Delay).unwrap(); + disp.turn_on().unwrap(); + + /* + thread::sleep(Duration::from_secs(5)); + disp.reset(&mut rst, &mut Delay).unwrap(); + disp.turn_off().unwrap(); + panic!("done!"); + */ + + // Clear the display + disp.clear(Rgb565::new(0x00, 0x00, 0x00)).unwrap(); + + //disp.flush().unwrap(); + //disp.flush().unwrap(); + + let text_style_clock = MonoTextStyleBuilder::new() + .font(&FONT_10X20) + .text_color(Rgb565::new(0xff, 0x00, 0x00)) + .build(); + + //let text = format!("{}.{}% {}.{}°C", rh / 10, rh % 10, temp / 10, temp % 10); + //Text::new(&text, Point::new(0, 10), text_style).draw(&mut disp).unwrap(); + Text::new("Abc", (0, 30).into(), text_style_clock) + .draw(&mut disp) + .unwrap(); + + let _ = disp.flush(); + + thread::sleep(Duration::from_secs(15)); + Text::new("5 seconds to off!", (0, 60).into(), text_style_clock) + .draw(&mut disp) + .unwrap(); + let start = Instant::now(); + let _ = disp.flush(); + println!("{:?} ms", start.elapsed().as_millis()); + thread::sleep(Duration::from_secs(5)); + + disp.reset(&mut rst, &mut Delay).unwrap(); + disp.turn_off().unwrap(); +} + +struct LineHandleWrapper(LineHandle); + +impl OutputPin for LineHandleWrapper { + type Error = gpio_cdev::Error; + + fn set_low(&mut self) -> Result<(), Self::Error> { + self.0.set_value(0) + } + + fn set_high(&mut self) -> Result<(), Self::Error> { + self.0.set_value(1) + } +} diff --git a/src/bin/take_measurement.rs b/src/bin/take_measurement.rs new file mode 100644 index 0000000..312839a --- /dev/null +++ b/src/bin/take_measurement.rs @@ -0,0 +1,53 @@ +use std::time::{Duration, SystemTime}; + +use gpio_cdev::Chip; +use rusqlite::{params, Connection}; + +fn main() { + let args = std::env::args().collect::>(); + if args.len() < 2 { + panic!("missing argument: database path"); + } + let database = Connection::open(&args[1]).expect("failed to open database"); + database + .execute( + " + CREATE TABLE IF NOT EXISTS sensor_readings( + time INTEGER PRIMARY KEY, + humidity INTEGER NOT NULL, + celsius INTEGER NOT NULL + )", + [], + ) + .unwrap(); + + let mut chip = Chip::new("/dev/gpiochip0").unwrap(); + let line = chip.get_line(26).unwrap(); + let mut attempts = 0; + let mut temps = vec![]; + let mut rhs = vec![]; + let time = std::time::SystemTime::now() + .duration_since(SystemTime::UNIX_EPOCH) + .unwrap(); + while temps.len() < 5 && attempts < 10 { + if let Ok((rh, temp)) = raspi_oled::am2302_reading(&line) { + if rh > 0 && temp < 500 { + rhs.push(rh); + temps.push(temp); + } + } + std::thread::sleep(Duration::from_secs(5)); + attempts += 1; + } + if !temps.is_empty() { + // median = hopefully no faulty readings + temps.sort(); + rhs.sort(); + database + .execute( + "INSERT INTO sensor_readings (time, humidity, celsius) VALUES (?1, ?2, ?3)", + params![time.as_secs(), rhs[rhs.len() / 2], temps[temps.len() / 2]], + ) + .unwrap(); + } +} diff --git a/src/main.rs b/src/main.rs index a54bd78..2889acb 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,3 +1,110 @@ +use embedded_graphics::{ + draw_target::DrawTarget, + pixelcolor::BinaryColor, + prelude::{OriginDimensions, Size}, + primitives::Rectangle, +}; +use image::{ImageBuffer, Rgb}; +use rusqlite::Connection; + +struct FrameOutput { + buffer: ImageBuffer, Vec>, +} + +impl DrawTarget for FrameOutput { + type Color = BinaryColor; + + type Error = (); + + fn draw_iter(&mut self, pixels: I) -> Result<(), Self::Error> + where + I: IntoIterator>, + { + for pos in pixels { + if pos.0.x < 0 || pos.0.y < 0 || pos.0.x >= 128 || pos.0.y >= 64 { + continue; + } + let color = if pos.1 == BinaryColor::On { + Rgb([0, 255, 255]) + } else { + Rgb([0, 0, 0]) + }; + self.buffer.put_pixel(pos.0.x as u32, pos.0.y as u32, color); + } + Ok(()) + } +} + +impl OriginDimensions for FrameOutput { + fn size(&self) -> Size { + Size::new(self.buffer.width(), self.buffer.height()) + } +} + +fn main() { + let args = std::env::args().collect::>(); + if args.len() < 2 { + panic!("missing argument: database path"); + } + + let mut disp = FrameOutput { + buffer: ImageBuffer::new(128, 64), + }; + + let database = Connection::open(&args[1]).expect("failed to open database"); + + let mut query = database + .prepare("SELECT celsius FROM sensor_readings ORDER BY sensor_readings.time DESC LIMIT 288") + .unwrap(); + let mut temps: Vec = query + .query_map([], |r| Ok(r.get(0))) + .unwrap() + .map(Result::unwrap) + .map(Result::unwrap) + .collect(); + let mut global_min = 1000; + let mut global_max = 0; + let mut vals: Vec<(i32, i32)> = vec![]; + for hour in temps.chunks_mut(6) { + hour.sort(); + let min = hour[1]; + let mut max = hour[hour.len() - 2]; + println!("min {} max {}", min, max); + // sanity check value + if max > 300 { + if vals.is_empty() { + max = min; + } else { + max = vals.last().unwrap().1; + } + } + + global_min = min.min(global_min); + global_max = max.max(global_max); + vals.push((min, max)); + } + println!("global {} | {}", global_min, global_max); + let diff = global_max - global_min; + let x = 1; + let y = 1; + let scaley = 64; + let scalex = 2; + vals.reverse(); + for (i, (a, b)) in vals.into_iter().enumerate() { + let x = x + i as i32 * scalex; + let y1 = y + (global_max - b) * scaley / diff; + let y2 = y + (global_max - a) * scaley / diff; + let height = y2 - y1 + 1; + disp.fill_solid( + &Rectangle::new((x, y1).into(), (scalex as u32, height as u32).into()), + BinaryColor::On, + ) + .unwrap(); + } + + disp.buffer.save("/tmp/frame.png").unwrap(); +} +/* use dht_hal::{Dht22, Reading}; use embedded_graphics::image::{Image, ImageRaw}; use embedded_graphics::mono_font::iso_8859_7::FONT_9X18; @@ -120,11 +227,11 @@ fn main() { database .execute( " - CREATE TABLE IF NOT EXISTS sensor_readings( - time INTEGER PRIMARY KEY, - humidity INTEGER NOT NULL, - celsius INTEGER NOT NULL - )", + CREATE TABLE IF NOT EXISTS sensor_readings( + time INTEGER PRIMARY KEY, + humidity INTEGER NOT NULL, + celsius INTEGER NOT NULL + )", [], ) .unwrap(); @@ -289,3 +396,4 @@ impl OutputPin for LineWrapper { .set_value(1) } } +*/