Compare commits
	
		
			110 Commits
		
	
	
		
			1.0.2
			...
			e961ea0911
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| e961ea0911 | |||
| 1c1eb53b6e | |||
| 1a2badc138 | |||
| 9323a4a3f5 | |||
| 35cfc73c9d | |||
| dad54c638b | |||
| 4f5be4d08c | |||
| b89aee2dcc | |||
| bbe2c3ebc5 | |||
| 62037db6e3 | |||
| 0bf3bdbaea | |||
| f65df5f22a | |||
| 406a920d7e | |||
| 889ba9b85f | |||
| 12606ba336 | |||
| cb2e17581a | |||
| 4dd5fb4e55 | |||
| 0a162e4a78 | |||
| ba45faf017 | |||
| c4dedb946f | |||
| 5004194567 | |||
| 768f8fc112 | |||
| adf1477c4b | |||
| 7474e25209 | |||
| f33c408c67 | |||
| ccd4125500 | |||
| 9825f2628b | |||
| 9e5797e4ca | |||
| fb562f908c | |||
| ffb00ee668 | |||
| 3ad64e55b8 | |||
| f01df2818c | |||
| da60a57f53 | |||
| 0629bd60c3 | |||
| 995977fd37 | |||
| 9bf15f28b8 | |||
| 8941ec2aef | |||
| b19961ed6a | |||
| 082efa367c | |||
| 3ffcdad666 | |||
| 65db36d097 | |||
| 57bb552950 | |||
| 1d9c539cd1 | |||
| 11d718cfe8 | |||
| 0125b16177 | |||
| d97dcddb96 | |||
| 9eafbd8aeb | |||
| 6aa7fc3a75 | |||
| 345b3566ae | |||
| 22cd346330 | |||
| aee9303f91 | |||
| 6462645d26 | |||
| 4bb76777db | |||
| d79b55b86d | |||
| 665a04c8a0 | |||
| 658b10f5f8 | |||
| c0374e35b1 | |||
| 15f701668f | |||
| 8fdfa19806 | |||
| 22d84e9464 | |||
| a5c5663390 | |||
| 7878fb9686 | |||
| b24642b10d | |||
| ce45d841b2 | |||
| 1b4e5eda9d | |||
| bb1917d1b4 | |||
| b285323bd7 | |||
| ecb161ee82 | |||
| 00c6ae338b | |||
| 814046146c | |||
| f52e992d84 | |||
| dc73882347 | |||
| 5ed8c42b99 | |||
| 0fcb902e9e | |||
| cfafbda77b | |||
| dace42aef2 | |||
| 67401e8faf | |||
| 77a278bd53 | |||
| 6df43fcc0e | |||
| 8add37fc42 | |||
| bfde6531c2 | |||
| 5f6ac7bcfd | |||
| c01f1ca484 | |||
| c6975c2097 | |||
| 2d079403c5 | |||
| 2d408871ad | |||
| 22fd077380 | |||
| 0fba1caf62 | |||
| 7e99cfc086 | |||
| 511011bb4b | |||
| dfca6a04bc | |||
| 4f639522b9 | |||
| 7d9af6af64 | |||
| e1136926a1 | |||
| 4206d9529b | |||
| b606aed10e | |||
| 9a2ceb9804 | |||
| f6bd7b1061 | |||
| 34460500a0 | |||
| 72afa3df62 | |||
| e74f7d6f6d | |||
| 5b09aec93a | |||
| 9f93f76d8e | |||
| 211369a1b2 | |||
| d7c4cd6635 | |||
| 4f78e99f65 | |||
| 541f7cbe95 | |||
| fc5f9735bf | |||
| ffbbd14ac3 | |||
| 4330e64489 | 
| @@ -5,7 +5,7 @@ name: default | |||||||
|  |  | ||||||
| steps: | steps: | ||||||
|   - name: web_build |   - name: web_build | ||||||
|     image: node:21 |     image: node:23 | ||||||
|     volumes: |     volumes: | ||||||
|       - name: web_app |       - name: web_app | ||||||
|         path: /tmp/web_build |         path: /tmp/web_build | ||||||
| @@ -56,7 +56,7 @@ steps: | |||||||
|       - ls -lah target/release/central_backend |       - ls -lah target/release/central_backend | ||||||
|  |  | ||||||
|   - name: esp32_compile |   - name: esp32_compile | ||||||
|     image: espressif/idf:v5.3.1 |     image: espressif/idf:v5.4.1 | ||||||
|     commands: |     commands: | ||||||
|       - cd esp32_device |       - cd esp32_device | ||||||
|       - /opt/esp/entrypoint.sh idf.py build |       - /opt/esp/entrypoint.sh idf.py build | ||||||
|   | |||||||
							
								
								
									
										1301
									
								
								central_backend/Cargo.lock
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										1301
									
								
								central_backend/Cargo.lock
									
									
									
										generated
									
									
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							| @@ -1,46 +1,46 @@ | |||||||
| [package] | [package] | ||||||
| name = "central_backend" | name = "central_backend" | ||||||
| version = "1.0.2" | version = "1.0.2" | ||||||
| edition = "2021" | edition = "2024" | ||||||
|  |  | ||||||
| [dependencies] | [dependencies] | ||||||
| log = "0.4.22" | log = "0.4.27" | ||||||
| env_logger = "0.11.5" | env_logger = "0.11.8" | ||||||
| lazy_static = "1.5.0" | lazy_static = "1.5.0" | ||||||
| dotenvy = "0.15.7" | dotenvy = "0.15.7" | ||||||
| clap = { version = "4.5.20", features = ["derive", "env"] } | clap = { version = "4.5.37", features = ["derive", "env"] } | ||||||
| anyhow = "1.0.89" | anyhow = "1.0.98" | ||||||
| thiserror = "2.0.3" | thiserror = "2.0.12" | ||||||
| openssl = { version = "0.10.66" } | openssl = { version = "0.10.72" } | ||||||
| openssl-sys = "0.9.102" | openssl-sys = "0.9.108" | ||||||
| libc = "0.2.159" | libc = "0.2.172" | ||||||
| foreign-types-shared = "0.1.1" | foreign-types-shared = "0.1.1" | ||||||
| asn1 = "0.20" | asn1 = "0.21.1" | ||||||
| actix-web = { version = "4", features = ["openssl"] } | actix-web = { version = "4.10.2", features = ["openssl"] } | ||||||
| futures = "0.3.31" | futures = "0.3.31" | ||||||
| serde = { version = "1.0.215", features = ["derive"] } | serde = { version = "1.0.219", features = ["derive"] } | ||||||
| reqwest = { version = "0.12.7", features = ["json"] } | reqwest = { version = "0.12.15", features = ["json"] } | ||||||
| serde_json = "1.0.131" | serde_json = "1.0.140" | ||||||
| rand = "0.8.5" | rand = "0.9.1" | ||||||
| actix = "0.13.5" | actix = "0.13.5" | ||||||
| actix-identity = "0.8.0" | actix-identity = "0.8.0" | ||||||
| actix-session = { version = "0.10.1", features = ["cookie-session"] } | actix-session = { version = "0.10.1", features = ["cookie-session"] } | ||||||
| actix-cors = "0.7.0" | actix-cors = "0.7.1" | ||||||
| actix-multipart = { version = "0.7.2", features = ["derive"] } | actix-multipart = { version = "0.7.2", features = ["derive"] } | ||||||
| actix-remote-ip = "0.1.0" | actix-remote-ip = "0.1.0" | ||||||
| futures-util = "0.3.31" | futures-util = "0.3.31" | ||||||
| uuid = { version = "1.11.0", features = ["v4", "serde"] } | uuid = { version = "1.16.0", features = ["v4", "serde"] } | ||||||
| semver = { version = "1.0.23", features = ["serde"] } | semver = { version = "1.0.26", features = ["serde"] } | ||||||
| lazy-regex = "3.3.0" | lazy-regex = "3.4.1" | ||||||
| tokio = { version = "1.40.0", features = ["full"] } | tokio = { version = "1.44.2", features = ["full"] } | ||||||
| tokio_schedule = "0.3.2" | tokio_schedule = "0.3.2" | ||||||
| mime_guess = "2.0.5" | mime_guess = "2.0.5" | ||||||
| rust-embed = "8.5.0" | rust-embed = "8.6.0" | ||||||
| jsonwebtoken = { version = "9.3.0", features = ["use_pem"] } | jsonwebtoken = { version = "9.3.1", features = ["use_pem"] } | ||||||
| prettytable-rs = "0.10.0" | prettytable-rs = "0.10.0" | ||||||
| chrono = "0.4.38" | chrono = "0.4.41" | ||||||
| serde_yml = "0.0.12" | serde_yml = "0.0.12" | ||||||
| bincode = "=2.0.0-rc.3" | bincode = "2.0.1" | ||||||
| fs4 = { version = "0.12.0", features = ["sync"] } | fs4 = { version = "0.13.1", features = ["sync"] } | ||||||
| zip = { version = "2.2.0", features = ["bzip2"] } | zip = { version = "2.2.0", features = ["bzip2"] } | ||||||
| walkdir = "2.5.0" | walkdir = "2.5.0" | ||||||
| @@ -13,10 +13,10 @@ use openssl::pkey::{PKey, Private}; | |||||||
| use openssl::x509::extension::{ | use openssl::x509::extension::{ | ||||||
|     BasicConstraints, ExtendedKeyUsage, KeyUsage, SubjectAlternativeName, SubjectKeyIdentifier, |     BasicConstraints, ExtendedKeyUsage, KeyUsage, SubjectAlternativeName, SubjectKeyIdentifier, | ||||||
| }; | }; | ||||||
| use openssl::x509::{CrlStatus, X509Crl, X509Name, X509NameBuilder, X509Req, X509}; | use openssl::x509::{CrlStatus, X509, X509Crl, X509Name, X509NameBuilder, X509Req}; | ||||||
| use openssl_sys::{ | use openssl_sys::{ | ||||||
|     X509_CRL_add0_revoked, X509_CRL_new, X509_CRL_set1_lastUpdate, X509_CRL_set1_nextUpdate, |     X509_CRL_add0_revoked, X509_CRL_new, X509_CRL_set_issuer_name, X509_CRL_set_version, | ||||||
|     X509_CRL_set_issuer_name, X509_CRL_set_version, X509_CRL_sign, X509_REVOKED_dup, |     X509_CRL_set1_lastUpdate, X509_CRL_set1_nextUpdate, X509_CRL_sign, X509_REVOKED_dup, | ||||||
|     X509_REVOKED_new, X509_REVOKED_set_revocationDate, X509_REVOKED_set_serialNumber, |     X509_REVOKED_new, X509_REVOKED_set_revocationDate, X509_REVOKED_set_serialNumber, | ||||||
| }; | }; | ||||||
|  |  | ||||||
|   | |||||||
| @@ -325,9 +325,11 @@ mod tests { | |||||||
|             ..Default::default() |             ..Default::default() | ||||||
|         }; |         }; | ||||||
|         dep_cycle_1.depends_on = vec![dep_cycle_3.id]; |         dep_cycle_1.depends_on = vec![dep_cycle_3.id]; | ||||||
|         assert!(dep_cycle_1 |         assert!( | ||||||
|  |             dep_cycle_1 | ||||||
|                 .error(&[dep_cycle_2.clone(), dep_cycle_3.clone()]) |                 .error(&[dep_cycle_2.clone(), dep_cycle_3.clone()]) | ||||||
|             .is_some()); |                 .is_some() | ||||||
|  |         ); | ||||||
|  |  | ||||||
|         dep_cycle_1.depends_on = vec![]; |         dep_cycle_1.depends_on = vec![]; | ||||||
|         assert!(dep_cycle_1.error(&[dep_cycle_2, dep_cycle_3]).is_none()); |         assert!(dep_cycle_1.error(&[dep_cycle_2, dep_cycle_3]).is_none()); | ||||||
| @@ -351,21 +353,29 @@ mod tests { | |||||||
|             ..Default::default() |             ..Default::default() | ||||||
|         }; |         }; | ||||||
|  |  | ||||||
|         assert!(target_relay |         assert!( | ||||||
|  |             target_relay | ||||||
|                 .error(&[other_dep.clone(), second_dep.clone()]) |                 .error(&[other_dep.clone(), second_dep.clone()]) | ||||||
|             .is_some()); |                 .is_some() | ||||||
|         assert!(target_relay |         ); | ||||||
|  |         assert!( | ||||||
|  |             target_relay | ||||||
|                 .error(&[other_dep.clone(), second_dep.clone(), target_relay.clone()]) |                 .error(&[other_dep.clone(), second_dep.clone(), target_relay.clone()]) | ||||||
|             .is_some()); |                 .is_some() | ||||||
|  |         ); | ||||||
|  |  | ||||||
|         second_dep.conflicts_with = vec![]; |         second_dep.conflicts_with = vec![]; | ||||||
|  |  | ||||||
|         assert!(target_relay |         assert!( | ||||||
|  |             target_relay | ||||||
|                 .error(&[other_dep.clone(), second_dep.clone()]) |                 .error(&[other_dep.clone(), second_dep.clone()]) | ||||||
|             .is_none()); |                 .is_none() | ||||||
|         assert!(target_relay |         ); | ||||||
|  |         assert!( | ||||||
|  |             target_relay | ||||||
|                 .error(&[other_dep.clone(), second_dep.clone(), target_relay.clone()]) |                 .error(&[other_dep.clone(), second_dep.clone(), target_relay.clone()]) | ||||||
|             .is_none()); |                 .is_none() | ||||||
|  |         ); | ||||||
|  |  | ||||||
|         // self loop |         // self loop | ||||||
|         let mut self_loop = DeviceRelay { |         let mut self_loop = DeviceRelay { | ||||||
|   | |||||||
| @@ -4,7 +4,7 @@ use crate::devices::device::{ | |||||||
|     Device, DeviceGeneralInfo, DeviceId, DeviceInfo, DeviceRelay, DeviceRelayID, |     Device, DeviceGeneralInfo, DeviceId, DeviceInfo, DeviceRelay, DeviceRelayID, | ||||||
| }; | }; | ||||||
| use crate::utils::time_utils::time_secs; | use crate::utils::time_utils::time_secs; | ||||||
| use openssl::x509::{X509Req, X509}; | use openssl::x509::{X509, X509Req}; | ||||||
| use std::collections::HashMap; | use std::collections::HashMap; | ||||||
|  |  | ||||||
| #[derive(thiserror::Error, Debug)] | #[derive(thiserror::Error, Debug)] | ||||||
|   | |||||||
| @@ -1,5 +1,5 @@ | |||||||
| use crate::app_config::{AppConfig, ConsumptionBackend}; | use crate::app_config::{AppConfig, ConsumptionBackend}; | ||||||
| use rand::{thread_rng, Rng}; | use rand::{Rng, rng}; | ||||||
| use std::num::ParseIntError; | use std::num::ParseIntError; | ||||||
| use std::path::Path; | use std::path::Path; | ||||||
|  |  | ||||||
| @@ -49,7 +49,7 @@ pub async fn get_curr_consumption() -> anyhow::Result<EnergyConsumption> { | |||||||
|     match backend { |     match backend { | ||||||
|         ConsumptionBackend::Constant { value } => Ok(*value), |         ConsumptionBackend::Constant { value } => Ok(*value), | ||||||
|  |  | ||||||
|         ConsumptionBackend::Random { min, max } => Ok(thread_rng().gen_range(*min..*max)), |         ConsumptionBackend::Random { min, max } => Ok(rng().random_range(*min..*max)), | ||||||
|  |  | ||||||
|         ConsumptionBackend::File { path } => { |         ConsumptionBackend::File { path } => { | ||||||
|             let path = Path::new(path); |             let path = Path::new(path); | ||||||
|   | |||||||
| @@ -1,7 +1,7 @@ | |||||||
| use std::collections::HashMap; | use std::collections::HashMap; | ||||||
|  |  | ||||||
| use crate::app_config::AppConfig; | use crate::app_config::AppConfig; | ||||||
| use prettytable::{row, Table}; | use prettytable::{Table, row}; | ||||||
|  |  | ||||||
| use crate::constants; | use crate::constants; | ||||||
| use crate::devices::device::{Device, DeviceId, DeviceRelay, DeviceRelayID}; | use crate::devices::device::{Device, DeviceId, DeviceRelay, DeviceRelayID}; | ||||||
| @@ -289,7 +289,11 @@ impl EnergyEngine { | |||||||
|                     continue; |                     continue; | ||||||
|                 } |                 } | ||||||
|  |  | ||||||
|                 log::info!("Forcefully turn on relay {} to catch up running constraints (only {}s this day)", r.name, total_runtime); |                 log::info!( | ||||||
|  |                     "Forcefully turn on relay {} to catch up running constraints (only {}s this day)", | ||||||
|  |                     r.name, | ||||||
|  |                     total_runtime | ||||||
|  |                 ); | ||||||
|                 new_relays_state.get_mut(&r.id).unwrap().on = true; |                 new_relays_state.get_mut(&r.id).unwrap().on = true; | ||||||
|             } |             } | ||||||
|         } |         } | ||||||
|   | |||||||
| @@ -1,7 +1,7 @@ | |||||||
| use crate::app_config::AppConfig; | use crate::app_config::AppConfig; | ||||||
| use crate::devices::device::{DeviceRelay, DeviceRelayID}; | use crate::devices::device::{DeviceRelay, DeviceRelayID}; | ||||||
| use crate::utils::files_utils; | use crate::utils::files_utils; | ||||||
| use crate::utils::time_utils::{day_number, time_start_of_day}; | use crate::utils::time_utils::{day_number, time_secs, time_start_of_day}; | ||||||
|  |  | ||||||
| const TIME_INTERVAL: usize = 30; | const TIME_INTERVAL: usize = 30; | ||||||
|  |  | ||||||
| @@ -128,15 +128,26 @@ pub fn relay_total_runtime_adjusted(relay: &DeviceRelay) -> usize { | |||||||
|         .unwrap_or(0); |         .unwrap_or(0); | ||||||
|  |  | ||||||
|     let time_start_day = time_start_of_day().unwrap_or(1726696800); |     let time_start_day = time_start_of_day().unwrap_or(1726696800); | ||||||
|  |  | ||||||
|  |     // Check if we have reached reset_time today yet or not | ||||||
|  |     if time_start_day + reset_time as u64 <= time_secs() { | ||||||
|         let start_time = time_start_day + reset_time as u64; |         let start_time = time_start_day + reset_time as u64; | ||||||
|         let end_time = time_start_day + 3600 * 24 + reset_time as u64; |         let end_time = time_start_day + 3600 * 24 + reset_time as u64; | ||||||
|         relay_total_runtime(relay.id, start_time, end_time).unwrap_or(3600 * 24) |         relay_total_runtime(relay.id, start_time, end_time).unwrap_or(3600 * 24) | ||||||
|     } |     } | ||||||
|  |     // If we have not reached reset time yet, we need to focus on previous day | ||||||
|  |     else { | ||||||
|  |         let time_start_yesterday = time_start_day - 3600 * 24; | ||||||
|  |         let start_time = time_start_yesterday + reset_time as u64; | ||||||
|  |         let end_time = time_start_day + reset_time as u64; | ||||||
|  |         relay_total_runtime(relay.id, start_time, end_time).unwrap_or(3600 * 24) | ||||||
|  |     } | ||||||
|  | } | ||||||
|  |  | ||||||
| #[cfg(test)] | #[cfg(test)] | ||||||
| mod tests { | mod tests { | ||||||
|     use crate::devices::device::DeviceRelayID; |     use crate::devices::device::DeviceRelayID; | ||||||
|     use crate::energy::relay_state_history::{relay_total_runtime, RelayStateHistory}; |     use crate::energy::relay_state_history::{RelayStateHistory, relay_total_runtime}; | ||||||
|  |  | ||||||
|     #[test] |     #[test] | ||||||
|     fn test_relay_state_history() { |     fn test_relay_state_history() { | ||||||
|   | |||||||
| @@ -35,7 +35,7 @@ pub fn save_log( | |||||||
|         .as_bytes(), |         .as_bytes(), | ||||||
|     )?; |     )?; | ||||||
|     file.flush()?; |     file.flush()?; | ||||||
|     file.unlock()?; |     fs4::fs_std::FileExt::unlock(&file)?; | ||||||
|  |  | ||||||
|     Ok(()) |     Ok(()) | ||||||
| } | } | ||||||
|   | |||||||
| @@ -5,7 +5,7 @@ use central_backend::energy::energy_actor::EnergyActor; | |||||||
| use central_backend::server::servers; | use central_backend::server::servers; | ||||||
| use central_backend::utils::files_utils::create_directory_if_missing; | use central_backend::utils::files_utils::create_directory_if_missing; | ||||||
| use futures::future; | use futures::future; | ||||||
| use tokio_schedule::{every, Job}; | use tokio_schedule::{Job, every}; | ||||||
|  |  | ||||||
| #[actix_web::main] | #[actix_web::main] | ||||||
| async fn main() -> std::io::Result<()> { | async fn main() -> std::io::Result<()> { | ||||||
|   | |||||||
| @@ -1,5 +1,5 @@ | |||||||
| use actix_identity::Identity; | use actix_identity::Identity; | ||||||
| use std::future::{ready, Ready}; | use std::future::{Ready, ready}; | ||||||
| use std::rc::Rc; | use std::rc::Rc; | ||||||
|  |  | ||||||
| use crate::app_config::AppConfig; | use crate::app_config::AppConfig; | ||||||
| @@ -7,8 +7,8 @@ use crate::constants; | |||||||
| use actix_web::body::EitherBody; | use actix_web::body::EitherBody; | ||||||
| use actix_web::dev::Payload; | use actix_web::dev::Payload; | ||||||
| use actix_web::{ | use actix_web::{ | ||||||
|     dev::{forward_ready, Service, ServiceRequest, ServiceResponse, Transform}, |  | ||||||
|     Error, FromRequest, HttpResponse, |     Error, FromRequest, HttpResponse, | ||||||
|  |     dev::{Service, ServiceRequest, ServiceResponse, Transform, forward_ready}, | ||||||
| }; | }; | ||||||
| use futures_util::future::LocalBoxFuture; | use futures_util::future::LocalBoxFuture; | ||||||
|  |  | ||||||
|   | |||||||
| @@ -1,6 +1,6 @@ | |||||||
|  | use actix_web::HttpResponse; | ||||||
| use actix_web::body::BoxBody; | use actix_web::body::BoxBody; | ||||||
| use actix_web::http::StatusCode; | use actix_web::http::StatusCode; | ||||||
| use actix_web::HttpResponse; |  | ||||||
| use std::error::Error; | use std::error::Error; | ||||||
| use std::fmt::{Display, Formatter}; | use std::fmt::{Display, Formatter}; | ||||||
| use std::io::ErrorKind; | use std::io::ErrorKind; | ||||||
|   | |||||||
| @@ -1,9 +1,9 @@ | |||||||
| use crate::logs::logs_manager; | use crate::logs::logs_manager; | ||||||
| use crate::logs::severity::LogSeverity; | use crate::logs::severity::LogSeverity; | ||||||
|  | use crate::server::WebEnergyActor; | ||||||
| use crate::server::custom_error::HttpResult; | use crate::server::custom_error::HttpResult; | ||||||
| use crate::server::devices_api::jwt_parser::JWTRequest; | use crate::server::devices_api::jwt_parser::JWTRequest; | ||||||
| use crate::server::WebEnergyActor; | use actix_web::{HttpResponse, web}; | ||||||
| use actix_web::{web, HttpResponse}; |  | ||||||
|  |  | ||||||
| #[derive(Debug, serde::Deserialize)] | #[derive(Debug, serde::Deserialize)] | ||||||
| pub struct LogRequest { | pub struct LogRequest { | ||||||
|   | |||||||
| @@ -1,7 +1,7 @@ | |||||||
| use crate::ota::ota_manager; | use crate::ota::ota_manager; | ||||||
| use crate::ota::ota_update::OTAPlatform; | use crate::ota::ota_update::OTAPlatform; | ||||||
| use crate::server::custom_error::HttpResult; | use crate::server::custom_error::HttpResult; | ||||||
| use actix_web::{web, HttpResponse}; | use actix_web::{HttpResponse, web}; | ||||||
|  |  | ||||||
| #[derive(serde::Deserialize)] | #[derive(serde::Deserialize)] | ||||||
| pub struct FirmwarePath { | pub struct FirmwarePath { | ||||||
|   | |||||||
| @@ -4,10 +4,10 @@ use crate::energy::energy_actor; | |||||||
| use crate::energy::energy_actor::RelaySyncStatus; | use crate::energy::energy_actor::RelaySyncStatus; | ||||||
| use crate::ota::ota_manager; | use crate::ota::ota_manager; | ||||||
| use crate::ota::ota_update::OTAPlatform; | use crate::ota::ota_update::OTAPlatform; | ||||||
|  | use crate::server::WebEnergyActor; | ||||||
| use crate::server::custom_error::HttpResult; | use crate::server::custom_error::HttpResult; | ||||||
| use crate::server::devices_api::jwt_parser::JWTRequest; | use crate::server::devices_api::jwt_parser::JWTRequest; | ||||||
| use crate::server::WebEnergyActor; | use actix_web::{HttpResponse, web}; | ||||||
| use actix_web::{web, HttpResponse}; |  | ||||||
| use openssl::nid::Nid; | use openssl::nid::Nid; | ||||||
| use openssl::x509::X509Req; | use openssl::x509::X509Req; | ||||||
| use std::str::FromStr; | use std::str::FromStr; | ||||||
|   | |||||||
| @@ -10,14 +10,14 @@ use crate::server::unsecure_server::*; | |||||||
| use crate::server::web_api::*; | use crate::server::web_api::*; | ||||||
| use crate::server::web_app_controller; | use crate::server::web_app_controller; | ||||||
| use actix_cors::Cors; | use actix_cors::Cors; | ||||||
| use actix_identity::config::LogoutBehaviour; |  | ||||||
| use actix_identity::IdentityMiddleware; | use actix_identity::IdentityMiddleware; | ||||||
|  | use actix_identity::config::LogoutBehaviour; | ||||||
| use actix_remote_ip::RemoteIPConfig; | use actix_remote_ip::RemoteIPConfig; | ||||||
| use actix_session::storage::CookieSessionStore; |  | ||||||
| use actix_session::SessionMiddleware; | use actix_session::SessionMiddleware; | ||||||
|  | use actix_session::storage::CookieSessionStore; | ||||||
| use actix_web::cookie::{Key, SameSite}; | use actix_web::cookie::{Key, SameSite}; | ||||||
| use actix_web::middleware::Logger; | use actix_web::middleware::Logger; | ||||||
| use actix_web::{web, App, HttpServer}; | use actix_web::{App, HttpServer, web}; | ||||||
| use openssl::ssl::{SslAcceptor, SslMethod}; | use openssl::ssl::{SslAcceptor, SslMethod}; | ||||||
| use std::time::Duration; | use std::time::Duration; | ||||||
|  |  | ||||||
|   | |||||||
| @@ -1,6 +1,6 @@ | |||||||
| use crate::app_config::AppConfig; | use crate::app_config::AppConfig; | ||||||
| use crate::server::custom_error::HttpResult; | use crate::server::custom_error::HttpResult; | ||||||
| use actix_web::{web, HttpResponse}; | use actix_web::{HttpResponse, web}; | ||||||
|  |  | ||||||
| #[derive(serde::Deserialize)] | #[derive(serde::Deserialize)] | ||||||
| pub struct ServeCRLPath { | pub struct ServeCRLPath { | ||||||
|   | |||||||
| @@ -1,8 +1,8 @@ | |||||||
| use crate::devices::device::DeviceRelayID; | use crate::devices::device::DeviceRelayID; | ||||||
| use crate::energy::{energy_actor, relay_state_history}; | use crate::energy::{energy_actor, relay_state_history}; | ||||||
| use crate::server::custom_error::HttpResult; |  | ||||||
| use crate::server::WebEnergyActor; | use crate::server::WebEnergyActor; | ||||||
| use actix_web::{web, HttpResponse}; | use crate::server::custom_error::HttpResult; | ||||||
|  | use actix_web::{HttpResponse, web}; | ||||||
|  |  | ||||||
| #[derive(serde::Deserialize)] | #[derive(serde::Deserialize)] | ||||||
| pub struct LegacyStateRelay { | pub struct LegacyStateRelay { | ||||||
|   | |||||||
| @@ -2,7 +2,7 @@ use crate::app_config::AppConfig; | |||||||
| use crate::server::custom_error::HttpResult; | use crate::server::custom_error::HttpResult; | ||||||
| use actix_identity::Identity; | use actix_identity::Identity; | ||||||
| use actix_remote_ip::RemoteIP; | use actix_remote_ip::RemoteIP; | ||||||
| use actix_web::{web, HttpMessage, HttpRequest, HttpResponse}; | use actix_web::{HttpMessage, HttpRequest, HttpResponse, web}; | ||||||
|  |  | ||||||
| #[derive(serde::Deserialize)] | #[derive(serde::Deserialize)] | ||||||
| pub struct AuthRequest { | pub struct AuthRequest { | ||||||
| @@ -17,11 +17,11 @@ pub async fn password_auth( | |||||||
|     remote_ip: RemoteIP, |     remote_ip: RemoteIP, | ||||||
| ) -> HttpResult { | ) -> HttpResult { | ||||||
|     if r.user != AppConfig::get().admin_username || r.password != AppConfig::get().admin_password { |     if r.user != AppConfig::get().admin_username || r.password != AppConfig::get().admin_password { | ||||||
|         log::error!("Failed login attempt from {}!", remote_ip.0.to_string()); |         log::error!("Failed login attempt from {}!", remote_ip.0); | ||||||
|         return Ok(HttpResponse::Unauthorized().json("Invalid credentials!")); |         return Ok(HttpResponse::Unauthorized().json("Invalid credentials!")); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     log::info!("Successful login attempt from {}!", remote_ip.0.to_string()); |     log::info!("Successful login attempt from {}!", remote_ip.0); | ||||||
|     Identity::login(&request.extensions(), r.user.to_string())?; |     Identity::login(&request.extensions(), r.user.to_string())?; | ||||||
|     Ok(HttpResponse::Ok().finish()) |     Ok(HttpResponse::Ok().finish()) | ||||||
| } | } | ||||||
|   | |||||||
| @@ -1,8 +1,8 @@ | |||||||
| use crate::devices::device::{DeviceGeneralInfo, DeviceId}; | use crate::devices::device::{DeviceGeneralInfo, DeviceId}; | ||||||
| use crate::energy::energy_actor; | use crate::energy::energy_actor; | ||||||
| use crate::server::custom_error::HttpResult; |  | ||||||
| use crate::server::WebEnergyActor; | use crate::server::WebEnergyActor; | ||||||
| use actix_web::{web, HttpResponse}; | use crate::server::custom_error::HttpResult; | ||||||
|  | use actix_web::{HttpResponse, web}; | ||||||
|  |  | ||||||
| /// Get the list of pending (not accepted yet) devices | /// Get the list of pending (not accepted yet) devices | ||||||
| pub async fn list_pending(actor: WebEnergyActor) -> HttpResult { | pub async fn list_pending(actor: WebEnergyActor) -> HttpResult { | ||||||
|   | |||||||
| @@ -2,8 +2,8 @@ use crate::app_config::ConsumptionHistoryType; | |||||||
| use crate::energy::consumption::EnergyConsumption; | use crate::energy::consumption::EnergyConsumption; | ||||||
| use crate::energy::consumption_history_file::ConsumptionHistoryFile; | use crate::energy::consumption_history_file::ConsumptionHistoryFile; | ||||||
| use crate::energy::{consumption, energy_actor}; | use crate::energy::{consumption, energy_actor}; | ||||||
| use crate::server::custom_error::HttpResult; |  | ||||||
| use crate::server::WebEnergyActor; | use crate::server::WebEnergyActor; | ||||||
|  | use crate::server::custom_error::HttpResult; | ||||||
| use crate::utils::time_utils::time_secs; | use crate::utils::time_utils::time_secs; | ||||||
| use actix_web::HttpResponse; | use actix_web::HttpResponse; | ||||||
|  |  | ||||||
|   | |||||||
| @@ -3,7 +3,7 @@ use crate::logs::logs_manager; | |||||||
| use crate::logs::severity::LogSeverity; | use crate::logs::severity::LogSeverity; | ||||||
| use crate::server::custom_error::HttpResult; | use crate::server::custom_error::HttpResult; | ||||||
| use crate::utils::time_utils::curr_day_number; | use crate::utils::time_utils::curr_day_number; | ||||||
| use actix_web::{web, HttpResponse}; | use actix_web::{HttpResponse, web}; | ||||||
|  |  | ||||||
| #[derive(serde::Deserialize)] | #[derive(serde::Deserialize)] | ||||||
| pub struct LogRequest { | pub struct LogRequest { | ||||||
|   | |||||||
| @@ -3,11 +3,11 @@ use crate::devices::device::DeviceId; | |||||||
| use crate::energy::energy_actor; | use crate::energy::energy_actor; | ||||||
| use crate::ota::ota_manager; | use crate::ota::ota_manager; | ||||||
| use crate::ota::ota_update::OTAPlatform; | use crate::ota::ota_update::OTAPlatform; | ||||||
| use crate::server::custom_error::HttpResult; |  | ||||||
| use crate::server::WebEnergyActor; | use crate::server::WebEnergyActor; | ||||||
| use actix_multipart::form::tempfile::TempFile; | use crate::server::custom_error::HttpResult; | ||||||
| use actix_multipart::form::MultipartForm; | use actix_multipart::form::MultipartForm; | ||||||
| use actix_web::{web, HttpResponse}; | use actix_multipart::form::tempfile::TempFile; | ||||||
|  | use actix_web::{HttpResponse, web}; | ||||||
|  |  | ||||||
| pub async fn supported_platforms() -> HttpResult { | pub async fn supported_platforms() -> HttpResult { | ||||||
|     Ok(HttpResponse::Ok().json(OTAPlatform::supported_platforms())) |     Ok(HttpResponse::Ok().json(OTAPlatform::supported_platforms())) | ||||||
|   | |||||||
| @@ -1,8 +1,8 @@ | |||||||
| use crate::devices::device::{DeviceId, DeviceRelay, DeviceRelayID}; | use crate::devices::device::{DeviceId, DeviceRelay, DeviceRelayID}; | ||||||
| use crate::energy::energy_actor; | use crate::energy::energy_actor; | ||||||
| use crate::server::custom_error::HttpResult; |  | ||||||
| use crate::server::WebEnergyActor; | use crate::server::WebEnergyActor; | ||||||
| use actix_web::{web, HttpResponse}; | use crate::server::custom_error::HttpResult; | ||||||
|  | use actix_web::{HttpResponse, web}; | ||||||
|  |  | ||||||
| /// Get the full list of relays | /// Get the full list of relays | ||||||
| pub async fn get_list(actor: WebEnergyActor) -> HttpResult { | pub async fn get_list(actor: WebEnergyActor) -> HttpResult { | ||||||
|   | |||||||
| @@ -19,7 +19,7 @@ mod serve_static_debug { | |||||||
|  |  | ||||||
| #[cfg(not(debug_assertions))] | #[cfg(not(debug_assertions))] | ||||||
| mod serve_static_release { | mod serve_static_release { | ||||||
|     use actix_web::{web, HttpResponse, Responder}; |     use actix_web::{HttpResponse, Responder, web}; | ||||||
|     use rust_embed::RustEmbed; |     use rust_embed::RustEmbed; | ||||||
|  |  | ||||||
|     #[derive(RustEmbed)] |     #[derive(RustEmbed)] | ||||||
|   | |||||||
| @@ -1,7 +1,7 @@ | |||||||
| use chrono::prelude::*; | use chrono::prelude::*; | ||||||
| use std::time::{SystemTime, UNIX_EPOCH}; | use std::time::{SystemTime, UNIX_EPOCH}; | ||||||
|  |  | ||||||
| /// Get the current time since epoch | /// Get the current time since epoch, in seconds | ||||||
| pub fn time_secs() -> u64 { | pub fn time_secs() -> u64 { | ||||||
|     SystemTime::now() |     SystemTime::now() | ||||||
|         .duration_since(UNIX_EPOCH) |         .duration_since(UNIX_EPOCH) | ||||||
|   | |||||||
							
								
								
									
										28
									
								
								central_frontend/eslint.config.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										28
									
								
								central_frontend/eslint.config.js
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,28 @@ | |||||||
|  | import js from '@eslint/js' | ||||||
|  | import globals from 'globals' | ||||||
|  | import reactHooks from 'eslint-plugin-react-hooks' | ||||||
|  | import reactRefresh from 'eslint-plugin-react-refresh' | ||||||
|  | import tseslint from 'typescript-eslint' | ||||||
|  |  | ||||||
|  | export default tseslint.config( | ||||||
|  |   { ignores: ['dist'] }, | ||||||
|  |   { | ||||||
|  |     extends: [js.configs.recommended, ...tseslint.configs.recommended], | ||||||
|  |     files: ['**/*.{ts,tsx}'], | ||||||
|  |     languageOptions: { | ||||||
|  |       ecmaVersion: 2020, | ||||||
|  |       globals: globals.browser, | ||||||
|  |     }, | ||||||
|  |     plugins: { | ||||||
|  |       'react-hooks': reactHooks, | ||||||
|  |       'react-refresh': reactRefresh, | ||||||
|  |     }, | ||||||
|  |     rules: { | ||||||
|  |       ...reactHooks.configs.recommended.rules, | ||||||
|  |       'react-refresh/only-export-components': [ | ||||||
|  |         'warn', | ||||||
|  |         { allowConstantExport: true }, | ||||||
|  |       ], | ||||||
|  |     }, | ||||||
|  |   }, | ||||||
|  | ) | ||||||
							
								
								
									
										2095
									
								
								central_frontend/package-lock.json
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										2095
									
								
								central_frontend/package-lock.json
									
									
									
										generated
									
									
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							| @@ -6,38 +6,40 @@ | |||||||
|   "scripts": { |   "scripts": { | ||||||
|     "dev": "vite", |     "dev": "vite", | ||||||
|     "build": "tsc -b && vite build", |     "build": "tsc -b && vite build", | ||||||
|     "lint": "eslint . --ext ts,tsx --report-unused-disable-directives --max-warnings 0", |     "lint": "eslint .", | ||||||
|     "preview": "vite preview" |     "preview": "vite preview" | ||||||
|   }, |   }, | ||||||
|   "dependencies": { |   "dependencies": { | ||||||
|     "@emotion/react": "^11.13.3", |     "@emotion/react": "^11.14.0", | ||||||
|     "@emotion/styled": "^11.13.0", |     "@emotion/styled": "^11.14.0", | ||||||
|     "@fontsource/roboto": "^5.1.0", |     "@fontsource/roboto": "^5.2.5", | ||||||
|     "@mdi/js": "^7.4.47", |     "@mdi/js": "^7.4.47", | ||||||
|     "@mdi/react": "^1.6.1", |     "@mdi/react": "^1.6.1", | ||||||
|     "@mui/icons-material": "^6.1.4", |     "@mui/icons-material": "^7.0.2", | ||||||
|     "@mui/material": "^6.1.4", |     "@mui/material": "^7.0.2", | ||||||
|     "@mui/x-charts": "^7.21.0", |     "@mui/x-charts": "^7.29.1", | ||||||
|     "@mui/x-date-pickers": "^7.21.0", |     "@mui/x-date-pickers": "^7.29.2", | ||||||
|     "@types/semver": "^7.5.8", |  | ||||||
|     "date-and-time": "^3.6.0", |     "date-and-time": "^3.6.0", | ||||||
|     "dayjs": "^1.11.13", |     "dayjs": "^1.11.13", | ||||||
|     "filesize": "^10.1.6", |     "filesize": "^10.1.6", | ||||||
|     "react": "^18.3.1", |     "react": "^19.0.0", | ||||||
|     "react-dom": "^18.3.1", |     "react-dom": "^19.0.0", | ||||||
|     "react-router-dom": "^7.0.0", |     "react-router-dom": "^7.4.0", | ||||||
|     "semver": "^7.6.3" |     "semver": "^7.7.1" | ||||||
|   }, |   }, | ||||||
|   "devDependencies": { |   "devDependencies": { | ||||||
|     "@types/react": "^18.3.11", |     "@types/react": "^19.0.0", | ||||||
|     "@types/react-dom": "^18.3.1", |     "@types/react-dom": "^19.0.4", | ||||||
|     "@typescript-eslint/eslint-plugin": "^8.15.0", |     "@types/semver": "^7.7.0", | ||||||
|     "@typescript-eslint/parser": "^8.10.0", |     "@typescript-eslint/eslint-plugin": "^8.31.1", | ||||||
|     "@vitejs/plugin-react": "^4.3.2", |     "@typescript-eslint/parser": "^8.31.1", | ||||||
|     "eslint": "^9.0.0", |     "@vitejs/plugin-react": "^4.4.1", | ||||||
|     "eslint-plugin-react-hooks": "^5.0.0", |     "eslint": "^9.23.0", | ||||||
|     "eslint-plugin-react-refresh": "^0.4.12", |     "eslint-plugin-react-hooks": "^5.2.0", | ||||||
|     "typescript": "^5.6.3", |     "eslint-plugin-react-refresh": "^0.4.20", | ||||||
|     "vite": "^5.4.9" |     "globals": "^16.0.0", | ||||||
|  |     "typescript": "^5.8.3", | ||||||
|  |     "typescript-eslint": "^8.24.1", | ||||||
|  |     "vite": "^6.2.3" | ||||||
|   } |   } | ||||||
| } | } | ||||||
|   | |||||||
| @@ -6,7 +6,7 @@ import { | |||||||
|   DialogTitle, |   DialogTitle, | ||||||
|   Typography, |   Typography, | ||||||
| } from "@mui/material"; | } from "@mui/material"; | ||||||
| import Grid from "@mui/material/Grid2"; | import Grid from "@mui/material/Grid"; | ||||||
| import { TimePicker } from "@mui/x-date-pickers"; | import { TimePicker } from "@mui/x-date-pickers"; | ||||||
| import React from "react"; | import React from "react"; | ||||||
| import { Device, DeviceRelay } from "../api/DeviceApi"; | import { Device, DeviceRelay } from "../api/DeviceApi"; | ||||||
|   | |||||||
| @@ -1,7 +1,7 @@ | |||||||
| import DeleteIcon from "@mui/icons-material/Delete"; | import DeleteIcon from "@mui/icons-material/Delete"; | ||||||
| import RefreshIcon from "@mui/icons-material/Refresh"; | import RefreshIcon from "@mui/icons-material/Refresh"; | ||||||
| import { IconButton, Tooltip } from "@mui/material"; | import { IconButton, Tooltip } from "@mui/material"; | ||||||
| import Grid from "@mui/material/Grid2"; | import Grid from "@mui/material/Grid"; | ||||||
| import React from "react"; | import React from "react"; | ||||||
| import { useNavigate, useParams } from "react-router-dom"; | import { useNavigate, useParams } from "react-router-dom"; | ||||||
| import { Device, DeviceApi } from "../../api/DeviceApi"; | import { Device, DeviceApi } from "../../api/DeviceApi"; | ||||||
|   | |||||||
| @@ -1,6 +1,6 @@ | |||||||
| import { Typography } from "@mui/material"; | import { Typography } from "@mui/material"; | ||||||
| import { CurrConsumptionWidget } from "./HomeRoute/CurrConsumptionWidget"; | import { CurrConsumptionWidget } from "./HomeRoute/CurrConsumptionWidget"; | ||||||
| import Grid from "@mui/material/Grid2"; | import Grid from "@mui/material/Grid"; | ||||||
| import { CachedConsumptionWidget } from "./HomeRoute/CachedConsumptionWidget"; | import { CachedConsumptionWidget } from "./HomeRoute/CachedConsumptionWidget"; | ||||||
| import { RelayConsumptionWidget } from "./HomeRoute/RelayConsumptionWidget"; | import { RelayConsumptionWidget } from "./HomeRoute/RelayConsumptionWidget"; | ||||||
| import { RelaysListRoute } from "./RelaysListRoute"; | import { RelaysListRoute } from "./RelaysListRoute"; | ||||||
|   | |||||||
| @@ -11,7 +11,7 @@ import Typography from "@mui/material/Typography"; | |||||||
| import * as React from "react"; | import * as React from "react"; | ||||||
| import { useLoadingMessage } from "../hooks/context_providers/LoadingMessageProvider"; | import { useLoadingMessage } from "../hooks/context_providers/LoadingMessageProvider"; | ||||||
| import { AuthApi } from "../api/AuthApi"; | import { AuthApi } from "../api/AuthApi"; | ||||||
| import Grid from "@mui/material/Grid2"; | import Grid from "@mui/material/Grid"; | ||||||
|  |  | ||||||
| function Copyright(props: any) { | function Copyright(props: any) { | ||||||
|   return ( |   return ( | ||||||
|   | |||||||
| @@ -1,6 +1,5 @@ | |||||||
| { | { | ||||||
|   "compilerOptions": { |   "compilerOptions": { | ||||||
|     "composite": true, |  | ||||||
|     "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.app.tsbuildinfo", |     "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.app.tsbuildinfo", | ||||||
|     "target": "ES2020", |     "target": "ES2020", | ||||||
|     "useDefineForClassFields": true, |     "useDefineForClassFields": true, | ||||||
| @@ -11,7 +10,6 @@ | |||||||
|     /* Bundler mode */ |     /* Bundler mode */ | ||||||
|     "moduleResolution": "bundler", |     "moduleResolution": "bundler", | ||||||
|     "allowImportingTsExtensions": true, |     "allowImportingTsExtensions": true, | ||||||
|     "resolveJsonModule": true, |  | ||||||
|     "isolatedModules": true, |     "isolatedModules": true, | ||||||
|     "moduleDetection": "force", |     "moduleDetection": "force", | ||||||
|     "noEmit": true, |     "noEmit": true, | ||||||
| @@ -21,7 +19,8 @@ | |||||||
|     "strict": true, |     "strict": true, | ||||||
|     "noUnusedLocals": true, |     "noUnusedLocals": true, | ||||||
|     "noUnusedParameters": true, |     "noUnusedParameters": true, | ||||||
|     "noFallthroughCasesInSwitch": true |     "noFallthroughCasesInSwitch": true, | ||||||
|  |     "noUncheckedSideEffectImports": true | ||||||
|   }, |   }, | ||||||
|   "include": ["src"] |   "include": ["src"] | ||||||
| } | } | ||||||
|   | |||||||
| @@ -1,11 +1,7 @@ | |||||||
| { | { | ||||||
|   "files": [], |   "files": [], | ||||||
|   "references": [ |   "references": [ | ||||||
|     { |     { "path": "./tsconfig.app.json" }, | ||||||
|       "path": "./tsconfig.app.json" |     { "path": "./tsconfig.node.json" } | ||||||
|     }, |  | ||||||
|     { |  | ||||||
|       "path": "./tsconfig.node.json" |  | ||||||
|     } |  | ||||||
|   ] |   ] | ||||||
| } | } | ||||||
|   | |||||||
| @@ -1,13 +1,24 @@ | |||||||
| { | { | ||||||
|   "compilerOptions": { |   "compilerOptions": { | ||||||
|     "composite": true, |  | ||||||
|     "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.node.tsbuildinfo", |     "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.node.tsbuildinfo", | ||||||
|     "skipLibCheck": true, |     "target": "ES2022", | ||||||
|  |     "lib": ["ES2023"], | ||||||
|     "module": "ESNext", |     "module": "ESNext", | ||||||
|  |     "skipLibCheck": true, | ||||||
|  |  | ||||||
|  |     /* Bundler mode */ | ||||||
|     "moduleResolution": "bundler", |     "moduleResolution": "bundler", | ||||||
|     "allowSyntheticDefaultImports": true, |     "allowImportingTsExtensions": true, | ||||||
|  |     "isolatedModules": true, | ||||||
|  |     "moduleDetection": "force", | ||||||
|  |     "noEmit": true, | ||||||
|  |  | ||||||
|  |     /* Linting */ | ||||||
|     "strict": true, |     "strict": true, | ||||||
|     "noEmit": true |     "noUnusedLocals": true, | ||||||
|  |     "noUnusedParameters": true, | ||||||
|  |     "noFallthroughCasesInSwitch": true, | ||||||
|  |     "noUncheckedSideEffectImports": true | ||||||
|   }, |   }, | ||||||
|   "include": ["vite.config.ts"] |   "include": ["vite.config.ts"] | ||||||
| } | } | ||||||
|   | |||||||
| @@ -1,7 +1,7 @@ | |||||||
| import { defineConfig } from 'vite' | import { defineConfig } from 'vite' | ||||||
| import react from '@vitejs/plugin-react' | import react from '@vitejs/plugin-react' | ||||||
|  |  | ||||||
| // https://vitejs.dev/config/ | // https://vite.dev/config/ | ||||||
| export default defineConfig({ | export default defineConfig({ | ||||||
|   plugins: [react()], |   plugins: [react()], | ||||||
| }) | }) | ||||||
|   | |||||||
							
								
								
									
										1502
									
								
								custom_consumption/Cargo.lock
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										1502
									
								
								custom_consumption/Cargo.lock
									
									
									
										generated
									
									
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							| @@ -1,12 +1,12 @@ | |||||||
| [package] | [package] | ||||||
| name = "custom_consumption" | name = "custom_consumption" | ||||||
| version = "0.1.0" | version = "0.1.0" | ||||||
| edition = "2021" | edition = "2024" | ||||||
|  |  | ||||||
| [dependencies] | [dependencies] | ||||||
| env_logger = "0.11.5" | env_logger = "0.11.8" | ||||||
| log = "0.4.22" | log = "0.4.27" | ||||||
| clap = { version = "4.5.18", features = ["derive", "env"] } | clap = { version = "4.5.37", features = ["derive", "env"] } | ||||||
| egui = "0.29.1" | egui = "0.31.1" | ||||||
| eframe = "0.29.1" | eframe = "0.31.1" | ||||||
| lazy_static = "1.5.0" | lazy_static = "1.5.0" | ||||||
|   | |||||||
| @@ -1,9 +1,3 @@ | |||||||
| { | { | ||||||
|   "$schema": "https://docs.renovatebot.com/renovate-schema.json", |   "extends": ["local>renovate/presets"] | ||||||
|   "packageRules": [ |  | ||||||
|     { |  | ||||||
|       "matchUpdateTypes": ["major", "minor", "patch"], |  | ||||||
|       "automerge": true |  | ||||||
|     } |  | ||||||
|   ] |  | ||||||
| } | } | ||||||
		Reference in New Issue
	
	Block a user