From 9c0fc5c61d768f80d4d5f9e3d8d2de606042725d Mon Sep 17 00:00:00 2001 From: stani Date: Sun, 16 Mar 2025 16:32:22 +0100 Subject: [PATCH] Added profile calculation --- CMakeLists.txt | 6 +- conan_provider.cmake | 679 ------------------------- src/Config.h | 4 + src/helper/CalculateProfile.cpp | 95 ++++ src/helper/CalculateProfile.h | 20 + src/helper/CsvBinary.cpp | 81 +-- src/helper/CsvBinary.h | 18 +- src/helper/StringOperations.cpp | 12 +- src/model/Building.cpp | 214 +++++--- src/model/Building.h | 7 +- src/model/Community.cpp | 55 +- src/model/Community.h | 31 +- src/services/Cost/BillCharge.h | 4 +- src/services/Cost/CalculateFinalSums.h | 4 +- src/services/Cost/CostPipeline.cpp | 21 +- src/services/Cost/TaxComponent.h | 8 +- src/services/CostHistory.h | 37 +- src/services/Surplus.cpp | 93 ++-- src/services/Surplus.h | 18 +- src/singelton/UsageProfile.cpp | 9 + src/singelton/UsageProfile.h | 49 ++ tests/helper/test_CsvBinary.cpp | 9 +- 22 files changed, 570 insertions(+), 904 deletions(-) delete mode 100644 conan_provider.cmake create mode 100644 src/helper/CalculateProfile.cpp create mode 100644 src/helper/CalculateProfile.h create mode 100644 src/singelton/UsageProfile.cpp create mode 100644 src/singelton/UsageProfile.h diff --git a/CMakeLists.txt b/CMakeLists.txt index f31a033..d5b8081 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,7 +1,7 @@ cmake_minimum_required(VERSION 3.30) project(Sim_C__) -set(CMAKE_CXX_STANDARD 26) +set(CMAKE_CXX_STANDARD 23) set(CMAKE_EXE_LINKER_FLAGS "-static") add_executable(Sim_C__ src/main.cpp @@ -42,6 +42,10 @@ add_executable(Sim_C__ src/helper/CsvBinary.cpp src/helper/CsvBinary.h tests/helper/test_CsvBinary.cpp + src/helper/CalculateProfile.cpp + src/helper/CalculateProfile.h + src/singelton/UsageProfile.cpp + src/singelton/UsageProfile.h ) find_package(doctest CONFIG REQUIRED) find_package(spdlog CONFIG REQUIRED) diff --git a/conan_provider.cmake b/conan_provider.cmake deleted file mode 100644 index 0d1eee6..0000000 --- a/conan_provider.cmake +++ /dev/null @@ -1,679 +0,0 @@ -# This file is managed by Conan, contents will be overwritten. -# To keep your changes, remove these comment lines, but the plugin won't be able to modify your requirements - -# The MIT License (MIT) -# -# Copyright (c) 2024 JFrog -# -# Permission is hereby granted, free of charge, to any person obtaining a copy -# of this software and associated documentation files (the "Software"), to deal -# in the Software without restriction, including without limitation the rights -# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -# copies of the Software, and to permit persons to whom the Software is -# furnished to do so, subject to the following conditions: -# -# The above copyright notice and this permission notice shall be included in all -# copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -# SOFTWARE. - -set(CONAN_MINIMUM_VERSION 2.0.5) - -# Create a new policy scope and set the minimum required cmake version so the -# features behind a policy setting like if(... IN_LIST ...) behaves as expected -# even if the parent project does not specify a minimum cmake version or a minimum -# version less than this module requires (e.g. 3.0) before the first project() call. -# (see: https://cmake.org/cmake/help/latest/variable/CMAKE_PROJECT_TOP_LEVEL_INCLUDES.html) -# -# The policy-affecting calls like cmake_policy(SET...) or `cmake_minimum_required` only -# affects the current policy scope, i.e. between the PUSH and POP in this case. -# -# https://cmake.org/cmake/help/book/mastering-cmake/chapter/Policies.html#the-policy-stack -cmake_policy(PUSH) -cmake_minimum_required(VERSION 3.24) - - -function(detect_os os os_api_level os_sdk os_subsystem os_version) - # it could be cross compilation - message(STATUS "CMake-Conan: cmake_system_name=${CMAKE_SYSTEM_NAME}") - if(CMAKE_SYSTEM_NAME AND NOT CMAKE_SYSTEM_NAME STREQUAL "Generic") - if(CMAKE_SYSTEM_NAME STREQUAL "Darwin") - set(${os} Macos PARENT_SCOPE) - elseif(CMAKE_SYSTEM_NAME STREQUAL "QNX") - set(${os} Neutrino PARENT_SCOPE) - elseif(CMAKE_SYSTEM_NAME STREQUAL "CYGWIN") - set(${os} Windows PARENT_SCOPE) - set(${os_subsystem} cygwin PARENT_SCOPE) - elseif(CMAKE_SYSTEM_NAME MATCHES "^MSYS") - set(${os} Windows PARENT_SCOPE) - set(${os_subsystem} msys2 PARENT_SCOPE) - else() - set(${os} ${CMAKE_SYSTEM_NAME} PARENT_SCOPE) - endif() - if(CMAKE_SYSTEM_NAME STREQUAL "Android") - if(DEFINED ANDROID_PLATFORM) - string(REGEX MATCH "[0-9]+" _os_api_level ${ANDROID_PLATFORM}) - elseif(DEFINED CMAKE_SYSTEM_VERSION) - set(_os_api_level ${CMAKE_SYSTEM_VERSION}) - endif() - message(STATUS "CMake-Conan: android api level=${_os_api_level}") - set(${os_api_level} ${_os_api_level} PARENT_SCOPE) - endif() - if(CMAKE_SYSTEM_NAME MATCHES "Darwin|iOS|tvOS|watchOS") - # CMAKE_OSX_SYSROOT contains the full path to the SDK for MakeFile/Ninja - # generators, but just has the original input string for Xcode. - if(NOT IS_DIRECTORY ${CMAKE_OSX_SYSROOT}) - set(_os_sdk ${CMAKE_OSX_SYSROOT}) - else() - if(CMAKE_OSX_SYSROOT MATCHES Simulator) - set(apple_platform_suffix simulator) - else() - set(apple_platform_suffix os) - endif() - if(CMAKE_OSX_SYSROOT MATCHES AppleTV) - set(_os_sdk "appletv${apple_platform_suffix}") - elseif(CMAKE_OSX_SYSROOT MATCHES iPhone) - set(_os_sdk "iphone${apple_platform_suffix}") - elseif(CMAKE_OSX_SYSROOT MATCHES Watch) - set(_os_sdk "watch${apple_platform_suffix}") - endif() - endif() - if(DEFINED os_sdk) - message(STATUS "CMake-Conan: cmake_osx_sysroot=${CMAKE_OSX_SYSROOT}") - set(${os_sdk} ${_os_sdk} PARENT_SCOPE) - endif() - if(DEFINED CMAKE_OSX_DEPLOYMENT_TARGET) - message(STATUS "CMake-Conan: cmake_osx_deployment_target=${CMAKE_OSX_DEPLOYMENT_TARGET}") - set(${os_version} ${CMAKE_OSX_DEPLOYMENT_TARGET} PARENT_SCOPE) - endif() - endif() - endif() -endfunction() - - -function(detect_arch arch) - # CMAKE_OSX_ARCHITECTURES can contain multiple architectures, but Conan only supports one. - # Therefore this code only finds one. If the recipes support multiple architectures, the - # build will work. Otherwise, there will be a linker error for the missing architecture(s). - if(DEFINED CMAKE_OSX_ARCHITECTURES) - string(REPLACE " " ";" apple_arch_list "${CMAKE_OSX_ARCHITECTURES}") - list(LENGTH apple_arch_list apple_arch_count) - if(apple_arch_count GREATER 1) - message(WARNING "CMake-Conan: Multiple architectures detected, this will only work if Conan recipe(s) produce fat binaries.") - endif() - endif() - if(CMAKE_SYSTEM_NAME MATCHES "Darwin|iOS|tvOS|watchOS" AND NOT CMAKE_OSX_ARCHITECTURES STREQUAL "") - set(host_arch ${CMAKE_OSX_ARCHITECTURES}) - elseif(MSVC) - set(host_arch ${CMAKE_CXX_COMPILER_ARCHITECTURE_ID}) - else() - set(host_arch ${CMAKE_SYSTEM_PROCESSOR}) - endif() - if(host_arch MATCHES "aarch64|arm64|ARM64") - set(_arch armv8) - elseif(host_arch MATCHES "armv7|armv7-a|armv7l|ARMV7") - set(_arch armv7) - elseif(host_arch MATCHES armv7s) - set(_arch armv7s) - elseif(host_arch MATCHES "i686|i386|X86") - set(_arch x86) - elseif(host_arch MATCHES "AMD64|amd64|x86_64|x64") - set(_arch x86_64) - endif() - message(STATUS "CMake-Conan: cmake_system_processor=${_arch}") - set(${arch} ${_arch} PARENT_SCOPE) -endfunction() - - -function(detect_cxx_standard cxx_standard) - set(${cxx_standard} ${CMAKE_CXX_STANDARD} PARENT_SCOPE) - if(CMAKE_CXX_EXTENSIONS) - set(${cxx_standard} "gnu${CMAKE_CXX_STANDARD}" PARENT_SCOPE) - endif() -endfunction() - - -macro(detect_gnu_libstdcxx) - # _conan_is_gnu_libstdcxx true if GNU libstdc++ - check_cxx_source_compiles(" - #include - #if !defined(__GLIBCXX__) && !defined(__GLIBCPP__) - static_assert(false); - #endif - int main(){}" _conan_is_gnu_libstdcxx) - - # _conan_gnu_libstdcxx_is_cxx11_abi true if C++11 ABI - check_cxx_source_compiles(" - #include - static_assert(sizeof(std::string) != sizeof(void*), \"using libstdc++\"); - int main () {}" _conan_gnu_libstdcxx_is_cxx11_abi) - - set(_conan_gnu_libstdcxx_suffix "") - if(_conan_gnu_libstdcxx_is_cxx11_abi) - set(_conan_gnu_libstdcxx_suffix "11") - endif() - unset (_conan_gnu_libstdcxx_is_cxx11_abi) -endmacro() - - -macro(detect_libcxx) - # _conan_is_libcxx true if LLVM libc++ - check_cxx_source_compiles(" - #include - #if !defined(_LIBCPP_VERSION) - static_assert(false); - #endif - int main(){}" _conan_is_libcxx) -endmacro() - - -function(detect_lib_cxx lib_cxx) - if(CMAKE_SYSTEM_NAME STREQUAL "Android") - message(STATUS "CMake-Conan: android_stl=${CMAKE_ANDROID_STL_TYPE}") - set(${lib_cxx} ${CMAKE_ANDROID_STL_TYPE} PARENT_SCOPE) - return() - endif() - - include(CheckCXXSourceCompiles) - - if(CMAKE_CXX_COMPILER_ID MATCHES "GNU") - detect_gnu_libstdcxx() - set(${lib_cxx} "libstdc++${_conan_gnu_libstdcxx_suffix}" PARENT_SCOPE) - elseif(CMAKE_CXX_COMPILER_ID MATCHES "AppleClang") - set(${lib_cxx} "libc++" PARENT_SCOPE) - elseif(CMAKE_CXX_COMPILER_ID MATCHES "Clang" AND NOT CMAKE_SYSTEM_NAME MATCHES "Windows") - # Check for libc++ - detect_libcxx() - if(_conan_is_libcxx) - set(${lib_cxx} "libc++" PARENT_SCOPE) - return() - endif() - - # Check for libstdc++ - detect_gnu_libstdcxx() - if(_conan_is_gnu_libstdcxx) - set(${lib_cxx} "libstdc++${_conan_gnu_libstdcxx_suffix}" PARENT_SCOPE) - return() - endif() - - # TODO: it would be an error if we reach this point - elseif(CMAKE_CXX_COMPILER_ID MATCHES "MSVC") - # Do nothing - compiler.runtime and compiler.runtime_type - # should be handled separately: https://github.com/conan-io/cmake-conan/pull/516 - return() - else() - # TODO: unable to determine, ask user to provide a full profile file instead - endif() -endfunction() - - -function(detect_compiler compiler compiler_version compiler_runtime compiler_runtime_type) - if(DEFINED CMAKE_CXX_COMPILER_ID) - set(_compiler ${CMAKE_CXX_COMPILER_ID}) - set(_compiler_version ${CMAKE_CXX_COMPILER_VERSION}) - else() - if(NOT DEFINED CMAKE_C_COMPILER_ID) - message(FATAL_ERROR "C or C++ compiler not defined") - endif() - set(_compiler ${CMAKE_C_COMPILER_ID}) - set(_compiler_version ${CMAKE_C_COMPILER_VERSION}) - endif() - - message(STATUS "CMake-Conan: CMake compiler=${_compiler}") - message(STATUS "CMake-Conan: CMake compiler version=${_compiler_version}") - - if(_compiler MATCHES MSVC) - set(_compiler "msvc") - string(SUBSTRING ${MSVC_VERSION} 0 3 _compiler_version) - # Configure compiler.runtime and compiler.runtime_type settings for MSVC - if(CMAKE_MSVC_RUNTIME_LIBRARY) - set(_msvc_runtime_library ${CMAKE_MSVC_RUNTIME_LIBRARY}) - else() - set(_msvc_runtime_library MultiThreaded$<$:Debug>DLL) # default value documented by CMake - endif() - - set(_KNOWN_MSVC_RUNTIME_VALUES "") - list(APPEND _KNOWN_MSVC_RUNTIME_VALUES MultiThreaded MultiThreadedDLL) - list(APPEND _KNOWN_MSVC_RUNTIME_VALUES MultiThreadedDebug MultiThreadedDebugDLL) - list(APPEND _KNOWN_MSVC_RUNTIME_VALUES MultiThreaded$<$:Debug> MultiThreaded$<$:Debug>DLL) - - # only accept the 6 possible values, otherwise we don't don't know to map this - if(NOT _msvc_runtime_library IN_LIST _KNOWN_MSVC_RUNTIME_VALUES) - message(FATAL_ERROR "CMake-Conan: unable to map MSVC runtime: ${_msvc_runtime_library} to Conan settings") - endif() - - # Runtime is "dynamic" in all cases if it ends in DLL - if(_msvc_runtime_library MATCHES ".*DLL$") - set(_compiler_runtime "dynamic") - else() - set(_compiler_runtime "static") - endif() - message(STATUS "CMake-Conan: CMake compiler.runtime=${_compiler_runtime}") - - # Only define compiler.runtime_type when explicitly requested - # If a generator expression is used, let Conan handle it conditional on build_type - if(NOT _msvc_runtime_library MATCHES ":Debug>") - if(_msvc_runtime_library MATCHES "Debug") - set(_compiler_runtime_type "Debug") - else() - set(_compiler_runtime_type "Release") - endif() - message(STATUS "CMake-Conan: CMake compiler.runtime_type=${_compiler_runtime_type}") - endif() - - unset(_KNOWN_MSVC_RUNTIME_VALUES) - - elseif(_compiler MATCHES AppleClang) - set(_compiler "apple-clang") - string(REPLACE "." ";" VERSION_LIST ${CMAKE_CXX_COMPILER_VERSION}) - list(GET VERSION_LIST 0 _compiler_version) - elseif(_compiler MATCHES Clang) - set(_compiler "clang") - string(REPLACE "." ";" VERSION_LIST ${CMAKE_CXX_COMPILER_VERSION}) - list(GET VERSION_LIST 0 _compiler_version) - elseif(_compiler MATCHES GNU) - set(_compiler "gcc") - string(REPLACE "." ";" VERSION_LIST ${CMAKE_CXX_COMPILER_VERSION}) - list(GET VERSION_LIST 0 _compiler_version) - endif() - - message(STATUS "CMake-Conan: [settings] compiler=${_compiler}") - message(STATUS "CMake-Conan: [settings] compiler.version=${_compiler_version}") - if (_compiler_runtime) - message(STATUS "CMake-Conan: [settings] compiler.runtime=${_compiler_runtime}") - endif() - if (_compiler_runtime_type) - message(STATUS "CMake-Conan: [settings] compiler.runtime_type=${_compiler_runtime_type}") - endif() - - set(${compiler} ${_compiler} PARENT_SCOPE) - set(${compiler_version} ${_compiler_version} PARENT_SCOPE) - set(${compiler_runtime} ${_compiler_runtime} PARENT_SCOPE) - set(${compiler_runtime_type} ${_compiler_runtime_type} PARENT_SCOPE) -endfunction() - - -function(detect_build_type build_type) - get_property(multiconfig_generator GLOBAL PROPERTY GENERATOR_IS_MULTI_CONFIG) - if(NOT multiconfig_generator) - # Only set when we know we are in a single-configuration generator - # Note: we may want to fail early if `CMAKE_BUILD_TYPE` is not defined - set(${build_type} ${CMAKE_BUILD_TYPE} PARENT_SCOPE) - endif() -endfunction() - - -macro(set_conan_compiler_if_appleclang lang command output_variable) - if(CMAKE_${lang}_COMPILER_ID STREQUAL "AppleClang") - execute_process(COMMAND xcrun --find ${command} - OUTPUT_VARIABLE _xcrun_out OUTPUT_STRIP_TRAILING_WHITESPACE) - cmake_path(GET _xcrun_out PARENT_PATH _xcrun_toolchain_path) - cmake_path(GET CMAKE_${lang}_COMPILER PARENT_PATH _compiler_parent_path) - if ("${_xcrun_toolchain_path}" STREQUAL "${_compiler_parent_path}") - set(${output_variable} "") - endif() - unset(_xcrun_out) - unset(_xcrun_toolchain_path) - unset(_compiler_parent_path) - endif() -endmacro() - - -macro(append_compiler_executables_configuration) - set(_conan_c_compiler "") - set(_conan_cpp_compiler "") - set(_conan_rc_compiler "") - set(_conan_compilers_list "") - if(CMAKE_C_COMPILER) - set(_conan_c_compiler "\"c\":\"${CMAKE_C_COMPILER}\"") - set_conan_compiler_if_appleclang(C cc _conan_c_compiler) - list(APPEND _conan_compilers_list ${_conan_c_compiler}) - else() - message(WARNING "CMake-Conan: The C compiler is not defined. " - "Please define CMAKE_C_COMPILER or enable the C language.") - endif() - if(CMAKE_CXX_COMPILER) - set(_conan_cpp_compiler "\"cpp\":\"${CMAKE_CXX_COMPILER}\"") - set_conan_compiler_if_appleclang(CXX c++ _conan_cpp_compiler) - list(APPEND _conan_compilers_list ${_conan_cpp_compiler}) - else() - message(WARNING "CMake-Conan: The C++ compiler is not defined. " - "Please define CMAKE_CXX_COMPILER or enable the C++ language.") - endif() - if(CMAKE_RC_COMPILER) - set(_conan_rc_compiler "\"rc\":\"${CMAKE_RC_COMPILER}\"") - list(APPEND _conan_compilers_list ${_conan_rc_compiler}) - # Not necessary to warn if RC not defined - endif() - if(NOT "x${_conan_compilers_list}" STREQUAL "x") - string(REPLACE ";" "," _conan_compilers_list "${_conan_compilers_list}") - string(APPEND profile "tools.build:compiler_executables={${_conan_compilers_list}}\n") - endif() - unset(_conan_c_compiler) - unset(_conan_cpp_compiler) - unset(_conan_rc_compiler) - unset(_conan_compilers_list) -endmacro() - - -function(detect_host_profile output_file) - detect_os(os os_api_level os_sdk os_subsystem os_version) - detect_arch(arch) - detect_compiler(compiler compiler_version compiler_runtime compiler_runtime_type) - detect_cxx_standard(compiler_cppstd) - detect_lib_cxx(compiler_libcxx) - detect_build_type(build_type) - - set(profile "") - string(APPEND profile "[settings]\n") - if(arch) - string(APPEND profile arch=${arch} "\n") - endif() - if(os) - string(APPEND profile os=${os} "\n") - endif() - if(os_api_level) - string(APPEND profile os.api_level=${os_api_level} "\n") - endif() - if(os_version) - string(APPEND profile os.version=${os_version} "\n") - endif() - if(os_sdk) - string(APPEND profile os.sdk=${os_sdk} "\n") - endif() - if(os_subsystem) - string(APPEND profile os.subsystem=${os_subsystem} "\n") - endif() - if(compiler) - string(APPEND profile compiler=${compiler} "\n") - endif() - if(compiler_version) - string(APPEND profile compiler.version=${compiler_version} "\n") - endif() - if(compiler_runtime) - string(APPEND profile compiler.runtime=${compiler_runtime} "\n") - endif() - if(compiler_runtime_type) - string(APPEND profile compiler.runtime_type=${compiler_runtime_type} "\n") - endif() - if(compiler_cppstd) - string(APPEND profile compiler.cppstd=${compiler_cppstd} "\n") - endif() - if(compiler_libcxx) - string(APPEND profile compiler.libcxx=${compiler_libcxx} "\n") - endif() - if(build_type) - string(APPEND profile "build_type=${build_type}\n") - endif() - - if(NOT DEFINED output_file) - set(file_name "${CMAKE_BINARY_DIR}/profile") - else() - set(file_name ${output_file}) - endif() - - string(APPEND profile "[conf]\n") - string(APPEND profile "tools.cmake.cmaketoolchain:generator=${CMAKE_GENERATOR}\n") - - # propagate compilers via profile - append_compiler_executables_configuration() - - if(os STREQUAL "Android") - string(APPEND profile "tools.android:ndk_path=${CMAKE_ANDROID_NDK}\n") - endif() - - message(STATUS "CMake-Conan: Creating profile ${file_name}") - file(WRITE ${file_name} ${profile}) - message(STATUS "CMake-Conan: Profile: \n${profile}") -endfunction() - - -function(conan_profile_detect_default) - message(STATUS "CMake-Conan: Checking if a default profile exists") - execute_process(COMMAND ${CONAN_COMMAND} profile path default - RESULT_VARIABLE return_code - OUTPUT_VARIABLE conan_stdout - ERROR_VARIABLE conan_stderr - ECHO_ERROR_VARIABLE # show the text output regardless - ECHO_OUTPUT_VARIABLE - WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}) - if(NOT ${return_code} EQUAL "0") - message(STATUS "CMake-Conan: The default profile doesn't exist, detecting it.") - execute_process(COMMAND ${CONAN_COMMAND} profile detect - RESULT_VARIABLE return_code - OUTPUT_VARIABLE conan_stdout - ERROR_VARIABLE conan_stderr - ECHO_ERROR_VARIABLE # show the text output regardless - ECHO_OUTPUT_VARIABLE - WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}) - endif() -endfunction() - - -function(conan_install) - cmake_parse_arguments(ARGS conan_args ${ARGN}) - set(conan_output_folder ${CMAKE_BINARY_DIR}/conan) - # Invoke "conan install" with the provided arguments - set(conan_args ${conan_args} -of=${conan_output_folder}) - message(STATUS "CMake-Conan: conan install ${CMAKE_SOURCE_DIR} ${conan_args} ${ARGN}") - - - # In case there was not a valid cmake executable in the PATH, we inject the - # same we used to invoke the provider to the PATH - if(DEFINED PATH_TO_CMAKE_BIN) - set(old_path $ENV{PATH}) - set(ENV{PATH} "$ENV{PATH}:${PATH_TO_CMAKE_BIN}") - endif() - - execute_process(COMMAND ${CONAN_COMMAND} install ${CMAKE_SOURCE_DIR} ${conan_args} ${ARGN} --format=json - RESULT_VARIABLE return_code - OUTPUT_VARIABLE conan_stdout - ERROR_VARIABLE conan_stderr - ECHO_ERROR_VARIABLE # show the text output regardless - WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}) - - if(DEFINED PATH_TO_CMAKE_BIN) - set(ENV{PATH} "${old_path}") - endif() - - if(NOT "${return_code}" STREQUAL "0") - message(FATAL_ERROR "Conan install failed='${return_code}'") - endif() - - # the files are generated in a folder that depends on the layout used, if - # one is specified, but we don't know a priori where this is. - # TODO: this can be made more robust if Conan can provide this in the json output - string(JSON conan_generators_folder GET "${conan_stdout}" graph nodes 0 generators_folder) - cmake_path(CONVERT ${conan_generators_folder} TO_CMAKE_PATH_LIST conan_generators_folder) - - message(STATUS "CMake-Conan: CONAN_GENERATORS_FOLDER=${conan_generators_folder}") - set_property(GLOBAL PROPERTY CONAN_GENERATORS_FOLDER "${conan_generators_folder}") - # reconfigure on conanfile changes - string(JSON conanfile GET "${conan_stdout}" graph nodes 0 label) - message(STATUS "CMake-Conan: CONANFILE=${CMAKE_SOURCE_DIR}/${conanfile}") - set_property(DIRECTORY ${CMAKE_SOURCE_DIR} APPEND PROPERTY CMAKE_CONFIGURE_DEPENDS "${CMAKE_SOURCE_DIR}/${conanfile}") - # success - set_property(GLOBAL PROPERTY CONAN_INSTALL_SUCCESS TRUE) - -endfunction() - - -function(conan_get_version conan_command conan_current_version) - execute_process( - COMMAND ${conan_command} --version - OUTPUT_VARIABLE conan_output - RESULT_VARIABLE conan_result - OUTPUT_STRIP_TRAILING_WHITESPACE - ) - if(conan_result) - message(FATAL_ERROR "CMake-Conan: Error when trying to run Conan") - endif() - - string(REGEX MATCH "[0-9]+\\.[0-9]+\\.[0-9]+" conan_version ${conan_output}) - set(${conan_current_version} ${conan_version} PARENT_SCOPE) -endfunction() - - -function(conan_version_check) - set(options ) - set(one_value_args MINIMUM CURRENT) - set(multi_value_args ) - cmake_parse_arguments(conan_version_check - "${options}" "${one_value_args}" "${multi_value_args}" ${ARGN}) - - if(NOT conan_version_check_MINIMUM) - message(FATAL_ERROR "CMake-Conan: Required parameter MINIMUM not set!") - endif() - if(NOT conan_version_check_CURRENT) - message(FATAL_ERROR "CMake-Conan: Required parameter CURRENT not set!") - endif() - - if(conan_version_check_CURRENT VERSION_LESS conan_version_check_MINIMUM) - message(FATAL_ERROR "CMake-Conan: Conan version must be ${conan_version_check_MINIMUM} or later") - endif() -endfunction() - - -macro(construct_profile_argument argument_variable profile_list) - set(${argument_variable} "") - if("${profile_list}" STREQUAL "CONAN_HOST_PROFILE") - set(_arg_flag "--profile:host=") - elseif("${profile_list}" STREQUAL "CONAN_BUILD_PROFILE") - set(_arg_flag "--profile:build=") - endif() - - set(_profile_list "${${profile_list}}") - list(TRANSFORM _profile_list REPLACE "auto-cmake" "${CMAKE_BINARY_DIR}/conan_host_profile") - list(TRANSFORM _profile_list PREPEND ${_arg_flag}) - set(${argument_variable} ${_profile_list}) - - unset(_arg_flag) - unset(_profile_list) -endmacro() - - -macro(conan_provide_dependency method package_name) - set_property(GLOBAL PROPERTY CONAN_PROVIDE_DEPENDENCY_INVOKED TRUE) - get_property(_conan_install_success GLOBAL PROPERTY CONAN_INSTALL_SUCCESS) - if(NOT _conan_install_success) - find_program(CONAN_COMMAND "conan" REQUIRED) - conan_get_version(${CONAN_COMMAND} CONAN_CURRENT_VERSION) - conan_version_check(MINIMUM ${CONAN_MINIMUM_VERSION} CURRENT ${CONAN_CURRENT_VERSION}) - message(STATUS "CMake-Conan: first find_package() found. Installing dependencies with Conan") - if("default" IN_LIST CONAN_HOST_PROFILE OR "default" IN_LIST CONAN_BUILD_PROFILE) - conan_profile_detect_default() - endif() - if("auto-cmake" IN_LIST CONAN_HOST_PROFILE) - detect_host_profile(${CMAKE_BINARY_DIR}/conan_host_profile) - endif() - construct_profile_argument(_host_profile_flags CONAN_HOST_PROFILE) - construct_profile_argument(_build_profile_flags CONAN_BUILD_PROFILE) - if(EXISTS "${CMAKE_SOURCE_DIR}/conanfile.py") - file(READ "${CMAKE_SOURCE_DIR}/conanfile.py" outfile) - if(NOT "${outfile}" MATCHES ".*CMakeDeps.*") - message(WARNING "Cmake-conan: CMakeDeps generator was not defined in the conanfile") - endif() - set(generator "") - elseif (EXISTS "${CMAKE_SOURCE_DIR}/conanfile.txt") - file(READ "${CMAKE_SOURCE_DIR}/conanfile.txt" outfile) - if(NOT "${outfile}" MATCHES ".*CMakeDeps.*") - message(WARNING "Cmake-conan: CMakeDeps generator was not defined in the conanfile. " - "Please define the generator as it will be mandatory in the future") - endif() - set(generator "-g;CMakeDeps") - endif() - get_property(_multiconfig_generator GLOBAL PROPERTY GENERATOR_IS_MULTI_CONFIG) - if(NOT _multiconfig_generator) - message(STATUS "CMake-Conan: Installing single configuration ${CMAKE_BUILD_TYPE}") - conan_install(${_host_profile_flags} ${_build_profile_flags} ${CONAN_INSTALL_ARGS} ${generator}) - else() - message(STATUS "CMake-Conan: Installing both Debug and Release") - conan_install(${_host_profile_flags} ${_build_profile_flags} -s build_type=Release ${CONAN_INSTALL_ARGS} ${generator}) - conan_install(${_host_profile_flags} ${_build_profile_flags} -s build_type=Debug ${CONAN_INSTALL_ARGS} ${generator}) - endif() - unset(_host_profile_flags) - unset(_build_profile_flags) - unset(_multiconfig_generator) - unset(_conan_install_success) - else() - message(STATUS "CMake-Conan: find_package(${ARGV1}) found, 'conan install' already ran") - unset(_conan_install_success) - endif() - - get_property(_conan_generators_folder GLOBAL PROPERTY CONAN_GENERATORS_FOLDER) - - # Ensure that we consider Conan-provided packages ahead of any other, - # irrespective of other settings that modify the search order or search paths - # This follows the guidelines from the find_package documentation - # (https://cmake.org/cmake/help/latest/command/find_package.html): - # find_package ( PATHS paths... NO_DEFAULT_PATH) - # find_package () - - # Filter out `REQUIRED` from the argument list, as the first call may fail - set(_find_args_${package_name} "${ARGN}") - list(REMOVE_ITEM _find_args_${package_name} "REQUIRED") - if(NOT "MODULE" IN_LIST _find_args_${package_name}) - find_package(${package_name} ${_find_args_${package_name}} BYPASS_PROVIDER PATHS "${_conan_generators_folder}" NO_DEFAULT_PATH NO_CMAKE_FIND_ROOT_PATH) - unset(_find_args_${package_name}) - endif() - - # Invoke find_package a second time - if the first call succeeded, - # this will simply reuse the result. If not, fall back to CMake default search - # behaviour, also allowing modules to be searched. - if(NOT ${package_name}_FOUND) - list(FIND CMAKE_MODULE_PATH "${_conan_generators_folder}" _index) - if(_index EQUAL -1) - list(PREPEND CMAKE_MODULE_PATH "${_conan_generators_folder}") - endif() - unset(_index) - find_package(${package_name} ${ARGN} BYPASS_PROVIDER) - list(REMOVE_ITEM CMAKE_MODULE_PATH "${_conan_generators_folder}") - endif() -endmacro() - - -cmake_language( - SET_DEPENDENCY_PROVIDER conan_provide_dependency - SUPPORTED_METHODS FIND_PACKAGE -) - - -macro(conan_provide_dependency_check) - set(_conan_provide_dependency_invoked FALSE) - get_property(_conan_provide_dependency_invoked GLOBAL PROPERTY CONAN_PROVIDE_DEPENDENCY_INVOKED) - if(NOT _conan_provide_dependency_invoked) - message(WARNING "Conan is correctly configured as dependency provider, " - "but Conan has not been invoked. Please add at least one " - "call to `find_package()`.") - if(DEFINED CONAN_COMMAND) - # supress warning in case `CONAN_COMMAND` was specified but unused. - set(_conan_command ${CONAN_COMMAND}) - unset(_conan_command) - endif() - endif() - unset(_conan_provide_dependency_invoked) -endmacro() - - -# Add a deferred call at the end of processing the top-level directory -# to check if the dependency provider was invoked at all. -cmake_language(DEFER DIRECTORY "${CMAKE_SOURCE_DIR}" CALL conan_provide_dependency_check) - -# Configurable variables for Conan profiles -set(CONAN_HOST_PROFILE "default;auto-cmake" CACHE STRING "Conan host profile") -set(CONAN_BUILD_PROFILE "default" CACHE STRING "Conan build profile") -set(CONAN_INSTALL_ARGS "--build=missing" CACHE STRING "Command line arguments for conan install") - -find_program(_cmake_program NAMES cmake NO_PACKAGE_ROOT_PATH NO_CMAKE_PATH NO_CMAKE_ENVIRONMENT_PATH NO_CMAKE_SYSTEM_PATH NO_CMAKE_FIND_ROOT_PATH) -if(NOT _cmake_program) - get_filename_component(PATH_TO_CMAKE_BIN "${CMAKE_COMMAND}" DIRECTORY) - set(PATH_TO_CMAKE_BIN "${PATH_TO_CMAKE_BIN}" CACHE INTERNAL "Path where the CMake executable is") -endif() - -cmake_policy(POP) diff --git a/src/Config.h b/src/Config.h index 4314334..8eac470 100644 --- a/src/Config.h +++ b/src/Config.h @@ -13,5 +13,9 @@ #endif #define VALUE_COUNT ((size_t)(4 * 24 * 365)) #define MAX_CONDITIONS 2560 +#include +#include + +typedef std::unique_ptr>>> usageProfile; #endif //CONFIG_H diff --git a/src/helper/CalculateProfile.cpp b/src/helper/CalculateProfile.cpp new file mode 100644 index 0000000..071c16f --- /dev/null +++ b/src/helper/CalculateProfile.cpp @@ -0,0 +1,95 @@ +// +// Created by stani on 3/14/2025. + +#include "CalculateProfile.h" + +#include +#include +#include + +#include "../singelton/UsageProfile.h" +#include +#include + +/** + * + * @param profileNameCon Name of the Consumption Profile e.g. G1 + * @param profileNameGen Name of the Generation Profile e.g. Solar + * @param annualConsumption Annual Consumption value + * @param annualGeneration Annual Consumption value + * @return Tuple first element consumption vector, second generation Vector + * @throws runtime_error if profileNameCon or profileNameGen is not loaded + * @throws + */ +std::tuple, std::vector> CalculateProfile::calculateProfile( + const std::string& profileNameCon, const std::string& profileNameGen, const float annualConsumption, + const float annualGeneration) +{ + const UsageProfile* profiles = UsageProfile::getInstance(); + std::vector calculatedConProfile; + std::vector calculatedGenProfile; + const auto itCon = std::ranges::find_if(*profiles->ConsumptionProfile, + [&profileNameCon]( + const std::pair>& pair) + { + return pair.first == profileNameCon; + }); + const auto itGen = std::ranges::find_if(*profiles->GenerationProfile, + [&profileNameGen]( + const std::pair>& pair) + { + return pair.first == profileNameGen; + }); + if (itCon == profiles->ConsumptionProfile->end()) { + throw std::runtime_error("Consumption profile not found: " + profileNameCon); + } + if (itGen == profiles->GenerationProfile->end()) { + throw std::runtime_error("Consumption profile not found: " + profileNameGen); + } + const float sumCon = std::accumulate(itCon->second.begin(), itCon->second.end(), 0.0f, + [](const float acc, const std::string& str) + { + float value; + const auto result = std::from_chars(str.data(), str.data() + str.size(), value); + if (result.ec != std::errc()) + { + throw std::invalid_argument("Invalid number format: " + str); + } + return acc + value; + }); + + const float sumGen = std::accumulate(itGen->second.begin(), itGen->second.end(), 0.0f, + [](const float acc, const std::string& str) + { + float value = 0.0f; + auto result = std::from_chars(str.data(), str.data() + str.size(), value); + if (result.ec != std::errc()) + { + throw std::invalid_argument("Invalid number format: " + str); + } + return acc + value; + }); + + for (auto&& [consumption, generation] : std::views::zip( + itCon->second, + itGen->second + )) + { + float floatCon = 0.f; + float floatGen = 0.f; + const auto res1 = std::from_chars(consumption.data(), consumption.data() + consumption.size(), floatCon); + const auto res2 = std::from_chars(generation.data(), generation.data() + generation.size(), floatGen); + if (res1.ec == std::errc::invalid_argument || res2.ec == std::errc::invalid_argument) + { + throw std::invalid_argument("Not a float"); + } + if (res1.ec == std::errc::result_out_of_range || res2.ec == std::errc::result_out_of_range) + { + throw std::out_of_range("Out fo range"); + } + calculatedConProfile.push_back(floatCon * annualConsumption / sumCon); + calculatedGenProfile.push_back(floatGen * annualGeneration / sumGen); + } + return make_tuple(std::move(calculatedConProfile), + std::move(calculatedGenProfile)); +} diff --git a/src/helper/CalculateProfile.h b/src/helper/CalculateProfile.h new file mode 100644 index 0000000..4266374 --- /dev/null +++ b/src/helper/CalculateProfile.h @@ -0,0 +1,20 @@ +// +// Created by stani on 3/14/2025. +// + +#ifndef CALCULATEPROFILE_H +#define CALCULATEPROFILE_H +#include +#include + + +class CalculateProfile +{ +public: + static std::tuple, std::vector> calculateProfile( + const std::string& profileNameCon, const std::string& profileNameGen, float annualConsumption, + float annualGeneration); +}; + + +#endif //CALCULATEPROFILE_H diff --git a/src/helper/CsvBinary.cpp b/src/helper/CsvBinary.cpp index 4f0c778..e9acf19 100644 --- a/src/helper/CsvBinary.cpp +++ b/src/helper/CsvBinary.cpp @@ -11,21 +11,25 @@ #include "../Config.h" -std::vector CsvBinary::splitLine(const std::string &line, const char delimiter) { +std::vector CsvBinary::splitLine(const std::string& line, const char delimiter) +{ std::vector tokens; std::stringstream ss(line); std::string token; - while (std::getline(ss, token, delimiter)) { + while (std::getline(ss, token, delimiter)) + { tokens.push_back(token); } return tokens; } -void CsvBinary::csvToBinary(const std::string &csvFile, const std::string &binFile) { +void CsvBinary::csvToBinary(const std::string& csvFile, const std::string& binFile) +{ std::ifstream inFile(csvFile); std::ofstream outFile(binFile, std::ios::binary); - if (!inFile.is_open() || !outFile.is_open()) { + if (!inFile.is_open() || !outFile.is_open()) + { LOG_DEBUG_ERROR("Failed opening file"); return; } @@ -37,14 +41,17 @@ void CsvBinary::csvToBinary(const std::string &csvFile, const std::string &binFi std::stringstream jsonHeader; jsonHeader << "{\"headers\":["; - while (std::getline(inFile, line)) { + while (std::getline(inFile, line)) + { std::vector row = splitLine(line, ';'); - if (isHeader) { + if (isHeader) + { header = row; // Store header as JSON - for (size_t i = 0; i < header.size(); ++i) { + for (size_t i = 0; i < header.size(); ++i) + { jsonHeader << "\"" << header[i] << "\""; if (i < header.size() - 1) jsonHeader << ","; } @@ -54,16 +61,17 @@ void CsvBinary::csvToBinary(const std::string &csvFile, const std::string &binFi size_t jsonSize = jsonStr.size(); // Write JSON size and content at the beginning of the binary file - outFile.write(reinterpret_cast(&jsonSize), sizeof(size_t)); + outFile.write(reinterpret_cast(&jsonSize), sizeof(size_t)); outFile.write(jsonStr.c_str(), jsonSize); isHeader = false; continue; } - for (const auto &field : row) { + for (const auto& field : row) + { size_t length = field.size(); - outFile.write(reinterpret_cast(&length), sizeof(size_t)); + outFile.write(reinterpret_cast(&length), sizeof(size_t)); outFile.write(field.c_str(), length); } } @@ -74,18 +82,20 @@ void CsvBinary::csvToBinary(const std::string &csvFile, const std::string &binFi LOG_DEBUG_INFO("CSV converted to binary successfully."); } -void CsvBinary::binaryToCsv(const std::string &binFile, const std::string &csvFile) { +void CsvBinary::binaryToCsv(const std::string& binFile, const std::string& csvFile) +{ std::ifstream inFile(binFile, std::ios::binary); std::ofstream outFile(csvFile); - if (!inFile.is_open() || !outFile.is_open()) { + if (!inFile.is_open() || !outFile.is_open()) + { LOG_DEBUG_ERROR("Failed opening file"); return; } // Read JSON metadata size_t jsonSize; - inFile.read(reinterpret_cast(&jsonSize), sizeof(size_t)); + inFile.read(reinterpret_cast(&jsonSize), sizeof(size_t)); std::string jsonStr(jsonSize, ' '); inFile.read(&jsonStr[0], jsonSize); @@ -98,30 +108,36 @@ void CsvBinary::binaryToCsv(const std::string &binFile, const std::string &csvFi std::stringstream ss(headersStr); std::string field; - while (std::getline(ss, field, ',')) { + while (std::getline(ss, field, ',')) + { field.erase(std::remove(field.begin(), field.end(), '\"'), field.end()); // Remove quotes header.push_back(field); } // Write header to CSV - for (size_t i = 0; i < header.size(); ++i) { + for (size_t i = 0; i < header.size(); ++i) + { outFile << header[i]; if (i < header.size() - 1) outFile << ";"; } outFile << "\n"; - while (!inFile.eof()) { + while (!inFile.eof()) + { std::vector row; - for (size_t i = 0; i < header.size(); ++i) { + for (size_t i = 0; i < header.size(); ++i) + { size_t length; - if (!inFile.read(reinterpret_cast(&length), sizeof(size_t))) break; + if (!inFile.read(reinterpret_cast(&length), sizeof(size_t))) break; std::string field(length, ' '); inFile.read(&field[0], length); row.push_back(field); } - if (!row.empty()) { - for (size_t i = 0; i < row.size(); ++i) { + if (!row.empty()) + { + for (size_t i = 0; i < row.size(); ++i) + { outFile << row[i]; if (i < row.size() - 1) outFile << ";"; } @@ -136,19 +152,20 @@ void CsvBinary::binaryToCsv(const std::string &binFile, const std::string &csvFi } std::unique_ptr>>> CsvBinary::binaryToVector( - const std::string &binFile) { - + const std::string& binFile) +{ std::ifstream inFile(binFile, std::ios::binary); auto data = std::make_unique>>>(); - if (!inFile.is_open()) { + if (!inFile.is_open()) + { LOG_DEBUG_ERROR("Failed to open binary file"); - return data; // Return empty structure + return data; // Return empty structure } // Read JSON metadata size size_t jsonSize; - inFile.read(reinterpret_cast(&jsonSize), sizeof(size_t)); + inFile.read(reinterpret_cast(&jsonSize), sizeof(size_t)); // Read JSON metadata std::string jsonStr(jsonSize, ' '); @@ -162,21 +179,25 @@ std::unique_ptr>>> C std::stringstream ss(headersStr); std::string field; - while (std::getline(ss, field, ',')) { + while (std::getline(ss, field, ',')) + { field.erase(std::remove(field.begin(), field.end(), '\"'), field.end()); // Remove quotes headers.push_back(field); } // Initialize data structure for columns - for (const auto &header : headers) { + for (const auto& header : headers) + { data->emplace_back(header, std::vector()); } // Read row data and distribute into columns - while (!inFile.eof()) { - for (size_t i = 0; i < headers.size(); ++i) { + while (!inFile.eof()) + { + for (size_t i = 0; i < headers.size(); ++i) + { size_t length; - if (!inFile.read(reinterpret_cast(&length), sizeof(size_t))) break; + if (!inFile.read(reinterpret_cast(&length), sizeof(size_t))) break; std::string value(length, ' '); if (!inFile.read(&value[0], length)) break; diff --git a/src/helper/CsvBinary.h b/src/helper/CsvBinary.h index bd7d48a..408dced 100644 --- a/src/helper/CsvBinary.h +++ b/src/helper/CsvBinary.h @@ -4,29 +4,23 @@ #ifndef CSVTOBINARY_H #define CSVTOBINARY_H -#include #include -#include #include #include #include -#include -class CsvBinary { +class CsvBinary +{ private: - - static std::vector splitLine(const std::string &line, char delimiter); - - static void saveHeaderToFile(const std::string &string, const std::string &line); + static std::vector splitLine(const std::string& line, char delimiter); public: + static void csvToBinary(const std::string& csvFile, const std::string& binFile); - static void csvToBinary(const std::string &csvFile, const std::string &binFile); - - static void binaryToCsv(const std::string &binFile, const std::string &csvFile); + static void binaryToCsv(const std::string& binFile, const std::string& csvFile); [[nodiscard]] static std::unique_ptr>>> binaryToVector( - const std::string &binFile); + const std::string& binFile); }; diff --git a/src/helper/StringOperations.cpp b/src/helper/StringOperations.cpp index 86c3159..3b7a424 100644 --- a/src/helper/StringOperations.cpp +++ b/src/helper/StringOperations.cpp @@ -4,12 +4,16 @@ #include "StringOperations.h" -void StringOperations::splitString(const std::string &input, const std::string &delimiter, std::string &before, -std::string &after) { - if (const size_t pos = input.find(delimiter); pos != std::string::npos) { +void StringOperations::splitString(const std::string& input, const std::string& delimiter, std::string& before, + std::string& after) +{ + if (const size_t pos = input.find(delimiter); pos != std::string::npos) + { before = input.substr(0, pos); after = input.substr(pos + delimiter.length()); - } else { + } + else + { before = input; after = ""; } diff --git a/src/model/Building.cpp b/src/model/Building.cpp index e5c2b81..b894e4a 100644 --- a/src/model/Building.cpp +++ b/src/model/Building.cpp @@ -6,19 +6,25 @@ #include -float Building::Metadata::special_rate_consumption() const { +#include "../helper/CalculateProfile.h" + +float Building::Metadata::special_rate_consumption() const +{ return SpecialRateConsumption; } -void Building::Metadata::set_special_rate_consumption(const float special_rate_consumption) { +void Building::Metadata::set_special_rate_consumption(const float special_rate_consumption) +{ SpecialRateConsumption = special_rate_consumption; } -float Building::Metadata::special_rate_generation() const { +float Building::Metadata::special_rate_generation() const +{ return SpecialRateGeneration; } -void Building::Metadata::set_special_rate_generation(const float special_rate_generation) { +void Building::Metadata::set_special_rate_generation(const float special_rate_generation) +{ SpecialRateGeneration = special_rate_generation; } @@ -102,260 +108,332 @@ void Building::Metadata::set_total_by_category_without(std::unordered_map &Building::Simulation_Values::generation_after_community() { +std::vector& Building::Simulation_Values::generation_after_community() +{ return GenerationAfterCommunity; } -void Building::Simulation_Values::generation_after_community(const std::vector &generation_after_community) { +void Building::Simulation_Values::generation_after_community(const std::vector& generation_after_community) +{ GenerationAfterCommunity = generation_after_community; } -std::vector &Building::Simulation_Values::consumption_after_community() { +std::vector& Building::Simulation_Values::consumption_after_community() +{ return ConsumptionAfterCommunity; } -void Building::Simulation_Values::consumption_after_community(const std::vector &consumption_after_community) { +void Building::Simulation_Values::consumption_after_community(const std::vector& consumption_after_community) +{ ConsumptionAfterCommunity = consumption_after_community; } -std::vector &Building::Simulation_Values::generation_to_community() { +std::vector& Building::Simulation_Values::generation_to_community() +{ return GenerationToCommunity; } -void Building::Simulation_Values::generation_to_community(const std::vector &generation_to_community) { +void Building::Simulation_Values::generation_to_community(const std::vector& generation_to_community) +{ GenerationToCommunity = generation_to_community; } -std::vector &Building::Simulation_Values::consumption_from_community() { +std::vector& Building::Simulation_Values::consumption_from_community() +{ return ConsumptionFromCommunity; } -void Building::Simulation_Values::consumption_from_community(const std::vector &consumption_from_community) { +void Building::Simulation_Values::consumption_from_community(const std::vector& consumption_from_community) +{ ConsumptionFromCommunity = consumption_from_community; } -float Building::Simulation_Values::con_from_community_relative() const { +float Building::Simulation_Values::con_from_community_relative() const +{ return this->ConsumptionFromCommunityRelative; } -void Building::Simulation_Values::set_con_from_community_relative(const float x) { +void Building::Simulation_Values::set_con_from_community_relative(const float x) +{ this->ConsumptionFromCommunityRelative = x; } -float Building::Simulation_Values::gen_to_community_relative() const { +float Building::Simulation_Values::gen_to_community_relative() const +{ return this->GenerationToCommunityRelative; } -void Building::Simulation_Values::set_gen_to_community_relative(float x) { +void Building::Simulation_Values::set_gen_to_community_relative(float x) +{ this->GenerationToCommunityRelative = x; } -float Building::Simulation_Values::consumption_after_own_coverage_sum() const { +float Building::Simulation_Values::consumption_after_own_coverage_sum() const +{ return ConsumptionAfterCommunitySum; } -void Building::Simulation_Values::set_consumption_after_own_coverage_sum(const float value) { +void Building::Simulation_Values::set_consumption_after_own_coverage_sum(const float value) +{ ConsumptionFromCommunityRelative = value; } -float Building::Simulation_Values::own_usage_sum() const { +float Building::Simulation_Values::own_usage_sum() const +{ return OwnUsageSum; } -void Building::Simulation_Values::set_own_usage_sum(const float value) { +void Building::Simulation_Values::set_own_usage_sum(const float value) +{ OwnUsageSum = value; } -float Building::Simulation_Values::needed_con_sum() const { +float Building::Simulation_Values::needed_con_sum() const +{ return NeededConSum; } -void Building::Simulation_Values::set_needed_con_sum(const float value) { +void Building::Simulation_Values::set_needed_con_sum(const float value) +{ NeededConSum = value; } -float Building::Simulation_Values::needed_gen_sum() const { +float Building::Simulation_Values::needed_gen_sum() const +{ return NeededGenSum; } -void Building::Simulation_Values::set_needed_gen_sum(const float value) { +void Building::Simulation_Values::set_needed_gen_sum(const float value) +{ NeededGenSum = value; } -float Building::Simulation_Values::consumption_after_community_sum() const { +float Building::Simulation_Values::consumption_after_community_sum() const +{ return ConsumptionAfterCommunitySum; } -void Building::Simulation_Values::set_consumption_after_community_sum(const float value) { +void Building::Simulation_Values::set_consumption_after_community_sum(const float value) +{ ConsumptionAfterCommunitySum = value; } -float Building::Simulation_Values::generation_after_community_sum() const { +float Building::Simulation_Values::generation_after_community_sum() const +{ return GenerationAfterCommunitySum; } -void Building::Simulation_Values::set_generation_after_community_sum(const float value) { +void Building::Simulation_Values::set_generation_after_community_sum(const float value) +{ GenerationAfterCommunitySum = value; } -float Building::Simulation_Values::consumption_from_community_sum() const { +float Building::Simulation_Values::consumption_from_community_sum() const +{ return ConsumptionFromCommunitySum; } -void Building::Simulation_Values::set_consumption_from_community_sum(const float value) { +void Building::Simulation_Values::set_consumption_from_community_sum(const float value) +{ ConsumptionFromCommunitySum = value; } -float Building::Simulation_Values::generation_to_community_sum() const { +float Building::Simulation_Values::generation_to_community_sum() const +{ return GenerationToCommunitySum; } -void Building::Simulation_Values::set_generation_to_community_sum(const float values) { +void Building::Simulation_Values::set_generation_to_community_sum(const float values) +{ GenerationToCommunitySum = values; } -std::vector &Building::Simulation_Values::consumption_after_own_coverage() { +std::vector& Building::Simulation_Values::consumption_after_own_coverage() +{ return ConsumptionAfterOwnCoverage; } void Building::Simulation_Values:: -set_community_coverage(std::vector community_coverage) { +set_community_coverage(std::vector community_coverage) +{ ConsumptionAfterOwnCoverage = std::move(community_coverage); } -std::vector &Building::Simulation_Values::own_usage() { +std::vector& Building::Simulation_Values::own_usage() +{ return OwnUsage; } -void Building::Simulation_Values::set_own_usage(std::vector own_usage) { +void Building::Simulation_Values::set_own_usage(std::vector own_usage) +{ OwnUsage = std::move(own_usage); } -std::vector &Building::Simulation_Values::needed_con() { +std::vector& Building::Simulation_Values::needed_con() +{ return NeededCon; } -void Building::Simulation_Values::set_needed_con(std::vector needed_con) { +void Building::Simulation_Values::set_needed_con(std::vector needed_con) +{ NeededCon = std::move(needed_con); } -std::vector &Building::Simulation_Values::needed_gen() { +std::vector& Building::Simulation_Values::needed_gen() +{ return NeededGen; } -void Building::Simulation_Values::set_needed_gen(std::vector needed_gen) { +void Building::Simulation_Values::set_needed_gen(std::vector needed_gen) +{ NeededGen = std::move(needed_gen); } -float Building::Simulation_Values::relativeSelfConsumption() const { +float Building::Simulation_Values::relativeSelfConsumption() const +{ return RelativeSelfConsumption; } -void Building::Simulation_Values::set_relativeSelfConsumption(float const relativeSelfConsumption) { +void Building::Simulation_Values::set_relativeSelfConsumption(float const relativeSelfConsumption) +{ this->RelativeSelfConsumption = relativeSelfConsumption; } -float Building::Simulation_Values::relativeSelfGeneration() const { +float Building::Simulation_Values::relativeSelfGeneration() const +{ return RelativeGeneration; } -void Building::Simulation_Values::set_relativeSelfGeneration(float const relativeSelfGeneration) { +void Building::Simulation_Values::set_relativeSelfGeneration(float const relativeSelfGeneration) +{ this->RelativeGeneration = relativeSelfGeneration; } -std::string Building::Metadata::name() const { +Building::Metadata::Metadata() +{ + auto [con, gen] = CalculateProfile::calculateProfile(ConsumptionProfileName, GenerationProfileName, + AnnualConsumption, AnnualConsumption); + ConsumptionProfile = std::move(con); + GenerationProfile = std::move(gen); +} + +std::string Building::Metadata::name() const +{ return Name; } -void Building::Metadata::set_name(const std::string &name) { +void Building::Metadata::set_name(const std::string& name) +{ Name = name; } -float Building::Metadata::annual_consumption() const { +float Building::Metadata::annual_consumption() const +{ return AnnualConsumption; } -void Building::Metadata::set_annual_consumption(float annual_consumption) { +void Building::Metadata::set_annual_consumption(float annual_consumption) +{ AnnualConsumption = annual_consumption; } -float Building::Metadata::annual_generation() const { +float Building::Metadata::annual_generation() const +{ return AnnualGeneration; } -void Building::Metadata::set_annual_generation(float annual_generation) { +void Building::Metadata::set_annual_generation(float annual_generation) +{ AnnualGeneration = annual_generation; } -std::vector &Building::Metadata::consumption_profile() { +std::vector& Building::Metadata::consumption_profile() +{ return ConsumptionProfile; } -void Building::Metadata::set_consumption_profile(std::vector consumption_profile) { +void Building::Metadata::set_consumption_profile(std::vector consumption_profile) +{ ConsumptionProfile = std::move(consumption_profile); } -std::vector &Building::Metadata::generation_profile() { +std::vector& Building::Metadata::generation_profile() +{ return GenerationProfile; } -void Building::Metadata::set_generation_profile(std::vector generation_profile) { +void Building::Metadata::set_generation_profile(std::vector generation_profile) +{ GenerationProfile = std::move(generation_profile); } -std::string Building::Metadata::consumption_profile_name() const { +std::string Building::Metadata::consumption_profile_name() const +{ return ConsumptionProfileName; } -void Building::Metadata::set_consumption_profile_name(const std::string &consumption_profile_name) { +void Building::Metadata::set_consumption_profile_name(const std::string& consumption_profile_name) +{ ConsumptionProfileName = consumption_profile_name; } -std::string Building::Metadata::generation_profile_name() const { +std::string Building::Metadata::generation_profile_name() const +{ return GenerationProfileName; } -void Building::Metadata::set_generation_profile_name(const std::string &generation_profile_name) { +void Building::Metadata::set_generation_profile_name(const std::string& generation_profile_name) +{ GenerationProfileName = generation_profile_name; } -short Building::Metadata::connection_power() const { +short Building::Metadata::connection_power() const +{ return ConnectionPower; } -void Building::Metadata::set_connection_power(short connection_power) { +void Building::Metadata::set_connection_power(short connection_power) +{ ConnectionPower = connection_power; } -short Building::Metadata::grid_power() const { +short Building::Metadata::grid_power() const +{ return GridPower; } -void Building::Metadata::set_grid_power(short grid_power) { +void Building::Metadata::set_grid_power(short grid_power) +{ GridPower = grid_power; } -std::unique_ptr &Building::Base::cost() { +std::unique_ptr& Building::Base::cost() +{ return CostHistory; } -void Building::Base::set_cost(std::unique_ptr cost) { +void Building::Base::set_cost(std::unique_ptr cost) +{ CostHistory = std::move(cost); } -std::shared_ptr& Building::Base::values() { +std::shared_ptr& Building::Base::values() +{ return Values; } -void Building::Base::set_values(std::shared_ptr values) { +void Building::Base::set_values(std::shared_ptr values) +{ Values = std::move(values); } -std::shared_ptr &Building::Base::metadata() { +std::shared_ptr& Building::Base::metadata() +{ return Data; } -void Building::Base::set_metadata(const std::shared_ptr& metadata) { +void Building::Base::set_metadata(const std::shared_ptr& metadata) +{ Data = metadata; } diff --git a/src/model/Building.h b/src/model/Building.h index 7fa1d31..5da85b2 100644 --- a/src/model/Building.h +++ b/src/model/Building.h @@ -14,7 +14,6 @@ namespace Building { - class Cost { private: @@ -126,8 +125,8 @@ namespace Building std::string Name{}; float AnnualConsumption{0.0f}; float AnnualGeneration{0.0f}; - std::vector ConsumptionProfile = std::vector(VALUE_COUNT, 0.0f); - std::vector GenerationProfile = std::vector(VALUE_COUNT, 0.0f); + std::vector ConsumptionProfile; + std::vector GenerationProfile; std::string ConsumptionProfileName{}; std::string GenerationProfileName{}; short ConnectionPower{0}; @@ -144,7 +143,7 @@ namespace Building std::unordered_map TotalByCategoryWithout{}; public: - Metadata() = default; + Metadata(); [[nodiscard]] std::string name() const; void set_name(const std::string& name); diff --git a/src/model/Community.cpp b/src/model/Community.cpp index 3f5cdc4..438759a 100644 --- a/src/model/Community.cpp +++ b/src/model/Community.cpp @@ -1,64 +1,81 @@ #include "Community.h" -std::string Community::name() const { +std::string Community::name() const +{ return Name; } -void Community::set_name(const std::string &name) { +void Community::set_name(const std::string& name) +{ Name = name; } -std::vector > &Community::buildings() { +std::vector>& Community::buildings() +{ return Buildings; } // Use move semantics for efficiency -void Community::set_buildings(std::vector > buildings) { +void Community::set_buildings(std::vector> buildings) +{ Buildings = std::move(buildings); } -Energy_Tariff Community::energy_tariff() const { +Energy_Tariff Community::energy_tariff() const +{ return energy_Tariff; } -void Community::set_energy_tariff(const Energy_Tariff &energy_tariff) { +void Community::set_energy_tariff(const Energy_Tariff& energy_tariff) +{ energy_Tariff = energy_tariff; } -std::vector &Community::generation_available() { +std::vector& Community::generation_available() +{ return GenerationAvailable; } -void Community::set_generation_available(std::vector &generationAvailable) { +void Community::set_generation_available(std::vector& generationAvailable) +{ this->GenerationAvailable = generationAvailable; } -std::vector &Community::consumption_available() { +std::vector& Community::consumption_available() +{ return ConsumptionAvailable; } -void Community::set_consumption_available(std::vector &consumptionAvailable) { +void Community::set_consumption_available(std::vector& consumptionAvailable) +{ this->ConsumptionAvailable = consumptionAvailable; } -std::vector &Community::is_gen_bigger_than_con() { +std::vector& Community::is_gen_bigger_than_con() +{ return IsGenBiggerThanCon; } -void Community::set_is_gen_bigger_than_con(std::vector &isGenBiggerThanCon) { +void Community::set_is_gen_bigger_than_con(std::vector& isGenBiggerThanCon) +{ this->IsGenBiggerThanCon = isGenBiggerThanCon; } auto Community::iterateBuildings( - std::vector > &Communities) - -> std::function &)>( - const std::function &)> { - return [&](const std::function &func1) { - return [&, func1](const std::function &func2) { - for (auto &community: Communities) { + std::vector>& Communities) + -> std::function&)>( + const std::function&)> +{ + return [&](const std::function& func1) + { + return [&, func1](const std::function& func2) + { + for (auto& community : Communities) + { func1(*community); - for (auto &building: community->buildings()) { + for (auto& building : community->buildings()) + { func2(*community, *building); } } diff --git a/src/model/Community.h b/src/model/Community.h index a46acec..c08e618 100644 --- a/src/model/Community.h +++ b/src/model/Community.h @@ -13,42 +13,43 @@ #include "Energy_Tariff.h" -class Community : public Model { +class Community : public Model +{ public: float total{0.f}; [[nodiscard]] std::string name() const; - void set_name(const std::string &name); + void set_name(const std::string& name); - std::vector > &buildings(); + std::vector>& buildings(); - void set_buildings(std::vector > buildings); + void set_buildings(std::vector> buildings); [[nodiscard]] Energy_Tariff energy_tariff() const; - void set_energy_tariff(const Energy_Tariff &energy_tariff); + void set_energy_tariff(const Energy_Tariff& energy_tariff); - std::vector &generation_available(); + std::vector& generation_available(); - void set_generation_available(std::vector &generationAvailable); + void set_generation_available(std::vector& generationAvailable); - std::vector &consumption_available(); + std::vector& consumption_available(); - void set_consumption_available(std::vector &consumptionAvailable); + void set_consumption_available(std::vector& consumptionAvailable); - std::vector &is_gen_bigger_than_con(); + std::vector& is_gen_bigger_than_con(); - void set_is_gen_bigger_than_con(std::vector &isGenBiggerThanCon); + void set_is_gen_bigger_than_con(std::vector& isGenBiggerThanCon); - static std::function &)>(const std:: + static std::function&)>(const std:: function &)> - iterateBuildings(std::vector > &Communities); + Community&)>&)> + iterateBuildings(std::vector>& Communities); private: std::string Name; - std::vector > Buildings; + std::vector> Buildings; std::vector GenerationAvailable = std::vector(VALUE_COUNT, 0.0f); std::vector ConsumptionAvailable = std::vector(VALUE_COUNT, 0.0f); std::vector IsGenBiggerThanCon = std::vector(VALUE_COUNT, false); diff --git a/src/services/Cost/BillCharge.h b/src/services/Cost/BillCharge.h index 5f964b6..bf9c4ad 100644 --- a/src/services/Cost/BillCharge.h +++ b/src/services/Cost/BillCharge.h @@ -7,11 +7,11 @@ #include "../../interfaces/ICostComponent.h" -class BillCharge : public ICostComponent { +class BillCharge : public ICostComponent +{ public: void apply(std::unique_ptr& building, std::unique_ptr& community) override; }; - #endif //BILLCHARGE_H diff --git a/src/services/Cost/CalculateFinalSums.h b/src/services/Cost/CalculateFinalSums.h index 80636e8..1a848f5 100644 --- a/src/services/Cost/CalculateFinalSums.h +++ b/src/services/Cost/CalculateFinalSums.h @@ -7,11 +7,11 @@ #include "../../interfaces/ICostComponent.h" -class CalculateFinalSums : public ICostComponent{ +class CalculateFinalSums : public ICostComponent +{ public: void apply(std::unique_ptr& building, std::unique_ptr& community) override; }; - #endif //CALCULATEFINALSUMS_H diff --git a/src/services/Cost/CostPipeline.cpp b/src/services/Cost/CostPipeline.cpp index 044eba1..8d932a5 100644 --- a/src/services/Cost/CostPipeline.cpp +++ b/src/services/Cost/CostPipeline.cpp @@ -5,12 +5,15 @@ #include "CostPipeline.h" -void CostPipeline::addCostComponent(const std::shared_ptr &components) { +void CostPipeline::addCostComponent(const std::shared_ptr& components) +{ this->components.push_back(components); } -void CostPipeline::calculateFinalCost() { - for (size_t i = 0; i < this->components.size() - 1; i++) { +void CostPipeline::calculateFinalCost() +{ + for (size_t i = 0; i < this->components.size() - 1; i++) + { iterateCommunity(this->components[i]); } // Ensure CalculateFinalSums is last @@ -18,14 +21,18 @@ void CostPipeline::calculateFinalCost() { } -void CostPipeline::iterateCommunity(std::shared_ptr &component) const { - for (auto &community: this->communities) { +void CostPipeline::iterateCommunity(std::shared_ptr& component) const +{ + for (auto& community : this->communities) + { iterateBuilding(community, component); } } -void CostPipeline::iterateBuilding(std::unique_ptr &community, std::shared_ptr &component) { - for (auto &building: community->buildings()) { +void CostPipeline::iterateBuilding(std::unique_ptr& community, std::shared_ptr& component) +{ + for (auto& building : community->buildings()) + { component->apply(building, community); } } diff --git a/src/services/Cost/TaxComponent.h b/src/services/Cost/TaxComponent.h index 3cee0c9..72a82b4 100644 --- a/src/services/Cost/TaxComponent.h +++ b/src/services/Cost/TaxComponent.h @@ -7,14 +7,16 @@ #include "../../interfaces/ICostComponent.h" -class TaxComponent : public ICostComponent { +class TaxComponent : public ICostComponent +{ double taxRate; public: - explicit TaxComponent(const double rate) : ICostComponent(), taxRate(rate) { + explicit TaxComponent(const double rate) : ICostComponent(), taxRate(rate) + { } - void apply(std::unique_ptr &building, std::unique_ptr &community) override; + void apply(std::unique_ptr& building, std::unique_ptr& community) override; }; diff --git a/src/services/CostHistory.h b/src/services/CostHistory.h index 623b5ce..1a42237 100644 --- a/src/services/CostHistory.h +++ b/src/services/CostHistory.h @@ -9,42 +9,56 @@ #include #include -class CostHistory { +class CostHistory +{ private: - struct CostPoint { + struct CostPoint + { std::string name; float value{0.0f}; float amount{0.f}; CostPoint(std::string name, const float value, const float amount) - : name(std::move(name)), value(value), amount(amount) {} + : name(std::move(name)), value(value), amount(amount) + { + } - [[nodiscard]] float total() const { + [[nodiscard]] float total() const + { return value * amount; } }; + std::vector costPoints{}; std::unordered_map TotalByCategory{}; + public: - void add_cost_point(const std::string &name, float value, float amount) { - if (amount==0.0) return; + void add_cost_point(const std::string& name, float value, float amount) + { + if (amount == 0.0) return; costPoints.emplace_back(name, value, amount); } - float total_cost() const { + float total_cost() const + { return std::accumulate(costPoints.begin(), costPoints.end(), 0.0f, - [](const float sum, const CostPoint &point) { + [](const float sum, const CostPoint& point) + { return sum + point.total(); }); } - const std::vector &get_cost_points() const { + const std::vector& get_cost_points() const + { return costPoints; } - std::unordered_map calculateCategories() { + + std::unordered_map calculateCategories() + { TotalByCategory.clear(); if (costPoints.empty()) return {}; - for (const CostPoint& point : costPoints) { + for (const CostPoint& point : costPoints) + { const size_t pos = point.name.find(' '); std::string result = (pos != std::string::npos) ? point.name.substr(0, pos) : point.name; TotalByCategory[result] += point.total(); @@ -54,5 +68,4 @@ public: }; - #endif //COSTHISTORY_H diff --git a/src/services/Surplus.cpp b/src/services/Surplus.cpp index 86ec505..45ce5ec 100644 --- a/src/services/Surplus.cpp +++ b/src/services/Surplus.cpp @@ -8,10 +8,12 @@ #include #include -void Surplus::CalculateSurplus() { - auto iterateFunc = Community::iterateBuildings(communities); +void Surplus::CalculateSurplus() +{ + auto iterateFunc = Community::iterateBuildings(communities); - auto modifyCommunity = [this](const Community &c) { + auto modifyCommunity = [this](const Community& c) + { this->consumptionAvailable = std::vector(VALUE_COUNT, 0.f); this->generationAvailable = std::vector(VALUE_COUNT, 0.f); @@ -19,8 +21,8 @@ void Surplus::CalculateSurplus() { }; - auto modifyBuildingSurplus = [this](Community &community, Building::Base &building) { - + auto modifyBuildingSurplus = [this](Community& community, Building::Base& building) + { CalculateBuildingSurplus(community, building); community.set_consumption_available(this->consumptionAvailable); @@ -29,7 +31,8 @@ void Surplus::CalculateSurplus() { iterateFunc(modifyCommunity)(modifyBuildingSurplus); - auto calculateCommunitySurplus = [this](Community &community) { + auto calculateCommunitySurplus = [this](Community& community) + { std::vector isGenBiggerThanCon; std::ranges::transform( consumptionAvailable, generationAvailable, @@ -39,14 +42,16 @@ void Surplus::CalculateSurplus() { community.set_is_gen_bigger_than_con(isGenBiggerThanCon); }; - auto calculateDistribution = [this](Community &community, Building::Base &building) { + auto calculateDistribution = [this](Community& community, Building::Base& building) + { CalculateSurplusCommunity(community, building); }; iterateFunc(calculateCommunitySurplus)(calculateDistribution); } -void Surplus::CalculateBuildingSurplus(Community &community, Building::Base &building) { +void Surplus::CalculateBuildingSurplus(Community& community, Building::Base& building) +{ auto ownCoverage = std::vector(VALUE_COUNT, 0.0f); auto neededConsumption = std::vector(VALUE_COUNT, 0.0f); auto neededGeneration = std::vector(VALUE_COUNT, 0.0f); @@ -54,11 +59,12 @@ void Surplus::CalculateBuildingSurplus(Community &community, Building::Base &bui assert(building.metadata() != nullptr && "Building metadata is null!"); - const auto &consumption = building.metadata()->consumption_profile(); - const auto &generation = building.metadata()->generation_profile(); + const auto& consumption = building.metadata()->consumption_profile(); + const auto& generation = building.metadata()->generation_profile(); size_t i = 0; // Fixed static variable issue - std::ranges::for_each(consumption, [&](auto c_ptr) { + std::ranges::for_each(consumption, [&](auto c_ptr) + { const float c = c_ptr ? c_ptr : 0.0f; const float g = i < generation.size() ? generation[i] : 0.0f; const float c_community = (i < consumptionAvailable.size()) ? consumptionAvailable[i] : 0.0f; @@ -91,24 +97,31 @@ void Surplus::CalculateBuildingSurplus(Community &community, Building::Base &bui const float totalGeneration = std::accumulate(building.metadata()->generation_profile().begin(), building.metadata()->generation_profile().end(), 0.0f); - if (totalConsumption > 0.0f) { + if (totalConsumption > 0.0f) + { building.values()->set_relativeSelfConsumption( std::accumulate(building.values()->own_usage().begin(), building.values()->own_usage().end(), 0.0f) / totalConsumption); - } else { + } + else + { building.values()->set_relativeSelfConsumption(0.0f); } - if (totalGeneration > 0.0f) { + if (totalGeneration > 0.0f) + { building.values()->set_relativeSelfGeneration( std::accumulate(building.values()->own_usage().begin(), building.values()->own_usage().end(), 0.0f) / totalGeneration); - } else { + } + else + { building.values()->set_relativeSelfGeneration(0.0f); } } -void Surplus::CalculateSurplusCommunity(Community &community, Building::Base &base) { +void Surplus::CalculateSurplusCommunity(Community& community, Building::Base& base) +{ const size_t neededGenSize = base.values()->needed_gen().size(); const size_t neededConSize = base.values()->needed_con().size(); const size_t consumptionAfterCommunitySize = base.values()->consumption_after_community().size(); @@ -124,7 +137,8 @@ void Surplus::CalculateSurplusCommunity(Community &community, Building::Base &ba neededGenSize != generationToCommunitySize || neededGenSize != consumptionFromCommunitySize || neededGenSize != communityConsumptionSize || - neededGenSize != communityGenerationSize) { + neededGenSize != communityGenerationSize) + { std::cerr << "Size mismatch detected in CalculateSurplusCommunity():\n"; std::cerr << "neededGenSize: " << neededGenSize << "\n"; std::cerr << "neededConSize: " << neededConSize << "\n"; @@ -139,7 +153,7 @@ void Surplus::CalculateSurplusCommunity(Community &community, Building::Base &ba } - for (auto &&[needed_g, needed_c, con_after,gen_after,con_from,gen_to, con_available, gen_available, isGenBigger]: + for (auto&& [needed_g, needed_c, con_after,gen_after,con_from,gen_to, con_available, gen_available, isGenBigger] : std::views::zip( base.values()->needed_gen(), base.values()->needed_con(), @@ -150,11 +164,15 @@ void Surplus::CalculateSurplusCommunity(Community &community, Building::Base &ba community.consumption_available(), community.generation_available(), community.is_gen_bigger_than_con() - )) { - if (isGenBigger) { + )) + { + if (isGenBigger) + { con_from = needed_g; gen_to = needed_g / gen_available * con_available; - } else { + } + else + { con_from = needed_c / con_available * gen_available; gen_to = needed_c; } @@ -162,13 +180,15 @@ void Surplus::CalculateSurplusCommunity(Community &community, Building::Base &ba gen_after = needed_g - gen_to; } CalculateSums(base); - if (base.metadata()->annual_consumption() != 0) { + if (base.metadata()->annual_consumption() != 0) + { base.values()->set_con_from_community_relative( std::accumulate(base.values()->consumption_from_community().begin(), base.values()->consumption_from_community().end(), 0.0f) / base.metadata()->annual_consumption()); } - if (base.metadata()->annual_generation() != 0) { + if (base.metadata()->annual_generation() != 0) + { base.values()->set_gen_to_community_relative( std::accumulate(base.values()->generation_to_community().begin(), base.values()->generation_to_community().end(), @@ -176,14 +196,21 @@ void Surplus::CalculateSurplusCommunity(Community &community, Building::Base &ba } } -void Surplus::CalculateSums(Building::Base &base) { +void Surplus::CalculateSums(Building::Base& base) +{ const auto& values = base.values(); - values->set_consumption_after_own_coverage_sum(std::accumulate(values->consumption_after_own_coverage().begin(),values->consumption_after_own_coverage().end(),0.f)); - values->set_own_usage_sum(std::accumulate(values->own_usage().begin(),values->own_usage().end(),0.f)); - values->set_needed_con_sum(std::accumulate(values->needed_con().begin(),values->needed_con().end(),0.f)); - values->set_needed_gen_sum(std::accumulate(values->needed_gen().begin(),values->needed_gen().end(),0.f)); - values->set_consumption_after_community_sum(std::accumulate(values->consumption_after_community().begin(),values->consumption_after_community().end(),0.f)); - values->set_generation_after_community_sum(std::accumulate(values->generation_after_community().begin(),values->generation_after_community().end(),0.f)); - values->set_consumption_from_community_sum(std::accumulate(values->consumption_from_community().begin(),values->consumption_from_community().end(),0.f)); - values->set_generation_to_community_sum(std::accumulate(values->generation_to_community().begin(),values->generation_to_community().end(),0.f)); -} \ No newline at end of file + values->set_consumption_after_own_coverage_sum(std::accumulate(values->consumption_after_own_coverage().begin(), + values->consumption_after_own_coverage().end(), + 0.f)); + values->set_own_usage_sum(std::accumulate(values->own_usage().begin(), values->own_usage().end(), 0.f)); + values->set_needed_con_sum(std::accumulate(values->needed_con().begin(), values->needed_con().end(), 0.f)); + values->set_needed_gen_sum(std::accumulate(values->needed_gen().begin(), values->needed_gen().end(), 0.f)); + values->set_consumption_after_community_sum(std::accumulate(values->consumption_after_community().begin(), + values->consumption_after_community().end(), 0.f)); + values->set_generation_after_community_sum(std::accumulate(values->generation_after_community().begin(), + values->generation_after_community().end(), 0.f)); + values->set_consumption_from_community_sum(std::accumulate(values->consumption_from_community().begin(), + values->consumption_from_community().end(), 0.f)); + values->set_generation_to_community_sum(std::accumulate(values->generation_to_community().begin(), + values->generation_to_community().end(), 0.f)); +} diff --git a/src/services/Surplus.h b/src/services/Surplus.h index eedda32..504eee9 100644 --- a/src/services/Surplus.h +++ b/src/services/Surplus.h @@ -11,25 +11,27 @@ #include -class Surplus { +class Surplus +{ private: - std::vector > &communities; + std::vector>& communities; std::vector consumptionAvailable; std::vector generationAvailable; public: - explicit Surplus(std::vector > &communities) : communities(communities), - consumptionAvailable(VALUE_COUNT, 0.0f), - generationAvailable(VALUE_COUNT, 0.0f) { + explicit Surplus(std::vector>& communities) : communities(communities), + consumptionAvailable(VALUE_COUNT, 0.0f), + generationAvailable(VALUE_COUNT, 0.0f) + { } void CalculateSurplus(); - void CalculateBuildingSurplus(Community &community, Building::Base &); + void CalculateBuildingSurplus(Community& community, Building::Base&); - void CalculateSurplusCommunity(Community &community, Building::Base &base); + void CalculateSurplusCommunity(Community& community, Building::Base& base); - void CalculateSums(Building::Base &base); + void CalculateSums(Building::Base& base); }; diff --git a/src/singelton/UsageProfile.cpp b/src/singelton/UsageProfile.cpp new file mode 100644 index 0000000..1981576 --- /dev/null +++ b/src/singelton/UsageProfile.cpp @@ -0,0 +1,9 @@ +// +// Created by stani on 3/14/2025. +// + +#include "UsageProfile.h" + + +std::mutex UsageProfile::mtx; +UsageProfile* UsageProfile::instance = nullptr; diff --git a/src/singelton/UsageProfile.h b/src/singelton/UsageProfile.h new file mode 100644 index 0000000..aa84633 --- /dev/null +++ b/src/singelton/UsageProfile.h @@ -0,0 +1,49 @@ +// +// Created by stani on 3/14/2025. +// + +#ifndef USAGEPROFILE_H +#define USAGEPROFILE_H +#include +#include "../Config.h" +#include "../helper/CsvBinary.h" + +class UsageProfile +{ +public: + static UsageProfile* getInstance() + { + std::lock_guard lock(mtx); + if (!instance) + { + instance = new UsageProfile(); + } + return instance; + } + + static void destroyInstance() + { + delete instance; + instance = nullptr; + } + + UsageProfile(const UsageProfile&) = delete; + UsageProfile& operator=(const UsageProfile&) = delete; + + usageProfile ConsumptionProfile; + usageProfile GenerationProfile; + +private: + UsageProfile(): ConsumptionProfile(CsvBinary::binaryToVector("Verbrauchsprofile.bin")), + GenerationProfile(CsvBinary::binaryToVector("ErzeugerProfile.bin")) + { + }; + + ~UsageProfile() = default; + + static UsageProfile* instance; + static std::mutex mtx; +}; + + +#endif //USAGEPROFILE_H diff --git a/tests/helper/test_CsvBinary.cpp b/tests/helper/test_CsvBinary.cpp index 08ebf02..899523a 100644 --- a/tests/helper/test_CsvBinary.cpp +++ b/tests/helper/test_CsvBinary.cpp @@ -12,12 +12,11 @@ TEST_CASE("Test Csv to binary and back") { CsvBinary::csvToBinary("Verbrauchsprofile.csv","Verbrauchsprofil.bin"); - CsvBinary::binaryToCsv("Verbrauchsprofil.bin","Restored.csv"); auto verbrauchsProfil = CsvBinary::binaryToVector("Verbrauchsprofil.bin"); - for (auto &row: *verbrauchsProfil) { - LOG_DEBUG_INFO("Sum from {}: {}",row.first ,std::accumulate( - row.second.begin(), row.second.end(), 0.f, - [](float sum, const std::string& val) { + for (const auto & [fst, snd]: *verbrauchsProfil) { + LOG_DEBUG_INFO("Sum from {}: {}",fst ,std::accumulate( + snd.begin(), snd.end(), 0.f, + [](const float sum, const std::string& val) { return sum + std::stof(val); // Convert string to float before addition } ));