Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
49 changes: 48 additions & 1 deletion src/sensesp/signalk/signalk_metadata.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
#include "signalk_metadata.h"

#include <cmath>

namespace sensesp {

SKMetadata::SKMetadata(const String& units, const String& display_name,
Expand All @@ -9,7 +11,10 @@ SKMetadata::SKMetadata(const String& units, const String& display_name,
units_{units},
description_{description},
short_name_{short_name},
timeout_{timeout} {}
timeout_{timeout},
supports_put_{-1},
display_scale_lower_{NAN},
display_scale_upper_{NAN} {}

void SKMetadata::add_entry(const String& sk_path, JsonArray& meta) {
JsonObject json = meta.add<JsonObject>();
Expand All @@ -35,6 +40,48 @@ void SKMetadata::add_entry(const String& sk_path, JsonArray& meta) {
if (this->timeout_ >= 0.0) {
val["timeout"] = this->timeout_;
}

if (!this->example_.isEmpty()) {
val["example"] = this->example_;
}

if (this->supports_put_ != -1) {
val["supportsPut"] = (this->supports_put_ == 1);
}

if (!std::isnan(this->display_scale_lower_) ||
!std::isnan(this->display_scale_upper_)) {
JsonObject scale = val["displayScale"].to<JsonObject>();
if (!std::isnan(this->display_scale_lower_)) {
scale["lower"] = this->display_scale_lower_;
}
if (!std::isnan(this->display_scale_upper_)) {
scale["upper"] = this->display_scale_upper_;
}
}

if (!this->zones_.empty()) {
JsonArray zones_arr = val["zones"].to<JsonArray>();
for (const SKZone& zone : this->zones_) {
JsonObject zone_obj = zones_arr.add<JsonObject>();
zone_obj["state"] = alarm_state_to_string(zone.state_);
zone_obj["message"] = zone.message_;
if (!std::isnan(zone.lower_)) zone_obj["lower"] = zone.lower_;
if (!std::isnan(zone.upper_)) zone_obj["upper"] = zone.upper_;
}
}
}

const char* SKMetadata::alarm_state_to_string(SKAlarmState state) {
switch (state) {
case SKAlarmState::kNominal: return "nominal";
case SKAlarmState::kNormal: return "normal";
case SKAlarmState::kAlert: return "alert";
case SKAlarmState::kWarn: return "warn";
case SKAlarmState::kAlarm: return "alarm";
case SKAlarmState::kEmergency: return "emergency";
default: return "normal";
}
}

} // namespace sensesp
44 changes: 43 additions & 1 deletion src/sensesp/signalk/signalk_metadata.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,39 @@
#define SENSESP_SIGNALK_SIGNALK_METADATA_H_

#include <ArduinoJson.h>
#include <cmath>
#include <vector>

namespace sensesp {

/**
* @brief Alarm state values for Signal K Zone metadata.
* @see https://demo.signalk.org/documentation/_signalk/server-api/ALARM_STATE.html
*/
enum class SKAlarmState {
kNominal,
kNormal,
kAlert,
kWarn,
kAlarm,
kEmergency
};

/**
* @brief Represents a single Signal K alarm zone within metadata.
* @see https://demo.signalk.org/documentation/_signalk/server-api/Zone.html
*/
struct SKZone {
float lower_; ///< Lower bound of the zone; NAN if not set
float upper_; ///< Upper bound of the zone; NAN if not set
String message_;
SKAlarmState state_;

SKZone(SKAlarmState state, const String& message,
float lower = NAN, float upper = NAN)
: lower_{lower}, upper_{upper}, message_{message}, state_{state} {}
};

/**
* @brief Holds Signal K meta data that is associated with
* the sk_path an SKEmitter class may optionally send to the server.
Expand All @@ -28,6 +58,11 @@ class SKMetadata {
String description_;
String short_name_;
float timeout_;
String example_;
int supports_put_; ///< -1 = not set, 0 = false, 1 = true
float display_scale_lower_; ///< NAN = not set
float display_scale_upper_; ///< NAN = not set
std::vector<SKZone> zones_;

/**
* @param units The unit of measurement the value represents. See
Expand All @@ -49,7 +84,11 @@ class SKMetadata {
float timeout = -1.0);

/// Default constructor creates a blank Metadata structure
SKMetadata() : timeout_{-1} {}
SKMetadata()
: timeout_{-1},
supports_put_{-1},
display_scale_lower_{NAN},
display_scale_upper_{NAN} {}

/**
* Adds an entry to the specified meta array that represents this metadata
Expand All @@ -59,6 +98,9 @@ class SKMetadata {
* @param[out] meta The array the metadata entry is supposed to be added to
*/
virtual void add_entry(const String& sk_path, JsonArray& meta);

private:
static const char* alarm_state_to_string(SKAlarmState state);
};

} // namespace sensesp
Expand Down