Program Listing for File PowerSensor.hpp

Return to documentation for file (host/include/PowerSensor.hpp)

#pragma once

#include <inttypes.h>

#include <array>
#include <thread>
#include <fstream>
#include <queue>
#include <memory>
#include <string>

#include "Semaphore.hpp"

namespace PowerSensor3 {

static const unsigned MAX_SENSORS = 8;
static const unsigned MAX_PAIRS = MAX_SENSORS / 2;
static const float VOLTAGE = 3.3;
static const unsigned MAX_LEVEL = 1023;
static const std::string POWERSENSOR_VERSION = "1.4.1";

struct State {
  std::array<double, MAX_PAIRS> consumedEnergy;
  std::array<double, MAX_PAIRS> current;
  std::array<double, MAX_PAIRS> voltage;
  double timeAtRead;
};

double Joules(const State &firstState, const State &secondState, int pairID = -1 /* default: all sensor pairs */);
double seconds(const State &firstState, const State &secondState);
double Watt(const State &firstState, const State &secondState, int pairID = -1 /* default: all sensor pairs */);

class PowerSensor {
 public:
    explicit PowerSensor(std::string device);
    ~PowerSensor();

    State read() const;

    void dump(const std::string dumpFileName);  // dumpFileName == 0 --> stop dumping
    void mark(char name);
    void mark(const State &startState, const State &stopState, const std::string name = 0, unsigned int tag = 0) const;
    void reset(bool dfuMode);

    void writeSensorsToEEPROM();
    void setType(unsigned int sensorID, const std::string type);
    void setPairName(unsigned int pairID, const std::string pairName);
    void setVref(unsigned int sensorID, const float vref);
    void setSensitivity(unsigned int sensorID, const float slope);
    void setInUse(unsigned int sensorID, const bool inUse);
    void setPolarity(unsigned int sensorID, const int polarity);

    std::string getType(unsigned int sensorID) const;
    std::string getPairName(unsigned int pairID) const;
    float getVref(unsigned int sensorID) const;
    float getSensitivity(unsigned int sensorID) const;
    bool getInUse(unsigned int sensorID) const;
    int getPolarity(unsigned int sensorID) const;
    std::string getVersion();

 private:
    static const unsigned MAX_TYPE_LENGTH = 16;
    static const unsigned MAX_PAIRNAME_LENGTH = 16;

    int fd;
    int pipe_fd;
    int openDevice(std::string device);
    std::queue<char> markers;
    void writeMarker();

    void initializeSensorPairs();
    void updateSensorPairs();

    inline char readCharFromDevice();
    inline void writeCharToDevice(char buffer);
    void readSensorsFromEEPROM();
    bool readLevelFromDevice(unsigned int* sensorNumber, uint16_t* level, unsigned int* marker);

    std::unique_ptr<std::ofstream> dumpFile;
    void dumpCurrentWattToFile();

    Semaphore threadStarted;
    std::thread* thread;
    mutable std::mutex mutex, dumpFileMutex;
    double startTime;
    unsigned int timestamp;
    void IOThread();
    void startIOThread();
    void stopIOThread();
    int startCleanupProcess();

    double totalEnergy(unsigned int pairID) const;

    struct Sensor {
      struct EEPROM {
        char type[MAX_TYPE_LENGTH];
        char pairName[MAX_PAIRNAME_LENGTH];
        float vref;
        float sensitivity;
        bool inUse;
      } __attribute__((packed));

      std::string type;
      std::string pairName;
      float vref;
      float sensitivity;
      bool inUse;
      uint16_t level;
      double valueAtLastMeasurement;
      void setType(const std::string type);
      void setPairName(const std::string pairName);
      void setVref(const float vref);
      void setSensitivity(const float slope);
      void setInUse(const bool inUse);
      void setPolarity(const int polarity);
      double getValue() const;
      void readFromEEPROM(int fd);
      void writeToEEPROM(int fd) const;
      void updateLevel(uint16_t level);
      void reset();
    } sensors[MAX_SENSORS];

    struct SensorPair {
      double currentAtLastMeasurement;
      double voltageAtLastMeasurement;
      double wattAtLastMeasurement;
      double timeAtLastMeasurement;
      double consumedEnergy;
      bool inUse;
    } sensorPairs[MAX_PAIRS];
};

}  // namespace PowerSensor3