From 4f6a1dfc4fddf4faf3befaecc1ce063decc7f5b7 Mon Sep 17 00:00:00 2001 From: Simon Date: Sat, 24 Sep 2022 21:32:01 +0200 Subject: [PATCH] Add documentation, start extending serialization Temperature sensors are still missing --- app/include/Serializer.h | 8 +++++-- app/src/Serializer.cxx | 40 ++++++++++++++++++++++++-------- app/src/main.cxx | 4 ++-- doc/Application Overview.drawio | 1 + doc/Application Overview.jpg | Bin 0 -> 27419 bytes 5 files changed, 39 insertions(+), 14 deletions(-) create mode 100644 doc/Application Overview.drawio create mode 100644 doc/Application Overview.jpg diff --git a/app/include/Serializer.h b/app/include/Serializer.h index 4f11042..2973086 100644 --- a/app/include/Serializer.h +++ b/app/include/Serializer.h @@ -17,9 +17,13 @@ using json = nlohmann::json; class Serializer { public: Serializer(); - void Serialize(std::vector> fans); + void SerializeFans(std::vector> fans); std::vector> - Deserialize(std::vector> availableSensors); + DeserializeFans(std::vector> availableSensors); + + void SerializeTempSensors(std::vector> senors); + std::vector> + DeserializeTempSensors(std::vector> availableSensors); private: void WriteJson(json o); diff --git a/app/src/Serializer.cxx b/app/src/Serializer.cxx index d334613..ea6bcfb 100644 --- a/app/src/Serializer.cxx +++ b/app/src/Serializer.cxx @@ -18,22 +18,18 @@ Serializer::Serializer() { } } -void Serializer::Serialize(vector> fans) { - json fansArr; - - for (auto f : fans) { - fansArr.emplace_back(f->toJson()); - } - +void Serializer::SerializeFans(vector> fans) { json obj; - obj["fans"] = fansArr; + for (auto f : fans) { + obj["fans"].push_back(f->toJson()); + } WriteJson(obj); } vector> -Serializer::Deserialize(vector> availableSensors) { +Serializer::DeserializeFans(vector> availableSensors) { vector> mapping; // Create a for the sensors first, then searching becomes cheaper @@ -57,11 +53,35 @@ Serializer::Deserialize(vector> availableSensors) { } void Serializer::WriteJson(json o) { + json obj; + + if (fs::exists(fs::path(SERIALIZATION_DIR) / FANS_JSON_FILENAME)) { + auto obj = ReadJson(); + } + + for (auto &[key, value] : o.items()) { + obj[key] = value; + } + ofstream ostrm(fs::path(SERIALIZATION_DIR) / FANS_JSON_FILENAME, ios::trunc); - ostrm << o.dump(2) << "\n"; + ostrm << obj.dump(2) << "\n"; } json Serializer::ReadJson() { ifstream istrm(fs::path(SERIALIZATION_DIR) / FANS_JSON_FILENAME); return json::parse(istrm); } + +void Serializer::SerializeTempSensors(vector> sensors) { + json obj; + + for (auto s : sensors) { + obj["tempSensors"].push_back(s->toJson()); + } + + WriteJson(obj); +} +vector> +DeserializeTempSensors(vector> availableSensors) { + return vector>(); +} diff --git a/app/src/main.cxx b/app/src/main.cxx index ca372a9..4510248 100644 --- a/app/src/main.cxx +++ b/app/src/main.cxx @@ -26,10 +26,10 @@ int main() { std::vector> fans; if (fs::exists(fs::path(SERIALIZATION_DIR) / FANS_JSON_FILENAME)) { - fans = s.Deserialize(pwmSensors); + fans = s.DeserializeFans(pwmSensors); } else { fans = m.createMapping(pwmSensors, controls); - s.Serialize(fans); + s.SerializeFans(fans); } for (auto f : fans) { diff --git a/doc/Application Overview.drawio b/doc/Application Overview.drawio new file mode 100644 index 0000000..3691335 --- /dev/null +++ b/doc/Application Overview.drawio @@ -0,0 +1 @@ +5VjbctowEP0aZtqHZHwJhjyCQ9JOQ4fJjfRRsRdbrWwRWdzy9V3ZMsYYUichgbYvIB1pJXH2nLVFw3aj+YUg47DPfWANy/DnDfusYVnmqd3CL4UsNGKa7QwJBPU1VgDX9Ak0aGh0Qn1IShMl50zScRn0eByDJ0sYEYLPytNGnJV3HZMAKsC1R1gVHVJfhhnabhoF/gVoEOY7m4YeiUg+WQNJSHw+W4HsXsN2Becya0VzF5hiL+clizvfMro8mIBY1gl4bDnd/sgd3j3IaWfY+za8fXo8Mu1smSlhE/2LB8N+Qy3V1MeWi5wL8JEa3eVChjzgMWG9Au0KPol9UBsa2CvmXHI+RtBE8CdIudB5JhPJEQplxPQozKm8V+HHuH/W/aFXU+2z+WpnkXdiKRb3+Qqqk8Yct5p5v4hLe0Wg31Eawa7HSJJQLwPPKcsPlJGgfvlW2jWU8Inw4BmuHS1fIgKQz+VkKQ60FfAI8MgYJ4ARSaflcxAt72A5r1AANrQIXiAIp6KHhuUwPG7Xp1NsBqp5TmKc404EnkaP4mYrEyrSKYShSJ2FVML1mKR0zbBylEWgjwBCwvx51qss6QDb0fLVdcfODTsrTGzmzgxXDOwY70RsXtBWmO3cXeBS/c69+vz6fb9+W7WbWc9uOmhpuPpui3kMJasZu7Vaq6bV2vu0mln12g1EYxBETgTsVQ2rpXepjD+qofVaOXxA8a2rCGefimjVKb4ljWwuvpWYa4gTLvKBB7E+9cCqt2OUq7fZ2nv1tv4pr669KB3We1L7b7Bqu45VXR6NeYJu+V+MegCvWRvy8haSCKNBjG2Rnb3LyAOwgUoq5Qr3kCkQOKB4pHhvvFybEFHfTx2fT+joFaUyejfBnWkc3KSut4wCudJkWcZuUmVaazXVrKbKOtmQquUFdue5qtbUq4G6e+Ym2Jo340PEbZ6sMWbXFHfzvQjbdll3OZZrzhgcHmmWsW/STupU6vRGW6vEIjWyzFqC3P8ClzPU7PJqM8JH4xqUl5JKycgrwrJUbEpTOZE7yJTVXn/JalYy5WxIlP1upbtZJ1NHOONmImI+GqlWKCAJ1Z96dZ+wKr5P5qrMjAFeFpfWdvz+5A5uG5arnEcSyFogvePPr35wv11VDEZy75qquH/Ti/vpbtyP3eLP03Rs5T9ou/cb \ No newline at end of file diff --git a/doc/Application Overview.jpg b/doc/Application Overview.jpg new file mode 100644 index 0000000000000000000000000000000000000000..d9fc2138c8f82933f9c38464e66174f26bb8aed7 GIT binary patch literal 27419 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 k6!>JhW=cZr2{mfkOO6w}P2m