diff --git a/.gitignore b/.gitignore
index b539c117fcc142b4f55d30a75ce7b212ed68869f..c3aed1a6ffb12f32c68d7d0e2c7cf1220c3adde9 100644
--- a/.gitignore
+++ b/.gitignore
@@ -15,6 +15,7 @@ downloads/
 eggs/
 .eggs/
 lib/
+!host/fipy/lib
 !client/client/lib
 lib64/
 parts/
diff --git a/client/client/lib/deep_sleep/f_deep_sleep.cpp b/client/client/lib/deep_sleep/f_deep_sleep.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..60d1ac0b44d850f809d44be2b2fd609536fb54a0
--- /dev/null
+++ b/client/client/lib/deep_sleep/f_deep_sleep.cpp
@@ -0,0 +1,23 @@
+#include "f_deep_sleep.hpp"
+
+void print_wakeup_reason(){
+  esp_sleep_wakeup_cause_t wakeup_reason;
+
+  wakeup_reason = esp_sleep_get_wakeup_cause();
+
+  switch(wakeup_reason)
+  {
+    case ESP_SLEEP_WAKEUP_EXT0 : Serial.println("Wakeup caused by external signal using RTC_IO"); break;
+    case ESP_SLEEP_WAKEUP_EXT1 : Serial.println("Wakeup caused by external signal using RTC_CNTL"); break;
+    case ESP_SLEEP_WAKEUP_TIMER : Serial.println("Wakeup caused by timer"); break;
+    case ESP_SLEEP_WAKEUP_TOUCHPAD : Serial.println("Wakeup caused by touchpad"); break;
+    case ESP_SLEEP_WAKEUP_ULP : Serial.println("Wakeup caused by ULP program"); break;
+    default : Serial.printf("Wakeup was not caused by deep sleep: %d\n",wakeup_reason); break;
+  }
+}
+
+
+void deep_sleep(int time_in_sec){
+  esp_sleep_enable_timer_wakeup(time_in_sec * 1000000);
+  esp_deep_sleep_start();
+}
diff --git a/client/client/lib/deep_sleep/f_deep_sleep.hpp b/client/client/lib/deep_sleep/f_deep_sleep.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..b0c91129d025c7cd48f0350a269a765c7c8e0f5b
--- /dev/null
+++ b/client/client/lib/deep_sleep/f_deep_sleep.hpp
@@ -0,0 +1,9 @@
+#ifndef F_DEEP_SLEEP_H
+#define F_DEEP_SLEEP_H
+
+#include <Arduino.h>
+
+void deep_sleep(int time_to_sleep);
+void print_wakeup_reason();
+
+#endif
diff --git a/client/client/lib/espnow/src/ESPNow.cpp b/client/client/lib/espnow/src/ESPNow.cpp
index e52930604dace5db905876e9ffcdc12642e943bf..359b43c50b855b7f90d955995befe915a3846e3d 100644
--- a/client/client/lib/espnow/src/ESPNow.cpp
+++ b/client/client/lib/espnow/src/ESPNow.cpp
@@ -7,7 +7,7 @@ Preferences preferences;
 void get_host_mac(uint8_t *destination)
 {
 	preferences.begin("config", true);
-	if (preferences.isKey("host")) {
+	if (!preferences.isKey("host")) {
 		preferences.getBytes("host", destination, sizeof(uint8_t) * 6);
 	} else {
 		memcpy(destination, BROADCAST_MAC, sizeof(BROADCAST_MAC));
@@ -31,11 +31,15 @@ void on_data_recv(const uint8_t *mac, const uint8_t *incomingData, int len)
 	if (!preferences.isKey("host")) {
 		preferences.putBytes("host", new_config.host, sizeof(new_config.host));
 		Serial.println("host mac saved to flash");
-	} // host change shouldn't be an issue
+	} else{
+		Serial.println("host mac already exists");
+	}// host change shouldn't be an issue
 	preferences.end();
 	// sync time
-	esptime::rtc.setTime(
+	Time::getInstance().setTime(
 	    new_config.time_millis); // see https://www.esp32.com/viewtopic.php?t=9965, maybe this needs an offset
+	Serial.println("Saved Time: " + (String) new_config.time_millis);
+	Serial.flush();
 }
 
 esp_err_t espnow_setup()
@@ -59,3 +63,29 @@ esp_err_t espnow_setup()
 
 	return ESP_OK;
 }
+
+esp_err_t espnow_send_message(const Message& message){
+	Serial.println("sending Message");
+	esp_err_t success;
+	ClientDataPackage dataP = message.get_client_data_package();
+	uint8_t recipient;
+	get_host_mac(&recipient);
+
+	success = esp_now_send(&recipient, (uint8_t *) &dataP, sizeof(ClientDataPackage));
+	// if(success != ESP_OK){
+	//     if(!ram_cache_is_full()){
+	//         ram_cache_push(*data);
+	//     }
+	// }
+
+	for (int i = 0; i < dataP.amountData; i++) {
+		Serial.println(dataP.values[i]);
+	}
+	
+	Serial.println((String) "time sent: " + dataP.timestamp);
+	Serial.println((String) "Send status: " + success);
+	Serial.println();
+	Serial.println("done");
+	Serial.flush();
+	return success;
+}
diff --git a/client/client/lib/espnow/src/ESPNow.hpp b/client/client/lib/espnow/src/ESPNow.hpp
index 1230290fca05d93f3c98bbd7c3374f364f5868bb..e4ac43b351c4431e8a1bd1b15740ae5fe085e2fe 100644
--- a/client/client/lib/espnow/src/ESPNow.hpp
+++ b/client/client/lib/espnow/src/ESPNow.hpp
@@ -16,6 +16,7 @@ typedef struct config {
 } config;
 
 esp_err_t espnow_setup();
+esp_err_t espnow_send_message(const Message& message);
 bool is_host_defined();
 void get_host_mac(uint8_t *destination);
 void on_data_sent(const uint8_t *mac_addr, esp_now_send_status_t status);
diff --git a/client/client/lib/espnow/src/Message.cpp b/client/client/lib/espnow/src/Message.cpp
index c4bfb3f765350c6ad51aa28ad605a7a13ae9c2e4..6975ab6cd228ab218df9759abddc498a082c288c 100644
--- a/client/client/lib/espnow/src/Message.cpp
+++ b/client/client/lib/espnow/src/Message.cpp
@@ -9,39 +9,21 @@ void Message::add_data(float value, int identifier)
 	}
 }
 
