Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

DateTimePlugin: Adding analog clock view configuration #198

Merged
merged 4 commits into from
Nov 6, 2024
Merged
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
120 changes: 111 additions & 9 deletions lib/DateTimePlugin/src/DateTimePlugin.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -59,13 +59,23 @@
*****************************************************************************/

/* Initialize plugin topic. */
const char* DateTimePlugin::TOPIC_CONFIG = "/dateTime";
const char DateTimePlugin::TOPIC_CONFIG[] = "/dateTime";

/* Initialize default time format. */
const char* DateTimePlugin::TIME_FORMAT_DEFAULT = "%I:%M %p";
const char DateTimePlugin::TIME_FORMAT_DEFAULT[] = "%I:%M %p";

/* Initialize default date format. */
const char* DateTimePlugin::DATE_FORMAT_DEFAULT = "%m/%d";
const char DateTimePlugin::DATE_FORMAT_DEFAULT[] = "%m/%d";

/* Color key names for the analog clock configuration. */
const char* DateTimePlugin::ANALOG_CLOCK_COLOR_KEYS[IDateTimeView::ANA_CLK_COL_MAX] =
{
"handHourCol",
"handMinCol",
"handSecCol",
"ringFiveMinCol",
"ringMinDotCol"
};

/******************************************************************************
* Public Methods
Expand Down Expand Up @@ -95,18 +105,22 @@ bool DateTimePlugin::setTopic(const String& topic, const JsonObjectConst& value)

if (true == topic.equals(TOPIC_CONFIG))
{
const size_t JSON_DOC_SIZE = 512U;
const IDateTimeView::AnalogClockConfig* analogClockCfg = nullptr;

const size_t JSON_DOC_SIZE = 768U;
DynamicJsonDocument jsonDoc(JSON_DOC_SIZE);
JsonObject jsonCfg = jsonDoc.to<JsonObject>();
JsonVariantConst jsonMode = value["mode"];
JsonVariantConst jsonViewMode = value["viewMode"];
JsonVariantConst jsonTimeFormat = value["timeFormat"];
JsonVariantConst jsonDateFormat = value["dateFormat"];
JsonVariantConst jsonTimeZone = value["timeZone"];
JsonVariantConst jsonStartOfWeek = value["startOfWeek"];
JsonVariantConst jsonDayOnColor = value["dayOnColor"];
JsonVariantConst jsonDayOffColor = value["dayOffColor"];

/* The received configuration may not contain all single key/value pair.
JsonObjectConst jsonAnalogClock = value["analogClock"];

/* The received configuration may not contain all single key/value pair.
* Therefore read first the complete internal configuration and
* overwrite them with the received ones.
*/
Expand All @@ -122,7 +136,13 @@ bool DateTimePlugin::setTopic(const String& topic, const JsonObjectConst& value)
jsonCfg["mode"] = jsonMode.as<uint8_t>();
isSuccessful = true;
}


if (false == jsonViewMode.isNull())
{
jsonCfg["viewMode"] = jsonViewMode.as<uint8_t>();
isSuccessful = true;
}

if (false == jsonTimeFormat.isNull())
{
jsonCfg["timeFormat"] = jsonTimeFormat.as<String>();
Expand Down Expand Up @@ -158,6 +178,12 @@ bool DateTimePlugin::setTopic(const String& topic, const JsonObjectConst& value)
jsonCfg["dayOffColor"] = jsonDayOffColor.as<String>();
isSuccessful = true;
}

if (false == jsonAnalogClock.isNull())
{
jsonCfg["analogClock"] = jsonAnalogClock;
isSuccessful = true;
}

