Advertisement
Chewpacker

main.cpp

Feb 26th, 2024
776
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 6.66 KB | Source Code | 0 0
  1. #include <ESP8266WiFi.h>
  2. #include <AbstractTask.h>
  3. #include <Scheduler.h>
  4. #include <Task.h>
  5. #include <PubSubClient.h>
  6. #include "helpers/wifihelper.h"
  7. #include <Arduino.h>
  8. #include <Arduino_JSON.h>
  9. #include <string>
  10. #include <stdexcept>
  11. #include <iostream>
  12. #include <FastLED.h>
  13.  
  14. #define DATA_PIN D2
  15. #define NUM_LEDS 60
  16.  
  17. CRGB leds[NUM_LEDS];
  18.  
  19. const unsigned long LED_UPDATE_INTERVAL = 5000;
  20.  
  21. const char *mqtt_server = "";
  22.   const int mqtt_port = ;
  23.   const char *mqtt_user = "";
  24.   const char *mqtt_password = "";
  25.   const char *mqtt_requesttopic = "garmin/requestStats";
  26.   const char *mqtt_responsetopic = "garmin/responseStats";
  27.   String responseMessage;
  28.   JSONVar jsonMessage;
  29.  
  30. WiFiClient espClient;
  31. PubSubClient client(espClient);
  32.  
  33. class Steps
  34. {
  35. public:
  36.   int StepGoal;
  37.   int TotalSteps;
  38.   float CalculatePercentage()
  39.   {
  40.     if (StepGoal != 0)
  41.     {
  42.       return static_cast<float>(TotalSteps) / static_cast<float>(StepGoal) * 100.0f;
  43.     }
  44.     else
  45.     {
  46.       Serial.println("Error: Division by zero.");
  47.       return -1.0f;
  48.     }
  49.   };
  50.   Steps(int stepGoal = 0, int totalSteps = 0)
  51.   {
  52.     StepGoal = stepGoal;
  53.     totalSteps = totalSteps;
  54.   };
  55. };
  56. Steps steps(0, 0);
  57.  
  58. class StateObject {
  59.   public:
  60.     int AverageStress;
  61.     int BodyBatteryLatest;
  62.     int SleepScore;
  63.     float RestStressPercentage;
  64.     Steps StepsObject;
  65.     bool StatsMode;
  66.     unsigned long LastUpdateTime;
  67.     int LastPercentage;
  68.     CRGB LastColour;
  69.     StateObject()
  70.     {
  71.       AverageStress = 0;
  72.       BodyBatteryLatest = 0;
  73.       SleepScore = 0;
  74.       RestStressPercentage = 0;
  75.       StepsObject = Steps(1, 0);
  76.       StatsMode = false;
  77.       LastUpdateTime = 0;
  78.       LastPercentage = 0;
  79.       LastColour = CRGB::Black;
  80.     };
  81. };
  82. StateObject stateObject;
  83.  
  84. class FastLedHelper
  85. {
  86. public:
  87.   void initializeLEDs()
  88.   {
  89.     FastLED.addLeds<WS2812B, DATA_PIN, GRB>(leds, NUM_LEDS);
  90.   }
  91.  
  92.   void updateLEDs(int percentage, CRGB colour, unsigned long &lastUpdateTime)
  93.   {
  94.     int ledsToLight = map(percentage, 0, 100, 0, NUM_LEDS);
  95.  
  96.     fill_solid(leds, NUM_LEDS, colour.Black);
  97.     FastLED.show();
  98.     delay(100);
  99.  
  100.     for (int i = NUM_LEDS - 1; i > NUM_LEDS - ledsToLight; i--)
  101.     {
  102.       leds[i] = colour;
  103.       FastLED.show();
  104.       delay(75);
  105.     }
  106.   }
  107.  
  108.   void ambientDisplay()
  109.   {
  110.     Serial.println("Starting Ambient Display");
  111.     fill_solid(leds, NUM_LEDS, CRGB::Black);
  112.     FastLED.show();
  113.  
  114.     for (int i = NUM_LEDS - 1; i >= 0; i--)
  115.     {
  116.       leds[i] = CRGB::Red;
  117.       FastLED.show();
  118.       delay(75);
  119.     }
  120.   }
  121.  
  122.   void displayStats(int percentage, CRGB colour)
  123.   {
  124.     if (percentage != stateObject.LastPercentage || colour != stateObject.LastColour)
  125.     {
  126.       updateLEDs(percentage, colour, stateObject.LastUpdateTime);
  127.     }
  128.   }
  129. } fastLedHelper;
  130.  
  131. class MqttHelper
  132. {
  133. public:
  134.   static void MapStateMessageToStateObject(JSONVar message)
  135.   {
  136.     if (message.hasOwnProperty("average_stress") &&
  137.         message.hasOwnProperty("body_battery_latest") &&
  138.         message.hasOwnProperty("sleep_score") &&
  139.         message.hasOwnProperty("rest_stress_percentage") &&
  140.         message.hasOwnProperty("step_goal") &&
  141.         message.hasOwnProperty("total_steps"))
  142.     {
  143.  
  144.       stateObject.AverageStress = message["average_stress"];
  145.       stateObject.BodyBatteryLatest = message["body_battery_latest"];
  146.       stateObject.SleepScore = message["sleep_score"];
  147.       stateObject.RestStressPercentage = (double)message["rest_stress_percentage"];
  148.       stateObject.StepsObject.StepGoal = message["step_goal"];
  149.       stateObject.StepsObject.TotalSteps = message["total_steps"];
  150.       stateObject.StatsMode = message["stats_mode"];
  151.     }
  152.     else
  153.     {
  154.       char newMessage[] = "Failed to map state message to state object, one or more parameters are missing";
  155.       Serial.println(newMessage);
  156.       throw std::invalid_argument(std::string(newMessage));
  157.     }
  158.   }
  159.  
  160. static void callback(char* topic, byte* payload, unsigned int length) {
  161.     for (unsigned int i = 0; i < length; i++) {
  162.         responseMessage += (char)payload[i];
  163.     }
  164.  
  165.     Serial.println(responseMessage);
  166.  
  167.       responseMessage.replace("False", "false");
  168.       responseMessage.replace("True", "true");
  169.  
  170.     jsonMessage = JSON.parse(responseMessage);
  171.  
  172.     MqttHelper::MapStateMessageToStateObject(jsonMessage);
  173.  
  174.     responseMessage = "";
  175.     jsonMessage = null;
  176. }
  177.  
  178. static void requestStats() {
  179.     client.publish(mqtt_requesttopic, "");
  180. }
  181.  
  182.   void setupMQTT()
  183.   {
  184.     client.setServer(mqtt_server, mqtt_port);
  185.     client.setCallback(&callback);
  186.  
  187.     while (!client.connected())
  188.     {
  189.       Serial.print("Connecting to MQTT...");
  190.       if (client.connect("ESP8266Client", mqtt_user, mqtt_password))
  191.       {
  192.         Serial.println("connected to MQTT, subscribed to ");
  193.         Serial.println(mqtt_responsetopic);
  194.         client.subscribe(mqtt_responsetopic);
  195.       }
  196.       else
  197.       {
  198.         Serial.print("failed, rc=");
  199.         Serial.print(client.state());
  200.         Serial.println(" try again in 5 seconds");
  201.         delay(5000);
  202.       }
  203.     }
  204.   }
  205. } mqttHelper;
  206.  
  207. class FastLedTask : public Task
  208. {
  209. protected:
  210.   void loop()
  211.   {
  212.     if (!stateObject.StatsMode)
  213.     {
  214.       fastLedHelper.ambientDisplay();
  215.       MqttHelper::requestStats();
  216.       delay(1000);
  217.     }
  218.     else
  219.     {
  220.       fastLedHelper.displayStats(stateObject.AverageStress, CRGB::Red);
  221.       MqttHelper::requestStats();
  222.       delay(10000);
  223.       if (stateObject.StatsMode)
  224.       {
  225.         fastLedHelper.displayStats(stateObject.BodyBatteryLatest, CRGB::Blue);
  226.       MqttHelper::requestStats();
  227.       delay(10000);
  228.       }
  229.       if (stateObject.StatsMode)
  230.       {
  231.         fastLedHelper.displayStats(stateObject.SleepScore, CRGB::Orange);
  232.       MqttHelper::requestStats();
  233.       delay(10000);
  234.       }
  235.       if (stateObject.StatsMode)
  236.       {
  237.         fastLedHelper.displayStats(stateObject.RestStressPercentage, CRGB::Purple);
  238.       MqttHelper::requestStats();
  239.       delay(10000);
  240.       }
  241.       if (stateObject.StatsMode)
  242.       {
  243.         fastLedHelper.displayStats(stateObject.StepsObject.CalculatePercentage(), CRGB::Green);
  244.       MqttHelper::requestStats();
  245.       delay(10000);
  246.       }
  247.     }
  248.   }
  249.  
  250. private:
  251.   time_t lastCheck;
  252.   bool firstRun;
  253. } fastLedTask;
  254.  
  255. class MqttTask : public Task
  256. {
  257. protected:
  258.   void loop()
  259.   {
  260.     client.loop();
  261.     delay(500);
  262.   }
  263.  
  264. private:
  265.   time_t lastCheck;
  266.   bool firstRun;
  267.  
  268. } mqttTask;
  269.  
  270. void setup()
  271. {
  272.   Serial.begin(115200);
  273.  
  274.   setupWiFi();
  275.  
  276.   fastLedHelper.initializeLEDs();
  277.   mqttHelper.setupMQTT();
  278.  
  279.   Scheduler.start(&mqttTask);
  280.   Scheduler.start(&fastLedTask);
  281.  
  282.   Scheduler.begin();
  283. }
  284.  
  285. void loop()
  286. {
  287. }
  288.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement