diff --git a/CMakeLists.txt b/CMakeLists.txt
index 99ba91acd1eaae9beffe3b64a8f7588c7e0ab9fe..976a40f96e21c5cc825db90bec7ab36a5da55cff 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -41,6 +41,7 @@ add_library(common OBJECT
         src/Services/EventActionService.cpp
         src/Services/TimeBasedSchedulingService.cpp
         src/Services/FunctionManagementService.cpp
+        src/Services/HousekeepingService.cpp
         src/Services/ParameterStatisticsService.cpp
         src/Helpers/Statistic.cpp
         )
diff --git a/inc/ECSS_Definitions.hpp b/inc/ECSS_Definitions.hpp
index 5f8b5ef24bde1effc062e50dfc6ff87d2d2bf818..cf90152f45211e38fffb6e459c4abfd3abf58bae 100644
--- a/inc/ECSS_Definitions.hpp
+++ b/inc/ECSS_Definitions.hpp
@@ -113,9 +113,9 @@ inline const uint16_t ECSSEventActionStructMapSize = 256;
 inline const uint8_t ECSSMaxDeltaOfReleaseTime = 60;
 
 /**
- * The maximum number of stored parameters in the \ref ParameterService
+ * The max number of simply commutated parameters per housekeeping structure in ST[03]
  */
-inline const uint8_t ECSSMaxParameters = 5;
+inline const uint16_t ECSSMaxSimplyCommutatedParameters = 10;
 
 /**
  * The number of functions supported by the \ref FunctionManagementService
@@ -134,8 +134,6 @@ inline const uint8_t ECSSFunctionNameLength = 32;
  */
 inline const uint8_t ECSSFunctionMaxArgLength = 32;
 
-/** @} */
-
 /**
  * @brief The maximum size of a log message
  */
@@ -144,7 +142,7 @@ inline const uint16_t LoggerMaxMessageSize = 512;
 /**
  * @brief Size of the array holding the Parameter objects for the ST[20] parameter service
  */
-inline const uint8_t ECSSParameterCount = 4;
+inline const uint8_t ECSSParameterCount = 12;
 
 /**
  * @brief Defines whether the optional CRC field is included
@@ -161,4 +159,11 @@ inline const uint8_t ECSSMaxStatisticParameters = 4;
  */
 inline const bool SupportsStandardDeviation = true;
 
+/**
+ * @brief Defines the max number of housekeeping structs that the housekeeping service can contain
+ */
+inline const uint8_t ECSSMaxHousekeepingStructures = 10;
+
+/** @} */
+
 #endif // ECSS_SERVICES_ECSS_DEFINITIONS_H
diff --git a/inc/ErrorHandler.hpp b/inc/ErrorHandler.hpp
index d836ba26a95d90745c85c166699a65ef373294be..2936e1f2ffb4d7c5f7f41e281cde943c9936969a 100644
--- a/inc/ErrorHandler.hpp
+++ b/inc/ErrorHandler.hpp
@@ -76,7 +76,15 @@ public:
 		/**
 		 * A Message that is included within another message is too large
 		 */
-		NestedMessageTooLarge = 11
+		NestedMessageTooLarge = 11,
+		/**
+		 * A request to access a non existing housekeeping structure in ST[03]
+		 */
+		NonExistentHousekeeping = 12,
+		/**
+		 * Attempt to access an invalid parameter in ST[03]
+		 */
+		NonExistentParameter = 13,
 	};
 
 	/**
@@ -144,23 +152,54 @@ public:
 		 */
 		GetNonExistingParameter = 8,
 		/**
-		 * Attempt to set a reporting rate which is smaller than the parameter sampling rate.
-		 * ST[04]
+		 * Attempt to add definition to the struct map but its already full. (ST[19])
 		 */
-		InvalidReportingRateError = 9,
+		EventActionDefinitionsMapIsFull = 11,
 		/**
-		 * Attempt to set a sampling rate which is greater than the parameter reporting rate.
+		 * Attempt to report/delete non existing housekeeping structure (ST[03])
+		 */
+		RequestedNonExistingStructure = 12,
+		/**
+		 * Attempt to create already created structure (ST[03])
+		 */
+		RequestedAlreadyExistingStructure = 13,
+		/**
+		 * Attempt to delete structure which has the periodic reporting status enabled (ST[03]) as per 6.3.3.5.2(d-2)
+		 */
+		RequestedDeletionOfEnabledHousekeeping = 14,
+		/**
+		 * Attempt to append a new parameter ID to a housekeeping structure, but the ID is already in the structure
+		 * (ST[03])
+		 */
+		AlreadyExistingParameter = 15,
+		/**
+		 * Attempt to append a new parameter id to a housekeeping structure, but the periodic generation status is
+		 * enabled (ST[03])
+		 */
+		RequestedAppendToEnabledHousekeeping = 16,
+		/**
+		 * Attempt to create a new housekeeping structure in Housekeeping Service, when the maximum number of
+		 * housekeeping structures is already reached (ST[03])
+		 */
+		ExceededMaxNumberOfHousekeepingStructures = 17,
+		/**
+		 * Attempt to add a new simply commutated parameter in a specific housekeeping structure, but the maximum
+		 * number of simply commutated parameters for this structure is already reached (ST[03])
+		 */
+		ExceededMaxNumberOfSimplyCommutatedParameters = 18,
+		/* Attempt to set a reporting rate which is smaller than the parameter sampling rate.
 		 * ST[04]
 		 */
-		InvalidSamplingRateError = 10,
+		InvalidReportingRateError = 19,
 		/**
-		 * Attempt to add definition to the struct map but its already full. (ST[19])
+		 * Attempt to set a sampling rate which is greater than the parameter reporting rate.
+		 * ST[04]
 		 */
-		EventActionDefinitionsMapIsFull = 11,
+		InvalidSamplingRateError = 20,
 		/**
 		 * Attempt to add new statistic definition but the maximum number is already reached (ST[04])
 		 */
-		MaxStatisticDefinitionsReached = 12,
+		MaxStatisticDefinitionsReached = 21,
 	};
 
 	/**
diff --git a/inc/Helpers/HousekeepingStructure.hpp b/inc/Helpers/HousekeepingStructure.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..1e75430829b003bf49b83002a59dfddc068879f6
--- /dev/null
+++ b/inc/Helpers/HousekeepingStructure.hpp
@@ -0,0 +1,35 @@
+#ifndef ECSS_SERVICES_HOUSEKEEPINGSTRUCTURE_HPP
+#define ECSS_SERVICES_HOUSEKEEPINGSTRUCTURE_HPP
+
+#include "ECSS_Definitions.hpp"
+#include "ErrorHandler.hpp"
+#include "etl/vector.h"
+#include "Helpers/Parameter.hpp"
+
+/**
+ * Implementation of the Housekeeping report structure used by the Housekeeping Reporting Subservice (ST[03]). The
+ * current version includes only simply commutated parameters, i.e. parameters that contain a single sampled value.
+ *
+ * @author Petridis Konstantinos <petridkon@gmail.com>
+ */
+class HousekeepingStructure {
+public:
+	uint8_t structureId;
+	/**
+	 * Defined as integer multiples of the minimum sampling interval as per 6.3.3.2.c.5 #NOTE-2.
+	 */
+	uint32_t collectionInterval = 0;
+	/**
+	 * Indicates whether the periodic generation of housekeeping reports is enabled.
+	 */
+	bool periodicGenerationActionStatus = false;
+
+	/**
+	 * Vector containing the IDs of the simply commutated parameters, contained in the housekeeping structure.
+	 */
+	etl::vector<uint16_t, ECSSMaxSimplyCommutatedParameters> simplyCommutatedParameterIds;
+
+	HousekeepingStructure() = default;
+};
+
+#endif
\ No newline at end of file
diff --git a/inc/Helpers/Parameter.hpp b/inc/Helpers/Parameter.hpp
index 7967011acf674d70453a84fa8b0990e6c902f983..ccc55ae9d8e24241afd8176f50ccf373a55130ec 100644
--- a/inc/Helpers/Parameter.hpp
+++ b/inc/Helpers/Parameter.hpp
@@ -54,7 +54,7 @@ public:
 		currentValue = value;
 	}
 