if (true == isSuccessful)
{
Expand Down Expand Up @@ -262,33 +288,59 @@ void DateTimePlugin::update(YAGfx& gfx)

void DateTimePlugin::getConfiguration(JsonObject& jsonCfg) const
{
const IDateTimeView::AnalogClockConfig* analogClockCfg = nullptr;

MutexGuard<MutexRecursive> guard(m_mutex);

jsonCfg["mode"] = m_mode;
jsonCfg["viewMode"] = m_view.getViewMode();
jsonCfg["timeFormat"] = m_timeFormat;
jsonCfg["dateFormat"] = m_dateFormat;
jsonCfg["timeZone"] = m_timeZone;
jsonCfg["startOfWeek"] = m_view.getStartOfWeek();
jsonCfg["dayOnColor"] = colorToHtml(m_view.getDayOnColor());
jsonCfg["dayOffColor"] = colorToHtml(m_view.getDayOffColor());

analogClockCfg = m_view.getAnalogClockConfig();
if (nullptr != analogClockCfg)
{
/* View supports analog clock, add the additinal config elements for it.
*/
JsonObject jsonAnalogClock = jsonCfg.createNestedObject("analogClock");
jsonAnalogClock["secondsMode"] = analogClockCfg->m_secondsMode;
for (uint32_t index = 0U; index < IDateTimeView::ANA_CLK_COL_MAX; ++index)
{
jsonAnalogClock[ANALOG_CLOCK_COLOR_KEYS[index]]= colorToHtml(analogClockCfg->m_colors[index]);
}
}

}

bool DateTimePlugin::setConfiguration(const JsonObjectConst& jsonCfg)
{
bool status = false;
JsonVariantConst jsonMode = jsonCfg["mode"];
JsonVariantConst jsonViewMode = jsonCfg["viewMode"];
JsonVariantConst jsonTimeFormat = jsonCfg["timeFormat"];
JsonVariantConst jsonDateFormat = jsonCfg["dateFormat"];
JsonVariantConst jsonTimeZone = jsonCfg["timeZone"];
JsonVariantConst jsonStartOfWeek = jsonCfg["startOfWeek"];
JsonVariantConst jsonDayOnColor = jsonCfg["dayOnColor"];
JsonVariantConst jsonDayOffColor = jsonCfg["dayOffColor"];
JsonVariantConst jsonAnalogClock = jsonCfg["analogClock"];

IDateTimeView::AnalogClockConfig analogClockConfig;

if ((false == jsonMode.is<uint8_t>()) &&
(MODE_MAX <= jsonMode.as<uint8_t>()))
{
LOG_WARNING("JSON mode not found or invalid type.");
}
else if ((false == jsonViewMode.is<uint8_t>()) &&
(IDateTimeView::VIEW_MODE_MAX <= jsonViewMode.as<uint8_t>()))
{
LOG_WARNING("JSON view mode not found or invalid type.");
}
else if (false == jsonTimeFormat.is<String>())
{
LOG_WARNING("JSON time format not found or invalid type.");
Expand All @@ -313,6 +365,10 @@ bool DateTimePlugin::setConfiguration(const JsonObjectConst& jsonCfg)
{
LOG_WARNING("JSON day off color not found or invalid type.");
}
else if (false == checkAnalogClockConfig(jsonAnalogClock, analogClockConfig))
{
/* Error printed inside checkAnalogClockConfig() already. */
}
else
{
MutexGuard<MutexRecursive> guard(m_mutex);
Expand All @@ -325,6 +381,12 @@ bool DateTimePlugin::setConfiguration(const JsonObjectConst& jsonCfg)
status = m_view.setStartOfWeek(jsonStartOfWeek.as<uint8_t>());
m_view.setDayOnColor(colorFromHtml(jsonDayOnColor.as<String>()));
m_view.setDayOffColor(colorFromHtml(jsonDayOffColor.as<String>()));
m_view.setViewMode(static_cast<IDateTimeView::ViewMode>(jsonViewMode.as<uint8_t>()));

if (false == jsonAnalogClock.isNull())
{
m_view.setAnalogClockConfig(analogClockConfig);
}

m_hasTopicChanged = true;
}
Expand Down Expand Up @@ -511,7 +573,7 @@ bool DateTimePlugin::getTimeAsString(String& time, const String& format, const t
return isSuccessful;
}

String DateTimePlugin::colorToHtml(const Color& color) const
String DateTimePlugin::colorToHtml(const Color& color)
{
char buffer[8]; /* '#' + 3x byte in hex + '\0' */

Expand All @@ -520,7 +582,7 @@ String DateTimePlugin::colorToHtml(const Color& color) const
return String(buffer);
}

Color DateTimePlugin::colorFromHtml(const String& htmlColor) const
Color DateTimePlugin::colorFromHtml(const String& htmlColor)
{
Color color;

Expand All @@ -532,6 +594,46 @@ Color DateTimePlugin::colorFromHtml(const String& htmlColor) const
return color;
}

bool DateTimePlugin::checkAnalogClockConfig(JsonVariantConst& jsonCfg, IDateTimeView::AnalogClockConfig & cfg)
{
bool result = true;

if (false == jsonCfg.isNull())
{
JsonVariantConst jsonSecondsMode = jsonCfg["secondsMode"];

if ((false == jsonSecondsMode.is<uint8_t>()) &&
(IDateTimeView::SECONDS_DISP_MAX <= jsonSecondsMode.as<uint8_t>()))
{
LOG_WARNING("JSON seconds mode not found or invalid type.");
result = false;
}
else
{
cfg.m_secondsMode = static_cast<IDateTimeView::SecondsDisplayMode>(jsonSecondsMode.as<uint8_t>());

for (uint32_t idx = 0U; idx < IDateTimeView::ANA_CLK_COL_MAX; ++ idx)
{
JsonVariantConst color = jsonCfg[ANALOG_CLOCK_COLOR_KEYS[idx]];

if (false == color.is<String>())
{
LOG_WARNING(
"JSON attribute %s not found or invalid type.",
ANALOG_CLOCK_COLOR_KEYS[idx]);
result = false;
}
else
{
cfg.m_colors[idx] = colorFromHtml(color);
}
}
}
}

return result;
}

/******************************************************************************
* External Functions
*****************************************************************************/
Expand Down
24 changes: 19 additions & 5 deletions lib/DateTimePlugin/src/DateTimePlugin.h
Original file line number Diff line number Diff line change
Expand Up @@ -279,7 +279,7 @@ class DateTimePlugin : public PluginWithConfig
/**
* Plugin topic, used to read/write the configuration.
*/
static const char* TOPIC_CONFIG;
static const char TOPIC_CONFIG[];

/** Time to check date update period in ms */
static const uint32_t CHECK_UPDATE_PERIOD = SIMPLE_TIMER_SECONDS(1U);
Expand All @@ -288,10 +288,13 @@ class DateTimePlugin : public PluginWithConfig
static const uint32_t MS_TO_SEC_DIVIDER = 1000U;

/** Default time format according to strftime(). */
static const char* TIME_FORMAT_DEFAULT;
static const char TIME_FORMAT_DEFAULT[];

/** Default date format according to strftime(). */
static const char* DATE_FORMAT_DEFAULT;
static const char DATE_FORMAT_DEFAULT[];

/** Color key names for the analog clock configuration. */
static const char* ANALOG_CLOCK_COLOR_KEYS[IDateTimeView::ANA_CLK_COL_MAX];

/**
* If the slot duration is infinite (0s), the default duration of 30s shall be assumed as base
Expand Down Expand Up @@ -359,7 +362,7 @@ class DateTimePlugin : public PluginWithConfig
*
* @return Color in HTML format
*/
String colorToHtml(const Color& color) const;
static String colorToHtml(const Color& color);

/**
* Convert color from HTML format.
Expand All @@ -368,7 +371,18 @@ class DateTimePlugin : public PluginWithConfig
*
* @return Color
*/
Color colorFromHtml(const String& htmlColor) const;
static Color colorFromHtml(const String& htmlColor);

/**
* Check if analog cfg is valid when present.
*
* @param jsonCfg[in] The json configuration, may be isNull().
* @param cfg[out] The parsed config data if json present and valid.
* @return true If no configuration or valid json values.
*/
static bool checkAnalogClockConfig(
JsonVariantConst& jsonCfg,
IDateTimeView::AnalogClockConfig & cfg);
};

/******************************************************************************
Expand Down
Loading