diff --git a/client/client_mock/.gitignore b/client/client_mock/.gitignore
new file mode 100644
index 0000000000000000000000000000000000000000..89cc49cbd652508924b868ea609fa8f6b758ec56
--- /dev/null
+++ b/client/client_mock/.gitignore
@@ -0,0 +1,5 @@
+.pio
+.vscode/.browse.c_cpp.db*
+.vscode/c_cpp_properties.json
+.vscode/launch.json
+.vscode/ipch
diff --git a/client/client_mock/.gitkeep b/client/client_mock/.gitkeep
new file mode 100644
index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
diff --git a/client/client_mock/platformio.ini b/client/client_mock/platformio.ini
new file mode 100644
index 0000000000000000000000000000000000000000..b7c388a5d2b4fd93dd5ddb27969ebd259d807847
--- /dev/null
+++ b/client/client_mock/platformio.ini
@@ -0,0 +1,33 @@
+[env:esp32dev]
+platform = espressif32@^5.0.0
+board = esp32dev
+framework = arduino
+monitor_speed = 115200
+lib_ldf_mode = deep
+lib_extra_dirs =
+    ../libs
+; C++17 https://community.platformio.org/t/esp32-c-17-toolchain-missing-std-optional/25850/6
+; we use c++17 features (i.e. optionals in ClientDataPackage.hpp)
+build_flags =
+    -I include
+    -DCORE_DEBUG_LEVEL=5
+    -std=gnu++17
+build_unflags = -std=gnu++11
+
+lib_deps =
+    sparkfun/SparkFun SCD30 Arduino Library@^1.0.18
+    Wire
+    adafruit/Adafruit ADS1X15@^2.4.0
+    wollewald/INA219_WE@^1.3.1
+    adafruit/Adafruit BusIO@^1.13.2
+    Adafruit_I2CDevice
+    SPI
+    envirodiy/SDI-12@^2.1.4
+    fbiego/ESP32Time@^2.0.0
+    bblanchon/ArduinoJson@^6.19.4
+    4-20ma/ModbusMaster@^2.0.1
+    adafruit/RTClib@^2.1.1
+    sensirion/arduino-sht@^1.2.2
+    robtillaart/SHT85@^0.3.2
+    plerup/EspSoftwareSerial@6.16.1
+
diff --git a/client/client_mock/src/main.cpp b/client/client_mock/src/main.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..faae21bb2a8b5ff08a56c6c0f26348cd1cc7cdaa
--- /dev/null
+++ b/client/client_mock/src/main.cpp
@@ -0,0 +1,101 @@
+#include "ESPNow.hpp"
+#include "MockSensor.hpp"
+#include "NoDataAvailableException.hpp"
+#include "f_deep_sleep.hpp"
+#include <Arduino.h>
+
+
+static const char *TAG = "MAIN";
+
+MockSensor mock_channel0;
+MockSensor mock_channel1;
+MockSensor mock_channel2;
+MockSensor mock_channel3;
+
+void send_msgs(const std::__cxx11::list<Message> msgs) {
+    for (const Message &msg: msgs) {
+
+        if (msg.send() != ESP_OK) {
+            RtcMemory::store(msg.getMessageAsMinifiedJsonString());
+        }
+        unsigned long ts = millis();
+        // it takes ~110ms for receiving an acknowledgement by the host in perfect conditions
+        uint16_t message_timeout = 2000;
+        while (!was_msg_received()) {
+            if ((millis() - ts) > message_timeout) {
+                RtcMemory::store(msg.getMessageAsMinifiedJsonString());
+                ESP_LOGE(TAG, "Timeout: Host not available\n");
+                break;
+            }
+        }
+        ESP_LOGD(TAG, "Time until acknowledgement: %ld", millis() - ts);
+    }
+}
+
+// one loop takes ~2200 ms
+void setup() {
+    unsigned long ts = millis();
+    Serial.begin(115200);
+    // Set the GPIO which conrtols the step up to OUTPUT
+    gpio_set_direction(GPIO_NUM_32, GPIO_MODE_OUTPUT);
+
+    // blinking led for debug
+    // gpio_set_direction(GPIO_NUM_17, GPIO_MODE_OUTPUT);
+    // gpio_set_level(GPIO_NUM_17, 1);
+
+    DeepSleep::print_wakeup_reason();
+    DeepSleep::bootCount++;
+    ESP_LOGD(TAG, "Boot number: %d", DeepSleep::bootCount);
+
+    gpio_set_level(GPIO_NUM_32, 1);
+    // delay(100);
+    mock_channel0.setup();
+    mock_channel1.setup();
+    mock_channel2.setup();
+    mock_channel3.setup();
+
+    mock_channel0.setChannel(0);
+    mock_channel1.setChannel(1);
+    mock_channel2.setChannel(2);
+    mock_channel3.setChannel(3);
+
+    ESP_LOGD(TAG, "Setup took %ld ms", millis() - ts);
+
+    try {
+        // FIXME: put me into seperate trys? No data will be sent when 1 exception occurs
+
+        ts = millis();
+        auto messages0 = mock_channel0.buildMessages();
+        auto messages1 = mock_channel1.buildMessages();
+        auto messages2 = mock_channel2.buildMessages();
+        auto messages3 = mock_channel3.buildMessages();
+        // roughly takes 500ms, ~120ms for each adc channel, barely anything for battery monitor
+        ESP_LOGD(TAG, "Reading data and building messages took %ld ms", millis() - ts);
+        gpio_set_level(GPIO_NUM_32, 0);
+
+        // FIXME: put this outside the try loop?
+        ts = millis();
+        espnow_setup();
+        ESP_LOGD(TAG, "EPSNow setup took %ld ms", millis() - ts);
+        ts = millis();
+        send_msgs(messages0);
+        send_msgs(messages1);
+        send_msgs(messages2);
+        send_msgs(messages3);
+        // roughly takes 3s in ideal conditions
+        ESP_LOGD(TAG, "Sending messages took %ld ms", millis() - ts);
+
+    } catch (const NoDataAvailableException &e) {
+        std::cerr << e.what() << '\n';
+    }
+    // just to be safe in case exception happens above
+    gpio_set_level(GPIO_NUM_32, 0);
+    // keep it in deep sleep
+    gpio_hold_en((gpio_num_t) GPIO_NUM_32);
+
+    // battery protection: go to deep sleep for unlimited time when voltage less than 3.2V
+    DeepSleep::deep_sleep(20);
+
+}
+
+void loop() {}
\ No newline at end of file
diff --git a/client/client_mock/test/README b/client/client_mock/test/README
new file mode 100644
index 0000000000000000000000000000000000000000..9b1e87bc67c90e7f09a92a3e855444b085c655a6
--- /dev/null
+++ b/client/client_mock/test/README
@@ -0,0 +1,11 @@
+
+This directory is intended for PlatformIO Test Runner and project tests.
+
+Unit Testing is a software testing method by which individual units of
+source code, sets of one or more MCU program modules together with associated
+control data, usage procedures, and operating procedures, are tested to
+determine whether they are fit for use. Unit testing finds problems early
+in the development cycle.
+
+More information about PlatformIO Unit Testing:
+- https://docs.platformio.org/en/latest/advanced/unit-testing/index.html
diff --git a/client/libs/includes/Protocol.hpp b/client/libs/includes/Protocol.hpp
index 92270db81e4a54e525f2cd054a15a03e7ebade15..f9a124978a42626fd128e579adc497bd23257678 100644
--- a/client/libs/includes/Protocol.hpp
+++ b/client/libs/includes/Protocol.hpp
@@ -6,10 +6,10 @@
 #define CLIENT_PROTOCOL_HPP
 
 #include <map>