-esp_err_t Message::send()
+ClientDataPackage Message ::get_client_data_package() const
 {
-	Serial.println("sending Message");
-	esp_err_t success;
-	success = esp_now_send(recipient, (uint8_t *)&data, sizeof(data));
-	// if(success != ESP_OK){
-	//     if(!ram_cache_is_full()){
-	//         ram_cache_push(*data);
-	//     }
-	// }
-	for (int i = 0; i < data.amountData; i++) {
-		Serial.println(data.values[i]);
-	}
-	Serial.println((String) "time sent: " + data.timestamp);
-	Serial.println((String) "Send status: " + success);
-	Serial.println();
-	Serial.flush();
-	Serial.println("done");
-	return success;
+	return data;
 }
 
 Message ::Message()
 {
 	// check for existing host mac address, use broadcast otherwise
-	get_host_mac(recipient);
 
 	data.amountData = 0;
-	data.timestamp = esptime::rtc.getMillis(); // I am assuming we are not sending data from Unix Epoch
+	data.timestamp = Time::getInstance().getMillis(); // I am assuming we are not sending data from Unix Epoch
 }
 
 Message ::Message(ClientDataPackage old_data)
 {
 	data = old_data;
 	// memcpy(&data, &old_data, sizeof(data));
-	get_host_mac(recipient);
 }
\ No newline at end of file
diff --git a/client/client/lib/espnow/src/Message.hpp b/client/client/lib/espnow/src/Message.hpp
index ee00f7fd7365a15c25a32d9ad81b575fb5edde3b..397ca6f707105be90fb76add8200b8edef93c8ed 100644
--- a/client/client/lib/espnow/src/Message.hpp
+++ b/client/client/lib/espnow/src/Message.hpp
@@ -1,7 +1,6 @@
 #pragma once
 
 #include "ClientDataPackage.hpp"