-	DataType getValue() {
+	inline DataType getValue() {
 		return currentValue;
 	}
 
diff --git a/inc/Platform/x86/ECSS_Configuration.hpp b/inc/Platform/x86/ECSS_Configuration.hpp
index 1e7f59f29fe3c3c2d081d35614c4ed2baa0f79db..07a47a4c254d5fb787f806e4c21aaeb4ae572d8a 100644
--- a/inc/Platform/x86/ECSS_Configuration.hpp
+++ b/inc/Platform/x86/ECSS_Configuration.hpp
@@ -24,6 +24,7 @@
 #define SERVICE_EVENTACTION         ///<  Compile ST[19] event-action
 #define SERVICE_EVENTREPORT         ///<  Compile ST[05] event reporting
 #define SERVICE_FUNCTION            ///<  Compile ST[08] function management
+#define SERVICE_HOUSEKEEPING        ///<  Compile ST[03] housekeeping
 #define SERVICE_LARGEPACKET         ///<  Compile ST[13] large packet transfer
 #define SERVICE_MEMORY              ///<  Compile ST[06] memory management
 #define SERVICE_PARAMETER           ///<  Compile ST[20] parameter management
diff --git a/inc/Platform/x86/Parameters/SystemParameters.hpp b/inc/Platform/x86/Parameters/SystemParameters.hpp
index a1a834afc32154f620880a76f5331ac10fb7a503..1ef75b416f65a0cf4497a7d74154ccf95894f2a5 100644
--- a/inc/Platform/x86/Parameters/SystemParameters.hpp
+++ b/inc/Platform/x86/Parameters/SystemParameters.hpp
@@ -1,4 +1,8 @@
+#ifndef ECSS_SERVICES_SYSTEMPARAMETERS_HPP
+#define ECSS_SERVICES_SYSTEMPARAMETERS_HPP
+
 #include "Helpers/Parameter.hpp"
+#include <optional>
 #include "etl/vector.h"
 /**
  * @author Athanasios Theocharis <athatheoc@gmail.com>
@@ -19,14 +23,39 @@ public:
 	Parameter<uint8_t> parameter1 = Parameter<uint8_t>(3);
 	Parameter<uint16_t> parameter2 = Parameter<uint16_t>(7);
 	Parameter<uint32_t> parameter3 = Parameter<uint32_t>(10);
-	Parameter<uint32_t> parameter4 = Parameter<uint32_t>(24);
+	Parameter<uint32_t> parameter4 = Parameter<uint32_t>(5);
+	Parameter<uint8_t> parameter5 = Parameter<uint8_t>(11);
+	Parameter<uint32_t> parameter6 = Parameter<uint32_t>(23);
+	Parameter<uint32_t> parameter7 = Parameter<uint32_t>(53);
+	Parameter<uint8_t> parameter8 = Parameter<uint8_t>(55);
+	Parameter<uint16_t> parameter9 = Parameter<uint16_t>(32);
+	Parameter<uint32_t> parameter10 = Parameter<uint32_t>(43);
+	Parameter<uint32_t> parameter11 = Parameter<uint32_t>(91);
+	Parameter<uint8_t> parameter12 = Parameter<uint8_t>(1);
+
 	/**
 	 * The key of the array is the ID of the parameter as specified in PUS
 	 */
-	etl::array<std::reference_wrapper<ParameterBase>, ECSSParameterCount> parametersArray = {parameter1, parameter2,
-	                                                                                           parameter3, parameter4};
+	etl::array<std::reference_wrapper<ParameterBase>, ECSSParameterCount> parametersArray = {
+	    parameter1, parameter2, parameter3, parameter4,  parameter5,  parameter6,
+	    parameter7, parameter8, parameter9, parameter10, parameter11, parameter12};
 
 	SystemParameters() = default;
+
+	/**
+	 * This is a simple getter function, which returns a reference to a specified parameter, from the parametersArray.
+	 *
+	 * @param parameterId the id of the parameter, whose reference is to be returned.
+	 */
+	std::optional<std::reference_wrapper<ParameterBase>> getParameter(uint16_t parameterId) {
+		if (parameterId >= parametersArray.size()) {
+			ErrorHandler::reportInternalError(ErrorHandler::InternalErrorType::NonExistentParameter);
+			return {};
+		}
+		return parametersArray[parameterId];
+	}
 };
 
 extern SystemParameters systemParameters;
+
+#endif
diff --git a/inc/ServicePool.hpp b/inc/ServicePool.hpp
index 7666d416803a0d701dc07f5aff2eac42e8540fd3..544b7460c93ca76b53d3ff76d5f321750085efb3 100644
--- a/inc/ServicePool.hpp
+++ b/inc/ServicePool.hpp
@@ -11,6 +11,7 @@
 #include "Services/TestService.hpp"
 #include "Services/MemoryManagementService.hpp"
 #include "Services/FunctionManagementService.hpp"
