diff --git a/src/hos_cosgi_sitemap/examples/test01.json b/src/hos_cosgi_sitemap/examples/test01.json index 9f555be3..0fb560e7 100644 --- a/src/hos_cosgi_sitemap/examples/test01.json +++ b/src/hos_cosgi_sitemap/examples/test01.json @@ -8,23 +8,28 @@ { "type": "sitemap/sitemap_template#/definitions/text_element", "label": "Switch0 Text", + "icon" : "some_icon01", + "format" : "Format: %1%", "device": { "id": "dummySwitch0", - "pointer": "" + "pointer": "/switch/value" } }, { "type": "sitemap/sitemap_template#/definitions/switch_element", "label": "Switch0", + "icon" : "some_icon02", + "format" : "bla: %1%", "device": { "id": "dummySwitch0", - "pointer": "" + "pointer": "/switch/value" } }, { "type": "sitemap/sitemap_template#/definitions/slider_element", "label": "Slider0", + "icon" : "some_icon03", "device": { - "id": "dummySlider0", - "pointer": "" + "id": "dummyDimmer0", + "pointer": "/dimmer/value" }, "min": 0, "max": 1, diff --git a/src/hos_cosgi_sitemap/include/hos_cosgi_sitemap/hos/cosgi/service/sitemap/sitemap_template/SitemapTemplate.h b/src/hos_cosgi_sitemap/include/hos_cosgi_sitemap/hos/cosgi/service/sitemap/sitemap_template/SitemapTemplate.h index aa1a7db5..fcc69213 100644 --- a/src/hos_cosgi_sitemap/include/hos_cosgi_sitemap/hos/cosgi/service/sitemap/sitemap_template/SitemapTemplate.h +++ b/src/hos_cosgi_sitemap/include/hos_cosgi_sitemap/hos/cosgi/service/sitemap/sitemap_template/SitemapTemplate.h @@ -34,6 +34,8 @@ class SitemapTemplate public: virtual SitemapService* getParent() noexcept = 0; virtual std::weak_ptr getRootPage() noexcept = 0; + + virtual libvariant::Variant renderSitemap() = 0; }; @@ -47,6 +49,8 @@ public: virtual size_t elementCount() noexcept = 0; virtual std::weak_ptr getElement(size_t index) noexcept = 0; virtual std::vector> getElements() noexcept = 0; + + virtual libvariant::Variant renderSitemap() = 0; }; @@ -72,6 +76,9 @@ public: virtual bool isComposite() noexcept = 0; virtual ElementType getType() noexcept = 0; + virtual const std::string& getTypeString() noexcept = 0; + + virtual libvariant::Variant renderSitemap() = 0; }; @@ -103,6 +110,7 @@ public: virtual const std::string& getDeviceID() noexcept = 0; virtual std::weak_ptr getDevice() noexcept = 0; virtual const std::string& getPointer() noexcept = 0; + virtual bool deviceExists() noexcept = 0; }; diff --git a/src/hos_cosgi_sitemap/src/hos/cosgi/service/sitemap/sitemap_template/SitemapTemplateImpl.cpp b/src/hos_cosgi_sitemap/src/hos/cosgi/service/sitemap/sitemap_template/SitemapTemplateImpl.cpp index 2a02b927..c4e955e1 100644 --- a/src/hos_cosgi_sitemap/src/hos/cosgi/service/sitemap/sitemap_template/SitemapTemplateImpl.cpp +++ b/src/hos_cosgi_sitemap/src/hos/cosgi/service/sitemap/sitemap_template/SitemapTemplateImpl.cpp @@ -61,15 +61,16 @@ namespace { struct _elementTypeInfo { std::string typeName; + std::string typeString; ElementType type; bool isComposite; }; _elementTypeInfo elementTypeInfo[] = { - { "sitemap/sitemap_template#/definitions/frame_element", ElementType::Frame, true }, - { "sitemap/sitemap_template#/definitions/text_element", ElementType::Text, false }, - { "sitemap/sitemap_template#/definitions/slider_element", ElementType::Slider, false }, - { "sitemap/sitemap_template#/definitions/switch_element", ElementType::Switch, false } + { "sitemap/sitemap_template#/definitions/frame_element", "sitemap/sitemap#/definitions/frame_element", ElementType::Frame, true }, + { "sitemap/sitemap_template#/definitions/text_element", "sitemap/sitemap#/definitions/text_element", ElementType::Text, false }, + { "sitemap/sitemap_template#/definitions/slider_element", "sitemap/sitemap#/definitions/slider_element", ElementType::Slider, false }, + { "sitemap/sitemap_template#/definitions/switch_element", "sitemap/sitemap#/definitions/switch_element", ElementType::Switch, false } }; } @@ -104,7 +105,7 @@ std::shared_ptr PageImpl::createElement(const libvariant::Variant& addParams.Erase("type"); _elementTypeInfo* info = nullptr; for (auto& e : elementTypeInfo) { - if (typeStr.compare(e.typeName)) { + if (typeStr.compare(e.typeName) == 0) { info = &e; break; } @@ -132,33 +133,58 @@ std::shared_ptr PageImpl::createElement(const libvariant::Variant& addParams.Erase("icon"); } } - if (info->isComposite) { - newElement = std::make_shared(*this, info->type, label, icon, parent); + switch (info->type) { + case ElementType::Frame: + newElement = std::make_shared(*this, info->typeString, label, icon, parent); + break; + default: + throw std::runtime_error((boost::format("Registered element type %1% is unknown.") % info->typeName).str()); + } } else { std::string format; - auto formatRaw = param["format"]; - if (!formatRaw.IsNull() && !formatRaw.IsString()) { - throw std::runtime_error("format is not a string."); - } else if (formatRaw.IsString()) { - format = formatRaw.AsString(); - addParams.Erase("format"); + if (param.Contains("format")) { + auto formatRaw = param["format"]; + if (!formatRaw.IsString()) { + throw std::runtime_error("format is not a string."); + } else { + format = formatRaw.AsString(); + addParams.Erase("format"); + } } std::shared_ptr device; - auto deviceRaw = param["device"]; - if (!deviceRaw.IsNull() && !deviceRaw.IsMap()) { - throw std::runtime_error("device is not a map."); - } else if (deviceRaw.IsMap()) { - device = sitemap.createDevice(deviceRaw); - addParams.Erase("device"); + if (param.Contains("device")) { + auto deviceRaw = param["device"]; + if (!deviceRaw.IsMap()) { + throw std::runtime_error("device is not a map."); + } else { + device = sitemap.createDevice(deviceRaw); + addParams.Erase("device"); + } } - auto pageRaw = param["page"]; - if (!pageRaw.IsNull() && !pageRaw.IsMap()) { - throw std::runtime_error("page is not a map."); - } else if (pageRaw.IsMap()) { - addParams.Erase("page"); + libvariant::Variant pageRaw; + if (param.Contains("page")) { + pageRaw = param["page"]; + if (!pageRaw.IsMap()) { + throw std::runtime_error("page is not a map."); + } else { + addParams.Erase("page"); + } + } + std::shared_ptr newAElement; + switch (info->type) { + case ElementType::Text: + newAElement = std::make_shared(*this, info->typeString, label, icon, format, device, addParams, parent); + break; + case ElementType::Slider: + newAElement = std::make_shared(*this, info->typeString, label, icon, format, device, addParams, parent); + break; + case ElementType::Switch: + newAElement = std::make_shared(*this, info->typeString, label, icon, format, device, addParams, parent); + break; + default: + throw std::runtime_error((boost::format("Registered element type %1% is unknown.") % info->typeName).str()); } - std::shared_ptr newAElement = std::make_shared(*this, info->type, label, icon, format, device, addParams, parent); if (pageRaw.IsMap()) { newAElement->createLinkedToPage(pageRaw); } @@ -188,6 +214,114 @@ std::shared_ptr AtomicElementImpl::createLinkedToPage(const libvariant } +libvariant::Variant SitemapTemplateImpl::renderSitemap() { + libvariant::Variant retval = libvariant::Variant::Map(); + retval["title"] = title; + retval["rootpage"] = rootPage->renderSitemap(); + retval["type"] = "sitemap/sitemap"; + return retval; +} + +libvariant::Variant PageImpl::renderSitemap() { + libvariant::Variant retval = libvariant::Variant::Map(); + retval["title"] = title; + libvariant::Variant elements = libvariant::Variant::List(); + for (auto i : this->elements) { + elements.Append(i->renderSitemap()); + } + retval["elements"] = elements; + retval["type"] = "sitemap/sitemap#/definitions/page"; + return retval; +} + +libvariant::Variant CompositeElementImpl::renderSitemap() { + libvariant::Variant retval = libvariant::Variant::Map(); + retval["label"] = label; + if (!icon.empty()) { + retval["icon"] = icon; + } + libvariant::Variant elements = libvariant::Variant::List(); + for (auto i : this->elements) { + elements.Append(i->renderSitemap()); + } + retval["elements"] = elements; + retval["type"] = typeString; + return retval; +} + +libvariant::Variant AtomicElementImpl::renderSitemap() { + libvariant::Variant retval = libvariant::Variant::Map(); + retval["label"] = label; + if (!icon.empty()) { + retval["icon"] = icon; + } + if (linkedToPage) { + retval["page"] = linkedToPage->renderSitemap(); + } + retval["value"] = _getDeviceValue(); + retval["type"] = typeString; + retval.Merge(additionalParams); + return retval; +} + + +libvariant::Variant AtomicElementImpl::_getDeviceValue() { + libvariant::Variant devState; + if (device->deviceExists()) { + try { + devState = device->getDevice().lock()->getCurrentState(); + if (!device->getPointer().empty()) { + devState = devState.GetPath(device->getPointer()); + } + } catch (...) { + devState = "NaN"; + } + } else { + devState = "NaN"; + } + if (!format.empty()) { + devState = (boost::format(format) % devState.AsString()).str(); + } + return devState; +} + +libvariant::Variant SliderElementImpl::_getDeviceValue() { + libvariant::Variant devState; + if (device->deviceExists()) { + try { + devState = device->getDevice().lock()->getCurrentState(); + if (!device->getPointer().empty()) { + devState = devState.GetPath(device->getPointer()); + } + devState = devState.AsDouble(); + } catch (...) { + devState = "NaN"; + } + } else { + devState = "NaN"; + } + return devState; +} + +libvariant::Variant SwitchElementImpl::_getDeviceValue() { + libvariant::Variant devState; + if (device->deviceExists()) { + try { + devState = device->getDevice().lock()->getCurrentState(); + if (!device->getPointer().empty()) { + devState = devState.GetPath(device->getPointer()); + } + devState = devState.AsBool(); + } catch (...) { + devState = "NaN"; + } + } else { + devState = "NaN"; + } + return devState; +} + + } // namespace sitemaptemplate } // namespace sitemap } // namespace service diff --git a/src/hos_cosgi_sitemap/src/hos/cosgi/service/sitemap/sitemap_template/SitemapTemplateImpl.h b/src/hos_cosgi_sitemap/src/hos/cosgi/service/sitemap/sitemap_template/SitemapTemplateImpl.h index 19018958..babebc55 100644 --- a/src/hos_cosgi_sitemap/src/hos/cosgi/service/sitemap/sitemap_template/SitemapTemplateImpl.h +++ b/src/hos_cosgi_sitemap/src/hos/cosgi/service/sitemap/sitemap_template/SitemapTemplateImpl.h @@ -49,6 +49,8 @@ public: virtual SitemapService* getParent() noexcept override { return dynamic_cast(&parent); } virtual std::weak_ptr getRootPage() noexcept override { return std::static_pointer_cast(rootPage); }; + + virtual libvariant::Variant renderSitemap() override; }; @@ -76,6 +78,8 @@ public: virtual std::weak_ptr getElement(size_t index) noexcept override { return std::static_pointer_cast(elements.at(index)); }; virtual std::vector> getElements() noexcept override; + + virtual libvariant::Variant renderSitemap() override; }; @@ -88,6 +92,7 @@ protected: uint64_t id; bool compositeFlag; ElementType type; + std::string typeString; PageImpl& page; CompositeElementImpl* parent; @@ -98,10 +103,12 @@ public: ElementImpl( PageImpl& page, bool isComposite, ElementType type, + std::string typeStr, CompositeElementImpl* parent, const std::string& label, const std::string& icon ) - : id(nextID.fetch_add(1)), compositeFlag(isComposite), type(type), page(page), parent(parent), label(label), icon(icon) {} + : id(nextID.fetch_add(1)), compositeFlag(isComposite), type(type), typeString(typeStr), + page(page), parent(parent), label(label), icon(icon) {} virtual uint64_t getID() noexcept override { return id; } virtual const std::string& getLabel() noexcept override { return label; } @@ -112,6 +119,7 @@ public: virtual bool isComposite() noexcept override { return compositeFlag; }; virtual ElementType getType() noexcept override { return type; } + virtual const std::string& getTypeString() noexcept override { return typeString; } }; @@ -119,19 +127,21 @@ public: class CompositeElementImpl : public virtual CompositeElement, public ElementImpl { -private: +protected: std::vector> elements; public: - CompositeElementImpl(PageImpl& page, ElementType etype, const std::string& label, const std::string& icon, + CompositeElementImpl(PageImpl& page, ElementType etype, std::string typeStr, const std::string& label, const std::string& icon, CompositeElementImpl* parent = nullptr) - : ElementImpl(page, true, etype, parent, label, icon) {} + : ElementImpl(page, true, etype, typeStr, parent, label, icon) {} std::shared_ptr createElement(const libvariant::Variant& param); virtual size_t elementCount() noexcept override { return elements.size(); } virtual std::weak_ptr getElement(size_t index) noexcept override { return std::static_pointer_cast(elements.at(index)); } virtual std::vector> getElements() noexcept override; + + virtual libvariant::Variant renderSitemap() override; }; @@ -139,25 +149,64 @@ public: class AtomicElementImpl : public virtual AtomicElement, public ElementImpl { -private: +protected: std::string format; std::shared_ptr device; libvariant::Variant additionalParams; std::shared_ptr linkedToPage; + virtual libvariant::Variant _getDeviceValue(); + public: - AtomicElementImpl(PageImpl& page, ElementType etype, const std::string& label, const std::string& icon, + AtomicElementImpl(PageImpl& page, ElementType etype, std::string typeStr, const std::string& label, const std::string& icon, const std::string& format, std::shared_ptr device, libvariant::Variant additionalParams, CompositeElementImpl* parent = nullptr) - : ElementImpl(page, false, etype, parent, label, icon), format(format), device(device), additionalParams(additionalParams) {} + : ElementImpl(page, false, etype, typeStr, parent, label, icon), format(format), device(device), additionalParams(additionalParams) {} std::shared_ptr createLinkedToPage(const libvariant::Variant& param); virtual const std::string& getFormat() noexcept override { return format; } virtual std::weak_ptr getDevice() noexcept override; virtual const libvariant::Variant& getAdditionalParams() noexcept override { return additionalParams; } - virtual std::weak_ptr getLinkedToPage() noexcept override { return linkedToPage; } + + virtual libvariant::Variant renderSitemap() override; +}; + + + +class FrameElementImpl : public CompositeElementImpl { +public: + FrameElementImpl(PageImpl& page, std::string typeStr, const std::string& label, const std::string& icon, CompositeElementImpl* parent = nullptr) + : CompositeElementImpl(page, ElementType::Frame, typeStr, label, icon, parent) {} +}; + + +class TextElementImpl : public AtomicElementImpl { +public: + TextElementImpl(PageImpl& page, std::string typeStr, const std::string& label, const std::string& icon, const std::string& format, + std::shared_ptr device, libvariant::Variant additionalParams, CompositeElementImpl* parent = nullptr) + : AtomicElementImpl(page, ElementType::Text, typeStr, label, icon, format, device, additionalParams, parent) {} +}; + + +class SliderElementImpl : public AtomicElementImpl { +private: + virtual libvariant::Variant _getDeviceValue() override; +public: + SliderElementImpl(PageImpl& page, std::string typeStr, const std::string& label, const std::string& icon, const std::string& format, + std::shared_ptr device, libvariant::Variant additionalParams, CompositeElementImpl* parent = nullptr) + : AtomicElementImpl(page, ElementType::Slider, typeStr, label, icon, format, device, additionalParams, parent) {} +}; + + +class SwitchElementImpl : public AtomicElementImpl { +private: + virtual libvariant::Variant _getDeviceValue() override; +public: + SwitchElementImpl(PageImpl& page, std::string typeStr, const std::string& label, const std::string& icon, const std::string& format, + std::shared_ptr device, libvariant::Variant additionalParams, CompositeElementImpl* parent = nullptr) + : AtomicElementImpl(page, ElementType::Switch, typeStr, label, icon, format, device, additionalParams, parent) {} }; @@ -177,6 +226,7 @@ public: virtual const std::string& getDeviceID() noexcept override { return deviceID; } virtual std::weak_ptr getDevice() noexcept override { return device; } virtual const std::string& getPointer() noexcept override { return pointer; } + virtual bool deviceExists() noexcept override { return !device.expired(); } }; diff --git a/src/hos_cosgi_sitemap/src/hos/cosgi/service/sitemap/webresource/SitemapHandler.cpp b/src/hos_cosgi_sitemap/src/hos/cosgi/service/sitemap/webresource/SitemapHandler.cpp index c8d5d629..cd91e517 100644 --- a/src/hos_cosgi_sitemap/src/hos/cosgi/service/sitemap/webresource/SitemapHandler.cpp +++ b/src/hos_cosgi_sitemap/src/hos/cosgi/service/sitemap/webresource/SitemapHandler.cpp @@ -12,6 +12,7 @@ #include #include "Poco/Net/NetException.h" #include +#include namespace hos { @@ -93,14 +94,9 @@ void SitemapHandler::__handleInfo(Poco::Net::HTTPServerRequest &req, Poco::Net:: std::string sitemapName = pathPieces[matchPieces.size()]; auto sitemap = service->getSitemap(sitemapName); if (!sitemap.expired()) { - // Get info category - std::string category; - if (pathPieces.size() > matchPieces.size() + 1) { - category = pathPieces[matchPieces.size() + 1]; - } // Get path from url and append pointer parameter std::stringstream path; - for (int i = matchPieces.size() + 2; i < pathPieces.size(); i++) { + for (int i = matchPieces.size() + 1; i < pathPieces.size(); i++) { path << "/" << pathPieces[i]; } std::string pointer; @@ -110,8 +106,8 @@ void SitemapHandler::__handleInfo(Poco::Net::HTTPServerRequest &req, Poco::Net:: } path << pointer; } - // Get device info - Variant result = libvariant::Variant("ToDo: Do something"); + // Render sitemap + Variant result = sitemap.lock()->renderSitemap(); // Return device info handleResponse(req, resp, form, result); } else {