-#include "ESPNow.hpp"
 #include "Time.hpp"
 #include <Arduino.h>
 #include <ESP32Time.h>
@@ -14,9 +13,8 @@ class Message {
 	Message();
 	Message(ClientDataPackage old_data);
 	void add_data(float value, int identifier);
-	esp_err_t send();
+	ClientDataPackage get_client_data_package() const;
 
   private:
 	ClientDataPackage data;
-	uint8_t recipient[6];
 };
\ No newline at end of file
diff --git a/client/client/lib/time/src/Time.cpp b/client/client/lib/time/src/Time.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..8fdf4b4decd253a197cda680a6613529daa2b127
--- /dev/null
+++ b/client/client/lib/time/src/Time.cpp
@@ -0,0 +1,28 @@
+#include "Time.hpp"
+
+#include <utility>
+void Time::setTime(long epoch, int ms)
+{
+	this->rtc.setTime(epoch, ms);
+}
+tm Time::getTimeStruct()
+{
+	return this->rtc.getTimeStruct();
+}
+String Time::getDateTime(bool mode)
+{
+	return this->rtc.getDateTime(mode);
+}
+String Time::getTime(String format)
+{
+	return this->rtc.getTime(std::move(format));
+}
+long Time::getEpochSeconds()
+{
+	return this->rtc.getEpoch();
+}
+
+long Time::getMillis()
+{
+	return this->rtc.getMillis();
+}
diff --git a/client/client/lib/time/src/Time.hpp b/client/client/lib/time/src/Time.hpp
index 93dfc964f0bef45fb86ccba203868ea995df4031..d53adb159f8f5deb092bcffa3977f550f59fcd1d 100644
--- a/client/client/lib/time/src/Time.hpp
+++ b/client/client/lib/time/src/Time.hpp
@@ -1,9 +1,75 @@
-#pragma once
+#ifndef ESPTIME
+#define ESPTIME
 
 #include <ESP32Time.h>
 
-namespace esptime {
-// internal linkage only
-static ESP32Time rtc; // global variable for the RTC (i don't think this is good practice)
-} // namespace esptime
-// namespace esptime
+class Time {
+  public:
+	static Time &getInstance()
+	{
+		static Time instance; // Guaranteed to be destroyed.
+		                      // Instantiated on first use.
+		return instance;
+	}
+
+	/*!
+	@brief  set the internal RTC time
+	@param  epoch
+	        epoch time in seconds
+	@param  ms
+	        microseconds (optional)
+	*/
+	void setTime(long epoch, int ms = 0);
+
+	/*!
+	@brief  get the internal RTC time as a tm struct
+	*/
+	tm getTimeStruct();
+
+	/*!
+	@brief  get the time and date as an Arduino String object
+	@param  mode
+	        true = Long date format
+	        false = Short date format
+	*/
+	String getDateTime(bool mode);
+
+	/*!
+	@brief  get the time as an Arduino String object with the specified format
+	@param	format
+	        time format
+	        http://www.cplusplus.com/reference/ctime/strftime/
+	*/
+	String getTime(String format = "%H:%M:%S");
+
+	/*!
+	@brief  get the current epoch seconds as long
+	*/
+	long getEpochSeconds();
+
+	/*!
+	@brief  get the current milliseconds as long
+	*/
+	long getMillis();
+
+  private:
+	Time() {} // Constructor? (the {} brackets) are needed here.
+
+	ESP32Time rtc = ESP32Time{};
+
+	// C++ 11
+	// =======
+	// We can use the better technique of deleting the methods
+	// we don't want.
+  public:
+	Time(Time const &) = delete;
+	void operator=(Time const &) = delete;
+
+	// Note: Scott Meyers mentions in his Effective Modern
+	//       C++ book, that deleted functions should generally
+	//       be public as it results in better error messages
+	//       due to the compilers behavior to check accessibility
+	//       before deleted status
+};
+
+#endif
\ No newline at end of file
diff --git a/client/client/src/main.cpp b/client/client/src/main.cpp
index 54220bae97fb193cf0d830b9d04c57a49976f3a4..1c549ba722451f99037e2fb54643cdb5dfc91636 100644
--- a/client/client/src/main.cpp
+++ b/client/client/src/main.cpp
@@ -1,31 +1,44 @@
+#include "ESPNow.hpp"
+#include "ram_caching.hpp"
 #include <Arduino.h>