+#include "Services/HousekeepingService.hpp"
 #include "Services/ParameterStatisticsService.hpp"
 
 /**
@@ -51,6 +52,10 @@ public:
 	FunctionManagementService functionManagement;
 #endif
 
+#ifdef SERVICE_HOUSEKEEPING
+	HousekeepingService housekeeping;
+#endif
+
 #ifdef SERVICE_LARGEPACKET
 	LargePacketTransferService largePacketTransferService;
 #endif
diff --git a/inc/Services/HousekeepingService.hpp b/inc/Services/HousekeepingService.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..a3a902127a8382f14bf71ab5e1a2676732c38c86
--- /dev/null
+++ b/inc/Services/HousekeepingService.hpp
@@ -0,0 +1,134 @@
+#ifndef ECSS_SERVICES_HOUSEKEEPINGSERVICE_HPP
+#define ECSS_SERVICES_HOUSEKEEPINGSERVICE_HPP
+
+#include "etl/map.h"
+#include "ECSS_Definitions.hpp"
+#include "Service.hpp"
+#include "ErrorHandler.hpp"
+#include "Parameters/SystemParameters.hpp"
+#include "Helpers/HousekeepingStructure.hpp"
+
+/**
+ * Implementation of the ST[03] Housekeeping Reporting Service. The job of the Housekeeping Service is to store
+ * parameters in the housekeeping structures so that it can generate housekeeping reports periodically.
+ *
+ * @author Petridis Konstantinos <petridkon@gmail.com>
+ */
+class HousekeepingService : Service {
+private:
+	/**
+	 * Appends the periodic properties of a housekeeping structure to a message.
+	 *
+	 * @note The structureId is checked before being passed in this function, so there is a convention that the ID is
+	 * valid. If this function needs to be called from another point of the code, the case of an invalid ID passed as
+	 * argument will lead in undefined behavior.
+	 */
+	void appendPeriodicPropertiesToMessage(Message& report, uint8_t structureId);
+
+	/**
+	 * Returns true if the given parameter ID exists in the parameters contained in the housekeeping structure.
+	 */
+	static bool existsInVector(const etl::vector<uint16_t, ECSSMaxSimplyCommutatedParameters>& ids,
+	                           uint16_t parameterId);
+
+public:
+	inline static const uint8_t ServiceType = 3;
+
+	/**
+	 * Map containing the housekeeping structures. Map[i] contains the housekeeping structure with ID = i.
+	 */
+	etl::map<uint8_t, HousekeepingStructure, ECSSMaxHousekeepingStructures> housekeepingStructures;
+
+	enum MessageType : uint8_t {
+		CreateHousekeepingReportStructure = 1,
+		DeleteHousekeepingReportStructure = 3,
+		EnablePeriodicHousekeepingParametersReport = 5,
+		DisablePeriodicHousekeepingParametersReport = 6,
+		ReportHousekeepingStructures = 9,
+		HousekeepingStructuresReport = 10,
+		HousekeepingParametersReport = 25,
+		GenerateOneShotHousekeepingReport = 27,
+		AppendParametersToHousekeepingStructure = 29,
+		ModifyCollectionIntervalOfStructures = 31,
+		ReportHousekeepingPeriodicProperties = 33,
+		HousekeepingPeriodicPropertiesReport = 35,
+	};
+
+	HousekeepingService() = default;
+
+	/**
+	 * Implementation of TC[3,1]. Request to create a housekeeping parameters report structure.
+	 */
+	void createHousekeepingReportStructure(Message& request);
+
+	/**
+	 * Implementation of TC[3,3]. Request to delete a housekeeping parameters report structure.
+	 */
+	void deleteHousekeepingReportStructure(Message& request);
+
+	/**
+	 * Implementation of TC[3,5]. Request to enable the periodic housekeeping parameters reporting for a specific
+	 * housekeeping structure.
+	 */
+	void enablePeriodicHousekeepingParametersReport(Message& request);
+
+	/**
+	 * Implementation of TC[3,6]. Request to disable the periodic housekeeping parameters reporting for a specific
+	 * housekeeping structure.
+	 */
+	void disablePeriodicHousekeepingParametersReport(Message& request);
+
+	/**
+	 * This function gets a message type TC[3,9] 'report housekeeping structures'.
+	 */
+	void reportHousekeepingStructures(Message& request);
+
+	/**
+	 * This function takes a structure ID as argument and constructs/stores a TM[3,10] housekeeping structure report.
+	 */
+	void housekeepingStructureReport(uint8_t structIdToReport);
+
+	/**
+	 * This function gets a housekeeping structure ID and stores a TM[3,25] 'housekeeping
+	 * parameter report' message.
+	 */
+	void housekeepingParametersReport(uint8_t structureId);
+
+	/**
+	 * This function takes as argument a message type TC[3,27] 'generate one shot housekeeping report' and stores
+	 * TM[3,25] report messages.
+	 */
+	void generateOneShotHousekeepingReport(Message& request);
+
+	/**
+	 * This function receives a message type TC[3,29] 'append new parameters to an already existing housekeeping
+	 * structure'
+	 *
+	 * @note As per 6.3.3.8.d.4, in case of an invalid parameter, the whole message shall be rejected. However, a
+	 * convention was made, saying that it would be more practical to just skip the invalid parameter and continue
+	 * processing the rest of the message.
+	 */
+	void appendParametersToHousekeepingStructure(Message& request);
+
+	/**
+	 * This function receives a message type TC[3,31] 'modify the collection interval of specified structures'.
+	 */
+	void modifyCollectionIntervalOfStructures(Message& request);
+
+	/**
+	 * This function takes as argument a message type TC[3,33] 'report housekeeping periodic properties' and
+	 * responds with a TM[3,35] 'housekeeping periodic properties report'.
+	 */
+	void reportHousekeepingPeriodicProperties(Message& request);
+
+	/**
+	 * It is responsible to call the suitable function that executes a TC packet. The source of that packet
+	 * is the ground station.
+	 *
+	 * @note This function is called from the main execute() that is defined in the file MessageParser.hpp
+	 * @param message Contains the necessary parameters to call the suitable subservice
+	 */
+	void execute(Message& message);
+};
+
+#endif
\ No newline at end of file
diff --git a/inc/Services/ParameterService.hpp b/inc/Services/ParameterService.hpp
index eefbea6e0b487d61f53a8b9b61c709698a3cbeab..112476436420e5e454f9dfc0ccd8957b4da08ecf 100644
--- a/inc/Services/ParameterService.hpp
+++ b/inc/Services/ParameterService.hpp
@@ -23,7 +23,6 @@
  */
 class ParameterService : public Service {
 public:
-
 	inline static const uint8_t ServiceType = 20;
 
 	enum MessageType : uint8_t {
diff --git a/src/MessageParser.cpp b/src/MessageParser.cpp
index f0938627aaab14baa05046c01d23ef7ad551b54f..c35c525bb5d3f1fb8b5010d1104a9c845da387af 100644
--- a/src/MessageParser.cpp
+++ b/src/MessageParser.cpp
@@ -7,6 +7,12 @@
 
 void MessageParser::execute(Message& message) {
 	switch (message.serviceType) {
+#ifdef SERVICE_HOUSEKEEPING
+		case HousekeepingService::ServiceType:
+			Services.housekeeping.execute(message);
+			break;
+#endif
+
 #ifdef SERVICE_PARAMETERSTATISTICS
 		case ParameterStatisticsService::ServiceType:
 			Services.parameterStatistics.execute(message);
diff --git a/src/Services/HousekeepingService.cpp b/src/Services/HousekeepingService.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..41888caafa883c6602ec90f38b9732c057f52389
--- /dev/null
+++ b/src/Services/HousekeepingService.cpp
@@ -0,0 +1,260 @@
+#include "Services/HousekeepingService.hpp"
+
+void HousekeepingService::createHousekeepingReportStructure(Message& request) {
+	request.assertTC(ServiceType, MessageType::CreateHousekeepingReportStructure);
+
+	uint8_t idToCreate = request.readUint8();
+	if (housekeepingStructures.find(idToCreate) != housekeepingStructures.end()) {
+		ErrorHandler::reportError(request, ErrorHandler::ExecutionStartErrorType::RequestedAlreadyExistingStructure);
+		return;
+	}
+	if (housekeepingStructures.size() >= ECSSMaxHousekeepingStructures) {
+		ErrorHandler::reportError(request,
+		                          ErrorHandler::ExecutionStartErrorType::ExceededMaxNumberOfHousekeepingStructures);
+		return;
+	}
+	HousekeepingStructure newStructure;
+	newStructure.structureId = idToCreate;
+	newStructure.collectionInterval = request.readUint32();
+	newStructure.periodicGenerationActionStatus = false;
+
+	uint16_t numOfSimplyCommutatedParams = request.readUint16();
+
+	for (uint16_t i = 0; i < numOfSimplyCommutatedParams; i++) {
+		uint16_t newParamId = request.readUint16();
+		if (existsInVector(newStructure.simplyCommutatedParameterIds, newParamId)) {
+			ErrorHandler::reportError(request, ErrorHandler::ExecutionStartErrorType::AlreadyExistingParameter);
+			continue;
+		}
+		newStructure.simplyCommutatedParameterIds.push_back(newParamId);
+	}
+	housekeepingStructures.insert({idToCreate, newStructure});
+}
+
+void HousekeepingService::deleteHousekeepingReportStructure(Message& request) {
+	request.assertTC(ServiceType, MessageType::DeleteHousekeepingReportStructure);
+	uint8_t numOfStructuresToDelete = request.readUint8();
+	for (uint8_t i = 0; i < numOfStructuresToDelete; i++) {
+		uint8_t structureId = request.readUint8();
+		if (housekeepingStructures.find(structureId) == housekeepingStructures.end()) {
+			ErrorHandler::reportError(request, ErrorHandler::ExecutionStartErrorType::RequestedNonExistingStructure);
+			continue;
+		}
+		if (housekeepingStructures.at(structureId).periodicGenerationActionStatus) {
+			ErrorHandler::reportError(request,
+			                          ErrorHandler::ExecutionStartErrorType::RequestedDeletionOfEnabledHousekeeping);
+			continue;
+		}
+		housekeepingStructures.erase(structureId);
+	}
+}
+
+void HousekeepingService::enablePeriodicHousekeepingParametersReport(Message& request) {
+	request.assertTC(ServiceType, MessageType::EnablePeriodicHousekeepingParametersReport);
+
+	uint8_t numOfStructIds = request.readUint8();
+	for (uint8_t i = 0; i < numOfStructIds; i++) {
+		uint8_t structIdToEnable = request.readUint8();
+		if (housekeepingStructures.find(structIdToEnable) == housekeepingStructures.end()) {
+			ErrorHandler::reportError(request, ErrorHandler::RequestedNonExistingStructure);
+			continue;
+		}
+		housekeepingStructures.at(structIdToEnable).periodicGenerationActionStatus = true;
+	}
+}
+
+void HousekeepingService::disablePeriodicHousekeepingParametersReport(Message& request) {
+	request.assertTC(ServiceType, MessageType::DisablePeriodicHousekeepingParametersReport);
+
+	uint8_t numOfStructIds = request.readUint8();
+	for (uint8_t i = 0; i < numOfStructIds; i++) {
+		uint8_t structIdToDisable = request.readUint8();
+		if (housekeepingStructures.find(structIdToDisable) == housekeepingStructures.end()) {
+			ErrorHandler::reportError(request, ErrorHandler::RequestedNonExistingStructure);
+			continue;
+		}
+		housekeepingStructures.at(structIdToDisable).periodicGenerationActionStatus = false;
+	}
+}
+
+void HousekeepingService::reportHousekeepingStructures(Message& request) {
+	request.assertTC(ServiceType, MessageType::ReportHousekeepingStructures);
+
+	uint8_t numOfStructsToReport = request.readUint8();
+	for (uint8_t i = 0; i < numOfStructsToReport; i++) {
+		uint8_t structureId = request.readUint8();
+		if (housekeepingStructures.find(structureId) == housekeepingStructures.end()) {
+			ErrorHandler::reportError(request, ErrorHandler::ExecutionStartErrorType::RequestedNonExistingStructure);
+			continue;
+		}
+		housekeepingStructureReport(structureId);
+	}
+}
+
+void HousekeepingService::housekeepingStructureReport(uint8_t structIdToReport) {
+	auto housekeepingStructure = housekeepingStructures.find(structIdToReport);
+	if (housekeepingStructure == housekeepingStructures.end()) {
+		ErrorHandler::reportInternalError(ErrorHandler::InternalErrorType::NonExistentHousekeeping);
+		return;
+	}
+	Message structReport(ServiceType, MessageType::HousekeepingStructuresReport, Message::TM, 1);
+	structReport.appendUint8(structIdToReport);
+
+	structReport.appendBoolean(housekeepingStructure->second.periodicGenerationActionStatus);
+	structReport.appendUint32(housekeepingStructure->second.collectionInterval);
+	structReport.appendUint16(housekeepingStructure->second.simplyCommutatedParameterIds.size());
+
+	for (auto parameterId : housekeepingStructure->second.simplyCommutatedParameterIds) {
+		structReport.appendUint16(parameterId);
+	}
+	storeMessage(structReport);
+}
+
+void HousekeepingService::housekeepingParametersReport(uint8_t structureId) {
+	if (housekeepingStructures.find(structureId) == housekeepingStructures.end()) {
+		ErrorHandler::reportInternalError(ErrorHandler::InternalErrorType::NonExistentHousekeeping);
+		return;
+	}
+	Message housekeepingReport(ServiceType, MessageType::HousekeepingParametersReport, Message::TM, 1);
+
+	housekeepingReport.appendUint8(structureId);
+	for (auto id : housekeepingStructures.at(structureId).simplyCommutatedParameterIds) {
+		if (auto parameter = systemParameters.getParameter(id)) {
+			parameter->get().appendValueToMessage(housekeepingReport);
+		}
+	}
+	storeMessage(housekeepingReport);
+}
+
+void HousekeepingService::generateOneShotHousekeepingReport(Message& request) {
+	request.assertTC(ServiceType, MessageType::GenerateOneShotHousekeepingReport);
+
+	uint8_t numOfStructsToReport = request.readUint8();
+	for (uint8_t i = 0; i < numOfStructsToReport; i++) {
+		uint8_t structureId = request.readUint8();
+		if (housekeepingStructures.find(structureId) == housekeepingStructures.end()) {
+			ErrorHandler::reportError(request, ErrorHandler::ExecutionStartErrorType::RequestedNonExistingStructure);
+			continue;
+		}
+		housekeepingParametersReport(structureId);
+	}
+}
+
+void HousekeepingService::appendParametersToHousekeepingStructure(Message& request) {
+	request.assertTC(ServiceType, MessageType::AppendParametersToHousekeepingStructure);
+
+	uint8_t targetStructId = request.readUint8();
+	if (housekeepingStructures.find(targetStructId) == housekeepingStructures.end()) {
+		ErrorHandler::reportError(request, ErrorHandler::ExecutionStartErrorType::RequestedNonExistingStructure);
+		return;
+	}
+	auto& housekeepingStructure = housekeepingStructures.at(targetStructId);
+	if (housekeepingStructure.periodicGenerationActionStatus) {
+		ErrorHandler::reportError(request, ErrorHandler::ExecutionStartErrorType::RequestedAppendToEnabledHousekeeping);
+		return;
+	}
+	uint16_t numOfSimplyCommutatedParameters = request.readUint16();
+
+	for (uint16_t i = 0; i < numOfSimplyCommutatedParameters; i++) {
+		if (housekeepingStructure.simplyCommutatedParameterIds.size() >= ECSSMaxSimplyCommutatedParameters) {
+			ErrorHandler::reportError(
+			    request, ErrorHandler::ExecutionStartErrorType::ExceededMaxNumberOfSimplyCommutatedParameters);
+			return;
+		}
+		uint16_t newParamId = request.readUint16();
+		if (newParamId >= systemParameters.parametersArray.size()) {
+			ErrorHandler::reportError(request, ErrorHandler::ExecutionStartErrorType::GetNonExistingParameter);
+			continue;
+		}
+		if (existsInVector(housekeepingStructure.simplyCommutatedParameterIds, newParamId)) {
+			ErrorHandler::reportError(request, ErrorHandler::ExecutionStartErrorType::AlreadyExistingParameter);
+			continue;
+		}
+		housekeepingStructure.simplyCommutatedParameterIds.push_back(newParamId);
+	}
+}
+
+void HousekeepingService::modifyCollectionIntervalOfStructures(Message& request) {
+	request.assertTC(ServiceType, MessageType::ModifyCollectionIntervalOfStructures);
+
+	uint8_t numOfTargetStructs = request.readUint8();
+	for (uint8_t i = 0; i < numOfTargetStructs; i++) {
+		uint8_t targetStructId = request.readUint8();
+		uint32_t newCollectionInterval = request.readUint32();
+		if (housekeepingStructures.find(targetStructId) == housekeepingStructures.end()) {
+			ErrorHandler::reportError(request, ErrorHandler::ExecutionStartErrorType::RequestedNonExistingStructure);
+			continue;
+		}
+		housekeepingStructures.at(targetStructId).collectionInterval = newCollectionInterval;
+	}
+}
+
+void HousekeepingService::reportHousekeepingPeriodicProperties(Message& request) {
+	request.assertTC(ServiceType, MessageType::ReportHousekeepingPeriodicProperties);
+
+	uint8_t numOfValidIds = 0;
+	uint8_t numOfStructIds = request.readUint8();
+	for (uint8_t i = 0; i < numOfStructIds; i++) {
+		uint8_t structIdToReport = request.readUint8();
+		if (housekeepingStructures.find(structIdToReport) != housekeepingStructures.end()) {
+			numOfValidIds++;
+		}
+	}
+	Message periodicPropertiesReport(ServiceType, MessageType::HousekeepingPeriodicPropertiesReport, Message::TM, 1);
+	periodicPropertiesReport.appendUint8(numOfValidIds);
+	request.resetRead();
+	request.readUint8();
+
+	for (uint8_t i = 0; i < numOfStructIds; i++) {
+		uint8_t structIdToReport = request.readUint8();
+		if (housekeepingStructures.find(structIdToReport) == housekeepingStructures.end()) {
+			ErrorHandler::reportError(request, ErrorHandler::ExecutionStartErrorType::RequestedNonExistingStructure);
+			continue;
+		}
+		appendPeriodicPropertiesToMessage(periodicPropertiesReport, structIdToReport);
+	}
+	storeMessage(periodicPropertiesReport);
+}
+
+void HousekeepingService::appendPeriodicPropertiesToMessage(Message& report, uint8_t structureId) {
+	report.appendUint8(structureId);
+	report.appendBoolean(housekeepingStructures.at(structureId).periodicGenerationActionStatus);
+	report.appendUint32(housekeepingStructures.at(structureId).collectionInterval);
+}
+
+void HousekeepingService::execute(Message& message) {
+	switch (message.messageType) {
+		case CreateHousekeepingReportStructure:
+			createHousekeepingReportStructure(message);
+			break;
+		case DeleteHousekeepingReportStructure:
+			deleteHousekeepingReportStructure(message);
+			break;
+		case EnablePeriodicHousekeepingParametersReport:
+			enablePeriodicHousekeepingParametersReport(message);
+			break;
+		case DisablePeriodicHousekeepingParametersReport:
+			disablePeriodicHousekeepingParametersReport(message);
+			break;
+		case ReportHousekeepingStructures:
+			reportHousekeepingStructures(message);
+			break;
+		case GenerateOneShotHousekeepingReport:
+			generateOneShotHousekeepingReport(message);
+			break;
+		case AppendParametersToHousekeepingStructure:
+			appendParametersToHousekeepingStructure(message);
+			break;
+		case ModifyCollectionIntervalOfStructures:
+			modifyCollectionIntervalOfStructures(message);
+			break;
+		case ReportHousekeepingPeriodicProperties:
+			reportHousekeepingPeriodicProperties(message);
+			break;
+	}
+}
+
+bool HousekeepingService::existsInVector(const etl::vector<uint16_t, ECSSMaxSimplyCommutatedParameters>& ids,
+                                         uint16_t parameterId) {
+	return std::find(std::begin(ids), std::end(ids), parameterId) != std::end(ids);
+}
diff --git a/src/Services/ParameterService.cpp b/src/Services/ParameterService.cpp
index de4786275099ed5c73436a354f0e244849d7f94e..02c9d2189520facc0b067afd5105a619b4836298 100644
--- a/src/Services/ParameterService.cpp
+++ b/src/Services/ParameterService.cpp
@@ -7,7 +7,8 @@
 
 void ParameterService::reportParameters(Message& paramIds) {
 	// TM[20,2]
-	Message parameterReport(ParameterService::ServiceType, ParameterService::MessageType::ParameterValuesReport, Message::TM, 1);
+	Message parameterReport(ParameterService::ServiceType, ParameterService::MessageType::ParameterValuesReport,
+	                        Message::TM, 1);
 
 	ErrorHandler::assertRequest(paramIds.packetType == Message::TC, paramIds,
 	                            ErrorHandler::AcceptanceErrorType::UnacceptableMessage);
@@ -41,11 +42,10 @@ void ParameterService::reportParameters(Message& paramIds) {
 }
 
 void ParameterService::setParameters(Message& newParamValues) {
-
 	ErrorHandler::assertRequest(newParamValues.packetType == Message::TC, newParamValues,
 	                            ErrorHandler::AcceptanceErrorType::UnacceptableMessage);
-	ErrorHandler::assertRequest(newParamValues.messageType == ParameterService::MessageType::SetParameterValues, newParamValues,
-	                            ErrorHandler::AcceptanceErrorType::UnacceptableMessage);
+	ErrorHandler::assertRequest(newParamValues.messageType == ParameterService::MessageType::SetParameterValues,
+	                            newParamValues, ErrorHandler::AcceptanceErrorType::UnacceptableMessage);
 	ErrorHandler::assertRequest(newParamValues.serviceType == ParameterService::ServiceType, newParamValues,
 	                            ErrorHandler::AcceptanceErrorType::UnacceptableMessage);
 
diff --git a/test/Helpers/systemParameters.cpp b/test/Helpers/systemParameters.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..8d5223ecec6d860a83309fb243fd7e1687ad6de9
--- /dev/null
+++ b/test/Helpers/systemParameters.cpp
@@ -0,0 +1,22 @@
+#include "Platform/x86/Parameters/SystemParameters.hpp"
+#include "catch2/catch.hpp"
+#include "../Services/ServiceTests.hpp"
+
+TEST_CASE("Getting a reference of a parameter") {
+	SECTION("Valid parameter requested") {
+		uint16_t parameterId = 7;
+		REQUIRE(static_cast<Parameter<uint16_t>&>(systemParameters.getParameter(parameterId)->get()).getValue() == 55);
+
+		parameterId = 11;
+		REQUIRE(static_cast<Parameter<uint16_t>&>(systemParameters.getParameter(parameterId)->get()).getValue() == 1);
+	}
+
+	SECTION("Invalid parameter requested") {
+		uint16_t parameterId = systemParameters.parametersArray.size() + 1;
+		REQUIRE(not systemParameters.getParameter(parameterId));
+
+		parameterId = parameterId + 24;
+		REQUIRE(not systemParameters.getParameter(parameterId));
+		CHECK(ServiceTests::countThrownErrors(ErrorHandler::InternalErrorType::NonExistentParameter) == 2);
+	}
+}
\ No newline at end of file
diff --git a/test/Services/HousekeepingService.cpp b/test/Services/HousekeepingService.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..369803777fc14e1a0fb5a50c76241e8fef73d3f5
--- /dev/null
+++ b/test/Services/HousekeepingService.cpp
@@ -0,0 +1,620 @@
+#include <iostream>
+#include "catch2/catch.hpp"
+#include "Message.hpp"
+#include "ServiceTests.hpp"
+#include "Services/HousekeepingService.hpp"
+#include "etl/algorithm.h"
+
+HousekeepingService& housekeepingService = Services.housekeeping;
+
+/**
+ * Helper function that forms the message that's going to be sent as request to create a new housekeeping structure.
+ */
+void buildRequest(Message& request, uint8_t idToCreate) {
+	uint32_t interval = 7;
+	uint16_t numOfSimplyCommutatedParams = 3;
+	etl::vector<uint16_t, 3> simplyCommutatedIds = {8, 4, 5};
+
+	request.appendUint8(idToCreate);
+	request.appendUint32(interval);
+	request.appendUint16(numOfSimplyCommutatedParams);
+	for (auto& id : simplyCommutatedIds) {
+		request.appendUint16(id);
+	}
+}
+
+/**
+ * Initializes 3 housekeeping structures with IDs = {0, 4, 6}
+ */
+void initializeHousekeepingStructures() {
+	uint8_t ids[3] = {0, 4, 6};
+	uint32_t interval = 7;
+	etl::vector<uint16_t, 3> simplyCommutatedIds = {8, 4, 5};
+
+	HousekeepingStructure structures[3];
+	int i = 0;
+	for (auto& newStructure : structures) {
+		newStructure.structureId = ids[i];
+		newStructure.collectionInterval = interval;
+		newStructure.periodicGenerationActionStatus = false;
+		for (uint16_t parameterId : simplyCommutatedIds) {
+			newStructure.simplyCommutatedParameterIds.push_back(parameterId);
+		}
+		housekeepingService.housekeepingStructures.insert({ids[i], newStructure});
+		i++;
+	}
+
+	REQUIRE(housekeepingService.housekeepingStructures.size() == 3);
+	REQUIRE(housekeepingService.housekeepingStructures.find(0) != housekeepingService.housekeepingStructures.end());
+	REQUIRE(housekeepingService.housekeepingStructures.find(4) != housekeepingService.housekeepingStructures.end());
+	REQUIRE(housekeepingService.housekeepingStructures.find(6) != housekeepingService.housekeepingStructures.end());
+}
+
+/**
+ * Helper function that stores samples into simply commutated parameters of different data type each.
+ */
+void storeSamplesToParameters(uint16_t id1, uint16_t id2, uint16_t id3) {
+	Message samples(HousekeepingService::ServiceType,
+	                HousekeepingService::MessageType::ReportHousekeepingPeriodicProperties, Message::TM, 1);
+
+	static_cast<Parameter<uint16_t>&>(systemParameters.parametersArray[id1].get()).setValue(33);
+	static_cast<Parameter<uint8_t>&>(systemParameters.parametersArray[id2].get()).setValue(77);
+	static_cast<Parameter<uint32_t>&>(systemParameters.parametersArray[id3].get()).setValue(99);
+}
+
+/**
+ * Helper function that forms the request to append new parameters to a housekeeping structure
+ */
+void appendNewParameters(Message& request, uint8_t idToAppend) {
+	uint16_t numOfSimplyCommutatedParams = 7;
+	etl::vector<uint16_t, 7> simplyCommutatedIds = {8, 4, 5, 9, 11, 10, 220};
+
+	request.appendUint8(idToAppend);
+	request.appendUint16(numOfSimplyCommutatedParams);
+	for (auto& id : simplyCommutatedIds) {
+		request.appendUint16(id);
+	}
+}
+
+TEST_CASE("Create housekeeping structure") {
+	SECTION("Valid structure creation request") {
+		Message request(HousekeepingService::ServiceType,
+		                HousekeepingService::MessageType::CreateHousekeepingReportStructure, Message::TC, 1);
+		uint8_t idToCreate = 2;
+		uint32_t interval = 7;
+		uint16_t numOfSimplyCommutatedParams = 3;
+		etl::array<uint16_t, 3> simplyCommutatedIds = {4, 5, 8};
+
+		request.appendUint8(idToCreate);
+		request.appendUint32(interval);
+		request.appendUint16(numOfSimplyCommutatedParams);
+		for (auto& id : simplyCommutatedIds) {
+			request.appendUint16(id);
+		}
+
+		MessageParser::execute(request);
+		HousekeepingStructure newStruct = housekeepingService.housekeepingStructures[idToCreate];
+
+		CHECK(ServiceTests::count() == 0);
+		CHECK(newStruct.structureId == idToCreate);
+		CHECK(newStruct.simplyCommutatedParameterIds.size() == numOfSimplyCommutatedParams);
+		CHECK(newStruct.collectionInterval == interval);
+		CHECK(std::equal(newStruct.simplyCommutatedParameterIds.begin(), newStruct.simplyCommutatedParameterIds.end(),
+		                 simplyCommutatedIds.begin()));
+
+		ServiceTests::reset();
+		Services.reset();
+	}
+
+	SECTION("Invalid structure creation request") {
+		Message request(HousekeepingService::ServiceType,
+		                HousekeepingService::MessageType::CreateHousekeepingReportStructure, Message::TC, 1);
+		uint8_t structureId = 9;
+		HousekeepingStructure structure1;
+		structure1.structureId = structureId;
+		housekeepingService.housekeepingStructures.insert({structureId, structure1});
+
+		uint8_t idToCreate = 9;
+		request.appendUint8(idToCreate);
+
+		MessageParser::execute(request);
+
+		CHECK(housekeepingService.housekeepingStructures.size() == 1);
+		CHECK(ServiceTests::count() == 1);
+		CHECK(ServiceTests::countThrownErrors(
+		          ErrorHandler::ExecutionStartErrorType::RequestedAlreadyExistingStructure) == 1);
+		housekeepingService.housekeepingStructures.erase(structureId);
+
+		ServiceTests::reset();
+		Services.reset();
+	}
+
+	SECTION("Exceeding max number of housekeeping structures") {
+		Message request(HousekeepingService::ServiceType,
+		                HousekeepingService::MessageType::CreateHousekeepingReportStructure, Message::TC, 1);
+
+		uint8_t idsToCreate[16] = {1, 3, 5, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19};
+		uint16_t numOfSimplyCommutatedParams = 3;
+		etl::vector<uint16_t, 3> simplyCommutatedIds = {8, 4, 5};
+		uint32_t interval = 12;
+
+		REQUIRE(housekeepingService.housekeepingStructures.size() == 0);
+
+		for (auto& structId : idsToCreate) {
+			request.appendUint8(structId);
+			request.appendUint32(interval);
+			request.appendUint16(numOfSimplyCommutatedParams);
+			for (auto& parameterId : simplyCommutatedIds) {
+				request.appendUint16(parameterId);
+			}
+			MessageParser::execute(request);
+		}
+
+		REQUIRE(housekeepingService.housekeepingStructures.size() == 10);
+		CHECK(ServiceTests::count() == 6);
+		CHECK(ServiceTests::countThrownErrors(
+		          ErrorHandler::ExecutionStartErrorType::ExceededMaxNumberOfHousekeepingStructures) == 5);
+
+		ServiceTests::reset();
+		Services.reset();
+	}
+
+	SECTION("Same simply commutated parameter twice in the request") {
+		Message request(HousekeepingService::ServiceType,
+		                HousekeepingService::MessageType::CreateHousekeepingReportStructure, Message::TC, 1);
+		uint8_t idToCreate = 2;
+		uint32_t interval = 7;
+		uint16_t numOfSimplyCommutatedParams = 9;
+		etl::vector<uint16_t, 9> simplyCommutatedIds = {8, 4, 5, 4, 8, 8, 5, 4, 11};
+
+		request.appendUint8(idToCreate);
+		request.appendUint32(interval);
+		request.appendUint16(numOfSimplyCommutatedParams);
+		for (auto& id : simplyCommutatedIds) {
+			request.appendUint16(id);
+		}
+
+		MessageParser::execute(request);
+
+		CHECK(ServiceTests::count() == 5);
+		CHECK(ServiceTests::countThrownErrors(ErrorHandler::ExecutionStartErrorType::AlreadyExistingParameter) == 5);
+		HousekeepingStructure newStruct = housekeepingService.housekeepingStructures[idToCreate];
+
+		REQUIRE(newStruct.simplyCommutatedParameterIds.size() == 4);
+		uint16_t existingParameterIds[4] = {8, 4, 5, 11};
+		for (auto parameterId : newStruct.simplyCommutatedParameterIds) {
+			CHECK(std::find(std::begin(existingParameterIds), std::end(existingParameterIds), parameterId) !=
+			      std::end(existingParameterIds));
+		}
+
+		ServiceTests::reset();
+		Services.reset();
+	}
+}
+
+TEST_CASE("Delete housekeeping structure") {
+	SECTION("One valid request, the rest invalid") {
+		Message createStruct(HousekeepingService::ServiceType,
+		                     HousekeepingService::MessageType::CreateHousekeepingReportStructure, Message::TC, 1);
+
+		buildRequest(createStruct, 2);
+		MessageParser::execute(createStruct);
+
+		REQUIRE(housekeepingService.housekeepingStructures.size() == 1);
+		REQUIRE(housekeepingService.housekeepingStructures.find(2) != housekeepingService.housekeepingStructures.end());
+		Message request(HousekeepingService::ServiceType,
+		                HousekeepingService::MessageType::DeleteHousekeepingReportStructure, Message::TC, 1);
+
+		uint8_t numOfStructs = 5;
+		uint8_t ids[5] = {2, 3, 4, 7, 8};
+		request.appendUint8(numOfStructs);
+		for (auto& id : ids) {
+			request.appendUint8(id);
+		}
+
+		MessageParser::execute(request);
+
+		CHECK(ServiceTests::count() == 4);
+		CHECK(ServiceTests::countThrownErrors(ErrorHandler::ExecutionStartErrorType::RequestedNonExistingStructure) ==
+		      4);
+
+		ServiceTests::reset();
+		Services.reset();
+	}
+
+	SECTION("Invalid request of periodic structure") {
+		Message request(HousekeepingService::ServiceType,
+		                HousekeepingService::MessageType::DeleteHousekeepingReportStructure, Message::TC, 1);
+		HousekeepingStructure periodicStruct;
+		periodicStruct.structureId = 4;
+		periodicStruct.periodicGenerationActionStatus = true;
+		housekeepingService.housekeepingStructures.insert({4, periodicStruct});
+
+		uint8_t numOfStructs = 1;
+		uint8_t structureId = 4;
+		request.appendUint8(numOfStructs);
+		request.appendUint8(structureId);
+
+		MessageParser::execute(request);
+
+		CHECK(ServiceTests::count() == 1);
+		CHECK(ServiceTests::countThrownErrors(
+		          ErrorHandler::ExecutionStartErrorType::RequestedDeletionOfEnabledHousekeeping) == 1);
+
+		ServiceTests::reset();
+		Services.reset();
+	}
+}
+
+TEST_CASE("Enable the periodic generation of housekeeping structures") {
+	SECTION("Both valid and invalid structure IDs in same request") {
+		initializeHousekeepingStructures();
+		Message request2(HousekeepingService::ServiceType,
+		                 HousekeepingService::MessageType::EnablePeriodicHousekeepingParametersReport, Message::TC, 1);
+		uint8_t numOfStructs = 5;
+		uint8_t idsToEnable[5] = {1, 3, 4, 6, 7};
+		request2.appendUint8(numOfStructs);
+		for (auto& id : idsToEnable) {
+			request2.appendUint8(id);
+		}
+		REQUIRE(not housekeepingService.housekeepingStructures[0].periodicGenerationActionStatus);
+		REQUIRE(not housekeepingService.housekeepingStructures[4].periodicGenerationActionStatus);
+		REQUIRE(not housekeepingService.housekeepingStructures[6].periodicGenerationActionStatus);
+
+		MessageParser::execute(request2);
+		CHECK(ServiceTests::count() == 3);
+		CHECK(ServiceTests::countThrownErrors(ErrorHandler::ExecutionStartErrorType::RequestedNonExistingStructure) ==
+		      3);
+		CHECK(not housekeepingService.housekeepingStructures[0].periodicGenerationActionStatus);
+		CHECK(housekeepingService.housekeepingStructures[4].periodicGenerationActionStatus);
+		CHECK(housekeepingService.housekeepingStructures[6].periodicGenerationActionStatus);
+
+		ServiceTests::reset();
+		Services.reset();
+	}
+}
+
+TEST_CASE("Disable the periodic generation of housekeeping structures") {
+	SECTION("Both valid and invalid structure IDs in request") {
+		initializeHousekeepingStructures();
+		Message request2(HousekeepingService::ServiceType,
+		                 HousekeepingService::MessageType::DisablePeriodicHousekeepingParametersReport, Message::TC, 1);
+		uint8_t numOfStructs = 4;
+		uint8_t idsToDisable[4] = {0, 1, 4, 6};
+		request2.appendUint8(numOfStructs);
+		for (auto& id : idsToDisable) {
+			request2.appendUint8(id);
+		}
+		housekeepingService.housekeepingStructures[0].periodicGenerationActionStatus = true;
+		housekeepingService.housekeepingStructures[4].periodicGenerationActionStatus = true;
+		housekeepingService.housekeepingStructures[6].periodicGenerationActionStatus = true;
+
+		MessageParser::execute(request2);
+
+		CHECK(ServiceTests::count() == 1);
+		CHECK(ServiceTests::countThrownErrors(ErrorHandler::ExecutionStartErrorType::RequestedNonExistingStructure) ==
+		      1);
+		CHECK(not housekeepingService.housekeepingStructures[0].periodicGenerationActionStatus);
+		CHECK(not housekeepingService.housekeepingStructures[4].periodicGenerationActionStatus);
+		CHECK(not housekeepingService.housekeepingStructures[6].periodicGenerationActionStatus);
+
+		ServiceTests::reset();
+		Services.reset();
+	}
+}
+
+TEST_CASE("Reporting of housekeeping structures") {
+	SECTION("Both valid and invalid structure IDs in request") {
+		initializeHousekeepingStructures();
+		Message request2(HousekeepingService::ServiceType,
+		                 HousekeepingService::MessageType::ReportHousekeepingStructures, Message::TC, 1);
+		uint8_t numOfStructs = 3;
+		uint8_t idsToReport[3] = {9, 4, 2};
+		request2.appendUint8(numOfStructs);
+		for (auto& id : idsToReport) {
+			request2.appendUint8(id);
+		}
+		MessageParser::execute(request2);
+
+		CHECK(ServiceTests::count() == 3);
+		CHECK(ServiceTests::countThrownErrors(ErrorHandler::ExecutionStartErrorType::RequestedNonExistingStructure) ==
+		      2);
+
+		Message report = ServiceTests::get(1); // Both 0 and 2 are the error messages because only id=4 was valid.
+
+		uint8_t validId = 4;
+		CHECK(report.readUint8() == validId);
+		CHECK(not report.readBoolean()); // periodic status
+		CHECK(report.readUint32() == 7); // interval
+		CHECK(report.readUint16() == 3); // number of simply commutated ids
+		CHECK(report.readUint16() == 8);
+		CHECK(report.readUint16() == 4); // ids
+		CHECK(report.readUint16() == 5);
+
+		ServiceTests::reset();
+		Services.reset();
+	}
+}
+
+TEST_CASE("Reporting of housekeeping structures without a TC message as argument") {
+	SECTION("Check the report message generated by the non-TC function") {
+		initializeHousekeepingStructures();
+		uint8_t structureId = 4;
+
+		housekeepingService.housekeepingStructureReport(structureId);
+		CHECK(ServiceTests::count() == 1);
+		Message report = ServiceTests::get(0);
+
+		REQUIRE(report.messageType == HousekeepingService::MessageType::HousekeepingStructuresReport);
+		CHECK(report.readUint8() == structureId);
+		CHECK(not report.readBoolean());
+		CHECK(report.readUint32() == 7);
+		CHECK(report.readUint16() == 3);
+		CHECK(report.readUint16() == 8);
+		CHECK(report.readUint16() == 4);
+		CHECK(report.readUint16() == 5);
+
+		ServiceTests::reset();
+		Services.reset();
+	}
+}
+
+TEST_CASE("Reporting of housekeeping parameters") {
+	SECTION("Valid structure request") {
+		storeSamplesToParameters(8, 4, 5);
+		initializeHousekeepingStructures();
+		uint8_t structId = 6;
+
+		housekeepingService.housekeepingParametersReport(structId);
+
+		CHECK(ServiceTests::count() == 1);
+		Message report = ServiceTests::get(0);
+		REQUIRE(report.messageType == HousekeepingService::MessageType::HousekeepingParametersReport);
+		REQUIRE(report.readUint8() == structId);
+		CHECK(report.readUint16() == 33);
+		CHECK(report.readUint8() == 77);
+		CHECK(report.readUint32() == 99);
+
+		ServiceTests::reset();
+		Services.reset();
+	}
+
+	SECTION("Invalid structure request") {
+		uint8_t structId = 8;
+		housekeepingService.housekeepingParametersReport(structId);
+
+		CHECK(ServiceTests::countThrownErrors(ErrorHandler::InternalErrorType::NonExistentHousekeeping) == 1);
+
+		structId = 12;
+		housekeepingService.housekeepingParametersReport(structId);
+
+		CHECK(ServiceTests::countThrownErrors(ErrorHandler::InternalErrorType::NonExistentHousekeeping) == 2);
+
+		ServiceTests::reset();
+		Services.reset();
+	}
+}
+
+TEST_CASE("Reporting of housekeeping parameters without a TC request") {
+	SECTION("Check the report message generated by the non-TC function") {
+		storeSamplesToParameters(8, 4, 5);
+		initializeHousekeepingStructures();
+		uint8_t structureId = 6;
+
+		housekeepingService.housekeepingParametersReport(structureId);
+		CHECK(ServiceTests::count() == 1);
+		Message report = ServiceTests::get(0);
+
+		REQUIRE(report.messageType == HousekeepingService::MessageType::HousekeepingParametersReport);
+		REQUIRE(report.readUint8() == structureId);
+		CHECK(report.readUint16() == 33);
+		CHECK(report.readUint8() == 77);
+		CHECK(report.readUint32() == 99);
+
+		ServiceTests::reset();
+		Services.reset();
+	}
+}
+
+TEST_CASE("One-shot housekeeping parameter report generation") {
+	SECTION("Both valid and invalid structure IDs in request") {
+		storeSamplesToParameters(8, 4, 5);
+		initializeHousekeepingStructures();
+		Message request2(HousekeepingService::ServiceType,
+		                 HousekeepingService::MessageType::GenerateOneShotHousekeepingReport, Message::TC, 1);
+		uint8_t numOfStructs = 5;
+		uint8_t structIds[5] = {0, 4, 7, 8, 11};
+		request2.appendUint8(numOfStructs);
+		for (auto& id : structIds) {
+			request2.appendUint8(id);
+		}
+		MessageParser::execute(request2);
+
+		CHECK(ServiceTests::count() == 5);
+		CHECK(ServiceTests::countThrownErrors(ErrorHandler::ExecutionStartErrorType::RequestedNonExistingStructure) ==
+		      3);
+		Message report1 = ServiceTests::get(0);
+		Message report2 = ServiceTests::get(1);
+
+		REQUIRE(report1.messageType == HousekeepingService::MessageType::HousekeepingParametersReport);
+		REQUIRE(report2.messageType == HousekeepingService::MessageType::HousekeepingParametersReport);
+
+		REQUIRE(report1.readUint8() == 0);
+		CHECK(report1.readUint16() == 33);
+		CHECK(report1.readUint8() == 77);
+		CHECK(report1.readUint32() == 99);
+
+		REQUIRE(report2.readUint8() == 4);
+		CHECK(report2.readUint16() == 33);
+		CHECK(report2.readUint8() == 77);
+		CHECK(report2.readUint32() == 99);
+
+		ServiceTests::reset();
+		Services.reset();
+	}
+}
+
+TEST_CASE("Append parameters in housekeeping report structure") {
+	SECTION("Non existing structure") {
+		initializeHousekeepingStructures();
+		Message request1(HousekeepingService::ServiceType,
+		                 HousekeepingService::MessageType::AppendParametersToHousekeepingStructure, Message::TC, 1);
+		uint8_t structId = 2;
+		request1.appendUint8(structId);
+		MessageParser::execute(request1);
+		CHECK(ServiceTests::count() == 1);
+		CHECK(ServiceTests::countThrownErrors(ErrorHandler::ExecutionStartErrorType::RequestedNonExistingStructure) ==
+		      1);
+
+		ServiceTests::reset();
+		Services.reset();
+	}
+
+	SECTION("Enabled structure") {
+		Message request(HousekeepingService::ServiceType,
+		                HousekeepingService::MessageType::EnablePeriodicHousekeepingParametersReport, Message::TC, 1);
+		// Enable 1 periodic struct with id=0
+		HousekeepingStructure newStruct;
+		newStruct.structureId = 0;
+		newStruct.periodicGenerationActionStatus = true;
+		housekeepingService.housekeepingStructures.insert({0, newStruct});
+
+		request.appendUint8(1);
+		request.appendUint8(0);
+		MessageParser::execute(request);
+
+		REQUIRE(housekeepingService.housekeepingStructures.at(0).periodicGenerationActionStatus);
+		Message request2(HousekeepingService::ServiceType,
+		                 HousekeepingService::MessageType::AppendParametersToHousekeepingStructure, Message::TC, 1);
+		uint8_t structId = 0;
+		request2.appendUint8(structId);
+		MessageParser::execute(request2);
+
+		CHECK(ServiceTests::count() == 1);
+		CHECK(ServiceTests::countThrownErrors(
+		          ErrorHandler::ExecutionStartErrorType::RequestedAppendToEnabledHousekeeping) == 1);
+
+		ServiceTests::reset();
+		Services.reset();
+	}
+
+	SECTION("Valid request including both valid and invalid parameters") {
+		initializeHousekeepingStructures();
+		Message request3(HousekeepingService::ServiceType,
+		                 HousekeepingService::MessageType::AppendParametersToHousekeepingStructure, Message::TC, 1);
+		uint8_t structId = 6;
+		appendNewParameters(request3, structId);
+		REQUIRE(housekeepingService.housekeepingStructures[structId].simplyCommutatedParameterIds.size() == 3);
+
+		MessageParser::execute(request3);
+		CHECK(ServiceTests::count() == 4);
+		CHECK(ServiceTests::countThrownErrors(ErrorHandler::ExecutionStartErrorType::AlreadyExistingParameter) == 3);
+		CHECK(ServiceTests::countThrownErrors(ErrorHandler::ExecutionStartErrorType::GetNonExistingParameter) == 1);
+
+		uint16_t currentlyExistingParameters[] = {8, 4, 5, 9, 10, 11};
+		HousekeepingStructure structToCheck = housekeepingService.housekeepingStructures[structId];
+		REQUIRE(structToCheck.simplyCommutatedParameterIds.size() == 6);
+		for (auto& existingParameter : currentlyExistingParameters) {
+			CHECK(std::find(std::begin(structToCheck.simplyCommutatedParameterIds),
+			                std::end(structToCheck.simplyCommutatedParameterIds),
+			                existingParameter) != std::end(structToCheck.simplyCommutatedParameterIds));
+		}
+		ServiceTests::reset();
+		Services.reset();
+	}
+
+	SECTION("Exceeding the maximum number of simply commutated parameters for the specified structure") {
+		initializeHousekeepingStructures();
+		uint8_t structId = 6;
+		Message request(HousekeepingService::ServiceType,
+		                HousekeepingService::MessageType::AppendParametersToHousekeepingStructure, Message::TC, 1);
+
+		uint16_t numOfSimplyCommutatedParams = 13;
+		etl::vector<uint16_t, 13> simplyCommutatedIds = {0, 1, 2, 3, 6, 7, 8, 9, 12, 13, 14, 15, 16};
+
+		request.appendUint8(structId);
+		request.appendUint16(numOfSimplyCommutatedParams);
+		for (auto& id : simplyCommutatedIds) {
+			request.appendUint16(id);
+		}
+		REQUIRE(housekeepingService.housekeepingStructures.find(structId) !=
+		        housekeepingService.housekeepingStructures.end());
+		REQUIRE(housekeepingService.housekeepingStructures[structId].simplyCommutatedParameterIds.size() == 3);
+
+		MessageParser::execute(request);
+
+		REQUIRE(housekeepingService.housekeepingStructures[structId].simplyCommutatedParameterIds.size() == 10);
+		CHECK(ServiceTests::count() == 2);
+		CHECK(ServiceTests::countThrownErrors(
+		          ErrorHandler::ExecutionStartErrorType::ExceededMaxNumberOfSimplyCommutatedParameters) == 1);
+		CHECK(ServiceTests::countThrownErrors(ErrorHandler::ExecutionStartErrorType::AlreadyExistingParameter) == 1);
+
+		ServiceTests::reset();
+		Services.reset();
+	}
+}
+
+TEST_CASE("Modification of housekeeping structures' interval") {
+	SECTION("Both valid and invalid requests") {
+		initializeHousekeepingStructures();
+		Message request(HousekeepingService::ServiceType,
+		                HousekeepingService::MessageType::ModifyCollectionIntervalOfStructures, Message::TC, 1);
+		uint8_t numOfStructs = 4;
+		uint8_t structIds[4] = {0, 4, 9, 10};
+		uint32_t intervals[4] = {12, 21, 32, 17};
+		request.appendUint8(numOfStructs);
+		int i = 0;
+		for (auto& id : structIds) {
+			request.appendUint8(id);
+			request.appendUint32(intervals[i++]);
+		}
+		MessageParser::execute(request);
+
+		CHECK(ServiceTests::count() == 2);
+		CHECK(ServiceTests::countThrownErrors(ErrorHandler::ExecutionStartErrorType::RequestedNonExistingStructure) ==
+		      2);
+		REQUIRE(housekeepingService.housekeepingStructures[0].collectionInterval == 12);
+		REQUIRE(housekeepingService.housekeepingStructures[4].collectionInterval == 21);
+
+		ServiceTests::reset();
+		Services.reset();
+	}
+}
+
+TEST_CASE("Reporting of housekeeping structure periodic properties") {
+	SECTION("Both valid and invalid structure IDs in request") {
+		initializeHousekeepingStructures();
+		Message request(HousekeepingService::ServiceType,
+		                HousekeepingService::MessageType::ReportHousekeepingPeriodicProperties, Message::TC, 1);
+		uint8_t numOfStructs = 6;
+		uint8_t structIds[6] = {0, 4, 1, 6, 9, 10};
+		request.appendUint8(numOfStructs);
+		for (auto& id : structIds) {
+			request.appendUint8(id);
+		}
+		housekeepingService.housekeepingStructures[0].periodicGenerationActionStatus = true;
+		housekeepingService.housekeepingStructures[4].collectionInterval = 24;
+		housekeepingService.housekeepingStructures[6].collectionInterval = 13;
+
+		MessageParser::execute(request);
+
+		CHECK(ServiceTests::count() == 4);
+		CHECK(ServiceTests::countThrownErrors(ErrorHandler::ExecutionStartErrorType::RequestedNonExistingStructure) ==
+		      3);
+
+		Message report = ServiceTests::get(3);
+		CHECK(report.readUint8() == 3); // Number of valid ids
+		CHECK(report.readUint8() == 0); // Id
+		CHECK(report.readBoolean() == true); // Periodic status
+		CHECK(report.readUint32() == 7); // Interval
+		CHECK(report.readUint8() == 4); // Id
+		CHECK(report.readBoolean() == false); // Periodic status
+		CHECK(report.readUint32() == 24); // Interval
+		CHECK(report.readUint8() == 6); // Id
+		CHECK(report.readBoolean() == false); // Periodic status
+		CHECK(report.readUint32() == 13); // Interval
+
+		ServiceTests::reset();
+		Services.reset();
+	}
+}
diff --git a/test/Services/ParameterService.cpp b/test/Services/ParameterService.cpp
index fa408e094b5241d14157c55a4eac3ea3f9f816f4..9f9d5fe92d5eb93ff50d04436080b098cd8d4eda 100644
--- a/test/Services/ParameterService.cpp
+++ b/test/Services/ParameterService.cpp
@@ -11,7 +11,8 @@ static void resetParameterValues() {
 
 TEST_CASE("Parameter Report Subservice") {
 	SECTION("All requested parameters invalid") {
-		Message request = Message(ParameterService::ServiceType, ParameterService::MessageType::ReportParameterValues, Message::TC, 1);
+		Message request = Message(ParameterService::ServiceType, ParameterService::MessageType::ReportParameterValues,
+		                          Message::TC, 1);
 		request.appendUint16(3);
 		request.appendUint16(54432);
 		request.appendUint16(60000);
@@ -24,14 +25,15 @@ TEST_CASE("Parameter Report Subservice") {
 		Message report = ServiceTests::get(3);
 		CHECK(report.serviceType == ParameterService::ServiceType);
 		CHECK(report.messageType == ParameterService::MessageType::ParameterValuesReport);
-		CHECK(report.readUint16() == 0);  // the message shall be empty
+		CHECK(report.readUint16() == 0); // the message shall be empty
 
 		ServiceTests::reset();
 		Services.reset();
 	}
 
 	SECTION("Some requested parameters invalid") {
-		Message request = Message(ParameterService::ServiceType, ParameterService::MessageType::ReportParameterValues, Message::TC, 1);
+		Message request = Message(ParameterService::ServiceType, ParameterService::MessageType::ReportParameterValues,
+		                          Message::TC, 1);
 		request.appendUint16(3);
 		request.appendUint16(1);
 		request.appendUint16(10000);
@@ -55,7 +57,8 @@ TEST_CASE("Parameter Report Subservice") {
 	}
 
 	SECTION("Parameters are of different types") {
-		Message request = Message(ParameterService::ServiceType, ParameterService::MessageType::ReportParameterValues, Message::TC, 1);
+		Message request = Message(ParameterService::ServiceType, ParameterService::MessageType::ReportParameterValues,
+		                          Message::TC, 1);
 		request.appendUint16(3);
 		request.appendUint16(0);
 		request.appendUint16(1);
@@ -81,7 +84,8 @@ TEST_CASE("Parameter Report Subservice") {
 
 TEST_CASE("Parameter Setting Subservice") {
 	SECTION("All parameter IDs are invalid") {
-		Message request = Message(ParameterService::ServiceType, ParameterService::MessageType::SetParameterValues, Message::TC, 1);
+		Message request =
+		    Message(ParameterService::ServiceType, ParameterService::MessageType::SetParameterValues, Message::TC, 1);
 		request.appendUint16(3);
 		request.appendUint16(54432);
 		request.appendUint16(1);
@@ -103,7 +107,8 @@ TEST_CASE("Parameter Setting Subservice") {
 	}
 
 	SECTION("The last parameter ID is invalid") {
-		Message request = Message(ParameterService::ServiceType, ParameterService::MessageType::SetParameterValues, Message::TC, 1);
+		Message request =
+		    Message(ParameterService::ServiceType, ParameterService::MessageType::SetParameterValues, Message::TC, 1);
 		request.appendUint16(3);
 		request.appendUint16(0);
 		request.appendUint8(1);
@@ -127,7 +132,8 @@ TEST_CASE("Parameter Setting Subservice") {
 	}
 
 	SECTION("The middle parameter ID is invalid") {
-		Message request = Message(ParameterService::ServiceType, ParameterService::MessageType::SetParameterValues, Message::TC, 1);
+		Message request =
+		    Message(ParameterService::ServiceType, ParameterService::MessageType::SetParameterValues, Message::TC, 1);
 		request.appendUint16(3);
 		request.appendUint16(0);
 		request.appendUint8(1);
@@ -151,7 +157,8 @@ TEST_CASE("Parameter Setting Subservice") {
 	}
 
 	SECTION("All IDs are valid") {
-		Message request = Message(ParameterService::ServiceType, ParameterService::MessageType::SetParameterValues, Message::TC, 1);
+		Message request =
+		    Message(ParameterService::ServiceType, ParameterService::MessageType::SetParameterValues, Message::TC, 1);
 		request.appendUint16(3);
 		request.appendUint16(0);
 		request.appendUint8(1);
@@ -174,7 +181,6 @@ TEST_CASE("Parameter Setting Subservice") {
 }
 
 TEST_CASE("Wrong Messages") {
-
 	SECTION("Wrong Service Type Handling Test for Report") {
 		Message falseRequest(62, 1, Message::TM, 1);
 
diff --git a/test/Services/ParameterStatisticsService.cpp b/test/Services/ParameterStatisticsService.cpp
index 3a831c73fb6de9652c4408ee3981383cd754ec7c..2e32020ae48220dd01a183f344c8868b3645724c 100644
--- a/test/Services/ParameterStatisticsService.cpp
+++ b/test/Services/ParameterStatisticsService.cpp
@@ -263,8 +263,8 @@ TEST_CASE("Add/Update statistics definitions") {
 		uint16_t paramId1 = 0;
 		uint16_t paramId2 = 1;
 		uint16_t paramId3 = 2;
-		uint16_t paramId4 = 7;
-		uint16_t paramId5 = 11;
+		uint16_t paramId4 = systemParameters.parametersArray.size() + 24;
+		uint16_t paramId5 = systemParameters.parametersArray.size() + 1;
 		uint16_t paramId6 = 3;
 
 		uint16_t interval1 = 14;