-enum class Protocol { I2C, RS485, Analog };
+enum class Protocol { I2C, RS485, Analog, Mock };
 
 // protocol to string
 const static std::map<Protocol, const char *> protocolToString = {
-    {Protocol::I2C, "I2C"}, {Protocol::RS485, "RS485"}, {Protocol::Analog, "ANALOG"}};
+    {Protocol::I2C, "I2C"}, {Protocol::RS485, "RS485"}, {Protocol::Analog, "ANALOG"}, {Protocol::Mock, "MOCK"}};
 
 #endif // CLIENT_PROTOCOL_HPP
diff --git a/client/libs/mock_sensor/MockSensor.cpp b/client/libs/mock_sensor/MockSensor.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..4833773e9b7e26da8ff00842e1fcee47fb613635
--- /dev/null
+++ b/client/libs/mock_sensor/MockSensor.cpp
@@ -0,0 +1,34 @@
+#include "MockSensor.hpp"
+
+static const char *TAG = "MOCK";
+
+void MockSensor::setup() {
+
+    ESP_LOGD(TAG, "MOCK Sensor initialized");
+    delay(100);
+    channel = 0;
+}
+
+float MockSensor::readData() {
+    // generate a random float value between 0 and 100
+    float randomValue = (float)rand() / (float)RAND_MAX * 100.0;
+    ESP_LOGD(TAG, "MOCK Sensor read value: %f", randomValue);
+    return randomValue;
+}
+
+
+void MockSensor::setChannel(int c) {
+    channel = c;
+}
+
+std::list<Message> MockSensor::buildMessages() {
+    std::list<Message> messages;
+    float data = readData();
+    MeasurementData MockData{data, channel, {}, "MOCK"};
+    messages.emplace_back(MockData, sensorInformation, Time::getInstance().getEpochSeconds());
+    return messages;
+}
+
+SensorInformation MockSensor::getSensorInformation() const {
+    return sensorInformation;
+}
diff --git a/client/libs/mock_sensor/MockSensor.hpp b/client/libs/mock_sensor/MockSensor.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..20df4d1d2c66b954949a5fbce9a7e074293d28b2
--- /dev/null
+++ b/client/libs/mock_sensor/MockSensor.hpp
@@ -0,0 +1,24 @@
+#ifndef _MOCK_SENSOR
+#define _MOCK_SENSOR
+
+#include "ForteSensor.hpp"
+#include "Message.hpp"
+#include "NoDataAvailableException.hpp"
+#include "Pinout.hpp"
+#include "esp_log.h"
+#include <Wire.h>
+
+class MockSensor : public ForteSensor<float> {
+  public:
+	void setup() override;
+	float readData() override;
+	void setChannel(int channel);
+	std::list<Message> buildMessages() override;
+	[[nodiscard]] SensorInformation getSensorInformation() const override;
+
+  private:
+	const SensorInformation sensorInformation{"MOCK", Protocol::Mock};
+	int channel;
+};
+
+#endif
\ No newline at end of file