-#include <scd30.hpp>
-#include <dr26.hpp>
-#include <drs26.hpp>
-#include <ina219.hpp>
+#include <ArduinoJson.h>
+#include "Time.hpp"
+#include "f_deep_sleep.hpp"
 
-// Forte_SCD30 scd30;
 
-void setup() {
-  Serial.begin(9600);
-  // scd30.setup();
-}
+void setup()
+{
+
+	// put your setup code here, to run once:
+	Serial.begin(115200);
+	while (!Serial)
+		;
+	Serial.flush();
 
-void loop() {
-  
-  void* data;
-  // data = scd30.read_data();
-
-  if(data==0)
-  {
-  Serial.println("Waiting for data !");
-  Serial.println();
-  }
-  // else{
-  //       Serial.print("Sensor CO2 "); Serial.println(data->C02);
-  //       Serial.print("Humidity "); Serial.println(data->Humidity);
-  //       Serial.print("Temperature "); Serial.println(data->Temperature);
-  //       Serial.println();
-  //   }
-  delay(5000);
+	esp_err_t result = espnow_setup();
 }
+
+int counter = 0;
+
+void loop()
+{
+	// put your main code here, to run repeatedly:
+	Message new_data = Message{};
+	new_data.add_data(++counter * 1.1, 0);
+	new_data.add_data(counter * 1.2, 1);
+	new_data.add_data(counter * 1.3, 2);
+	espnow_send_message(new_data);
+
+	// if(!ram_cache_is_empty()){
+	//   ClientDataPackage old_data = ram_cache_pop();
+	//   Message* resend_message = new Message(old_data);
+	//   resend_message->send();
+	//   delete resend_message;u
+	// }
+	Serial.println("Saved Time Loop: " + Time::getInstance().getTime("%c"));
+
+	Serial.println("delaying...");
+	Serial.flush();
+	delay(5000); // 5 second receive window
+	// deep_sleep(900); // go to sleep for 15 mins (900s)
+}
\ No newline at end of file
diff --git a/host/fipy/lib/espnow.py b/host/fipy/lib/espnow.py
new file mode 100644
index 0000000000000000000000000000000000000000..6afe2a8b0c2d766e626dd864c493e6a3dd8ab6e7
--- /dev/null
+++ b/host/fipy/lib/espnow.py
@@ -0,0 +1,57 @@
+import network
+from network import ESPNOW
+import time
+from lib.rtc_time import RTCTime
+import struct
+
+w = network.WLAN()
+self_mac, sta = w.mac()
+peer_list = []
+
+class Forte_ESPNOW:
+    def __init__(self):
+        ESPNOW.init()
+        ESPNOW.on_recv(espnow_recv)
+    
+    def add_peer(mac):
+        peer_list.append(ESPNOW.add_peer(mac))
+
+def espnow_respond(mac):
+    msg = struct.pack("<6sl", self_mac, time.time())
+    print(int(time.time()))
+
+    ESPNOW.send(mac, msg)
+    print("response sent")
+
+def espnow_recv(result):
+    print("message recv")
+    mac, peer, msg = result
+
+    data = bytes_to_data(msg)
+    try:
+        print("amount data: " + str(data["amountData"]))
+    #     print(data["timestamp"])
+    #     print(data["data"])
+
+    except Exception as error:
+        print(error)
+
+    if(peer not in peer_list):
+        Forte_ESPNOW.add_peer(mac)
+    
+    espnow_respond(mac)
+
+def bytes_to_data(msg):
+    # turn bytes from message into 22-tuple of integers(identifiers), floats(values), integer(amount) and long(timestamp)
+    data = struct.unpack("<10i10fil", bytes(msg))
+    amountData = data[20]
+    timestamp = data[21]
+    identifiers = data[0:amountData]
+    values = data[10 : (10 + amountData)]
+    return {
+        "amountData": amountData,
+        "timestamp": timestamp,
+        "data": dict(zip(identifiers, values)),
+    }
+
+
diff --git a/host/fipy/lib/rtc_time.py b/host/fipy/lib/rtc_time.py
new file mode 100644
index 0000000000000000000000000000000000000000..d57b3944d0e00847266b988349464009d3e0a971
--- /dev/null
+++ b/host/fipy/lib/rtc_time.py
@@ -0,0 +1,35 @@
+from time import sleep
+from machine import RTC
+
+
+class RTCTime:
+    # def __init__(
+    #     self,
+    #     main_ntp_server: str = "pool.ntp.org",
+    #     backup_ntp_server: str = "time.nist.gov",
+    #     update_interval_seconds: int = 3600,
+    # ):
+    #     self.rtc = RTC()
+    #     self._setup_ntp(main_ntp_server, backup_ntp_server, update_interval_seconds)
+    
+    
+    def __init__(self, datetime):
+        self.rtc = RTC()
+        self.rtc.init(datetime)
+
+    def _setup_ntp(
+        self, main_ntp_server: str, backup_ntp_server: str, update_interval_seconds: int
+    ):
+        print("Setting up NTP")
+        self.rtc.ntp_sync(main_ntp_server, update_interval_seconds, backup_ntp_server)
+        while not self.rtc.synced():
+            print(self.rtc.synced())
+            sleep(1)
+
+    
+
+    def get_time(self):
+        return self.rtc.now()
+
+    def is_synchronized(self):
+        return self.rtc.synced()
diff --git a/host/fipy/main.py b/host/fipy/main.py
index 1735bdbadcc6e0bcfa8649fc1ee81eecab71aceb..020d027e0345c701725c418eade7e55179d05551 100644
--- a/host/fipy/main.py
+++ b/host/fipy/main.py
@@ -1,39 +1,9 @@
 # main.py -- put your code here!
-from network import WLAN
-from network import ESPNOW
-import binascii
-import struct
+# from network import ESPNOW
 from time import sleep
 from lib.server_transfer import DataTransferWiFi
-
-
-def bytes_to_data(msg):
-    # turn bytes from message into 22-tuple of integers(identifiers), floats(values), integer(amount) and long(timestamp)
-    data = struct.unpack("<10i10fil", bytes(msg))
-    amountData = data[20]
-    timestamp = data[21]
-    identifiers = data[0:amountData]
-    values = data[10 : (10 + amountData)]
-    return {
-        "amountData": amountData,
-        "timestamp": timestamp,
-        "data": dict(zip(identifiers, values)),
-    }
-
-
-def espnow_recv(result):
-    mac, peer, msg = result
-
-    data = bytes_to_data(msg)
-    try:
-        print(data["amountData"])
-        print(data["timestamp"])
-        print(data["data"])
-        print(str(binascii.hexlify(mac), "ascii"))
-
-    except Exception as error:
-        print(error)
-
+from lib.espnow import Forte_ESPNOW
+from lib.rtc_time import RTCTime
 
 # data = DataTransferWiFi()
 # data.connect("Z", "AbsoluteSandwich")
@@ -41,15 +11,9 @@ def espnow_recv(result):
 #     "airSensors,sensor_id=TLM0201 temperature=73.97038159354763,humidity=35.23103248356096,co=0.4844531056779361 1661175680\nairSensors,sensor_id=TLM0202 temperature=75.30007505999716,humidity=35.65192991869171,co=0.5141876544505826 1661175680\nairSensors,sensor_id=TLM0202 temperature=75.30007505999756,humidity=35.65192991869171,co=0.5141876544505826 1661175680"
 # )
 # data.disconnect()
-
-w = WLAN()
-
-ESPNOW.init()
-p = ESPNOW.add_peer("58cf79043c84")
-
-ESPNOW.on_recv(espnow_recv)
-
+#
+rtc_time = RTCTime((2014, 5, 1, 4, 13, 0, 0, 0))
+espnow = Forte_ESPNOW()
 while True:
-    print("...")
     sleep(5)
     pass