215 lines
5.8 KiB
C++
215 lines
5.8 KiB
C++
/*******************************************************************************
|
|
Copyright © 2017 Philips Lighting Holding B.V.
|
|
All Rights Reserved.
|
|
********************************************************************************/
|
|
|
|
#include <algorithm>
|
|
#include "FullConfigRetriever.h"
|
|
|
|
namespace huestream {
|
|
|
|
#define CLIP_ERROR_TYPE_UNAUTHORIZED_USER 1
|
|
|
|
FullConfigRetriever::FullConfigRetriever(const shared_ptr<IHttp> http) : _http(http), _currentlyStreamingUsername("") {
|
|
}
|
|
|
|
void FullConfigRetriever::Execute(BridgePtr bridge, RetrieveCallbackHandler cb) {
|
|
_bridge = bridge;
|
|
_cb = cb;
|
|
|
|
if (!GetFullConfig()) {
|
|
_cb(OPERATION_FAILED, _bridge);
|
|
return;
|
|
}
|
|
|
|
if (!ParseToJson()) {
|
|
_cb(OPERATION_FAILED, _bridge);
|
|
return;
|
|
}
|
|
|
|
if (!CheckForNoErrorsInResponse()) {
|
|
_cb(OPERATION_FAILED, _bridge);
|
|
return;
|
|
}
|
|
|
|
if (!ParseConfig()) {
|
|
_cb(OPERATION_FAILED, _bridge);
|
|
return;
|
|
}
|
|
|
|
ParseGroups();
|
|
|
|
_cb(OPERATION_SUCCESS, _bridge);
|
|
}
|
|
|
|
bool FullConfigRetriever::GetFullConfig() {
|
|
string _baseUrl = "http://" + _bridge->GetIpAddress() + "/api/" + _bridge->GetUser() + "/";
|
|
string fullConfigUrl = _baseUrl;
|
|
|
|
auto req = std::make_shared<HttpRequestInfo>(HTTP_REQUEST_GET, fullConfigUrl);
|
|
_http->Execute(req);
|
|
|
|
if (req->GetSuccess()) {
|
|
_response = req->GetResponse();
|
|
} else {
|
|
_bridge->SetIsValidIp(false);
|
|
}
|
|
|
|
return req->GetSuccess();
|
|
}
|
|
|
|
bool FullConfigRetriever::ParseToJson() {
|
|
JSONNode n = libjson::parse(_response);
|
|
if (n.type() == JSON_NULL) {
|
|
_bridge->SetIsValidIp(false);
|
|
return false;
|
|
}
|
|
_root = n;
|
|
return true;
|
|
}
|
|
|
|
bool FullConfigRetriever::CheckForNoErrorsInResponse() const {
|
|
bool hasError = false;
|
|
bool hasUnauthorizedError = false;
|
|
|
|
if (_root.type() == JSON_ARRAY) {
|
|
for (auto it = _root.begin(); it != _root.end(); ++it) {
|
|
auto entry = it->find("error");
|
|
if (entry != it->end()) {
|
|
hasError = true;
|
|
auto i = entry->find("type");
|
|
if (i != entry->end()) {
|
|
if (i->as_int() == CLIP_ERROR_TYPE_UNAUTHORIZED_USER) {
|
|
hasUnauthorizedError = true;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (hasError) {
|
|
if (hasUnauthorizedError) {
|
|
_bridge->SetIsAuthorized(false);
|
|
_bridge->SetIsValidIp(true);
|
|
} else {
|
|
_bridge->SetIsValidIp(false);
|
|
}
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
bool FullConfigRetriever::ParseConfig() const {
|
|
if (!SerializerHelper::IsAttributeSet(&_root, "config")) {
|
|
_bridge->SetIsValidIp(false);
|
|
return false;
|
|
}
|
|
|
|
JSONNode config = (_root)["config"];
|
|
string name = "";
|
|
Serializable::DeserializeValue(&config, "name", &name, "");
|
|
_bridge->SetName(name);
|
|
|
|
string modelid = "";
|
|
Serializable::DeserializeValue(&config, "modelid", &modelid, "");
|
|
_bridge->SetModelId(modelid);
|
|
|
|
string swversion = "";
|
|
Serializable::DeserializeValue(&config, "swversion", &swversion, "");
|
|
_bridge->SetSoftwareVersion(swversion);
|
|
|
|
string apiversion = "";
|
|
Serializable::DeserializeValue(&config, "apiversion", &apiversion, "");
|
|
_bridge->SetApiversion(apiversion);
|
|
|
|
string bridgeid = "";
|
|
Serializable::DeserializeValue(&config, "bridgeid", &bridgeid, "");
|
|
_bridge->SetId(bridgeid);
|
|
|
|
if (!SerializerHelper::IsAttributeSet(&_root, "groups")) {
|
|
_bridge->SetIsValidIp(false);
|
|
return false;
|
|
}
|
|
|
|
_bridge->SetIsValidIp(true);
|
|
return true;
|
|
}
|
|
|
|
void FullConfigRetriever::ParseGroups() {
|
|
JSONNode groups = (_root)["groups"];
|
|
auto parsedGroups = std::make_shared<GroupList>();
|
|
for (auto jsonGroup = groups.begin(); jsonGroup != groups.end(); ++jsonGroup) {
|
|
if (GroupIsEntertainment(*jsonGroup) && GroupIsClassTv(*jsonGroup)) {
|
|
auto group = ParseEntertainmentGroup(*jsonGroup);
|
|
parsedGroups->push_back(group);
|
|
}
|
|
}
|
|
_bridge->SetGroups(parsedGroups);
|
|
}
|
|
|
|
bool FullConfigRetriever::GroupIsEntertainment(const JSONNode& j) {
|
|
return (SerializerHelper::IsAttributeSet(&j, "type") && j["type"].as_string() == "Entertainment");
|
|
}
|
|
|
|
bool FullConfigRetriever::GroupIsClassTv(const JSONNode& j) {
|
|
return (SerializerHelper::IsAttributeSet(&j, "class") && j["class"].as_string() == "TV");
|
|
}
|
|
|
|
shared_ptr<Group> FullConfigRetriever::ParseEntertainmentGroup(const JSONNode& node) {
|
|
auto groupId = std::stoi(node.name());
|
|
|
|
auto group = std::make_shared<Group>();
|
|
group->SetId(groupId);
|
|
|
|
string name = "";
|
|
Serializable::DeserializeValue(&node, "name", &name, "");
|
|
group->SetName(name);
|
|
|
|
ParseLightsAndLocations(node, group);
|
|
|
|
ParseStreamActive(node, group);
|
|
|
|
return group;
|
|
}
|
|
|
|
void FullConfigRetriever::ParseLightsAndLocations(const JSONNode& node, GroupPtr group) const {
|
|
if (SerializerHelper::IsAttributeSet(&node, "locations")) {
|
|
auto locations = node["locations"];
|
|
for (auto i = locations.begin(); i != locations.end(); ++i) {
|
|
auto lightId = std::stoi(i->name());
|
|
auto coordinates = *i;
|
|
group->AddLight(lightId, coordinates[0].as_float(), coordinates[1].as_float());
|
|
}
|
|
}
|
|
}
|
|
|
|
void FullConfigRetriever::ParseStreamActive(const JSONNode& node, GroupPtr group) {
|
|
if (SerializerHelper::IsAttributeSet(&node, "stream")) {
|
|
auto stream = node["stream"];
|
|
if (SerializerHelper::IsAttributeSet(&stream, "active") && SerializerHelper::IsAttributeSet(&stream, "owner")) {
|
|
auto active = stream["active"].as_bool();
|
|
group->SetActive(active);
|
|
if (active) {
|
|
auto owner = stream["owner"].as_string();
|
|
group->SetOwner(owner);
|
|
group->SetFriendlyOwnerName(GetFriendlyName(owner));
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
std::string FullConfigRetriever::GetFriendlyName(std::string userName) {
|
|
std::string name = "";
|
|
JSONNode config = (_root)["config"];
|
|
if (SerializerHelper::IsAttributeSet(&config, "whitelist")) {
|
|
JSONNode whitelist = (config)["whitelist"];
|
|
if (SerializerHelper::IsAttributeSet(&whitelist, userName)) {
|
|
JSONNode user = (whitelist)[userName];
|
|
Serializable::DeserializeValue(&user, "name", &name, "");
|
|
}
|
|
}
|
|
return name;
|
|
}
|
|
|
|
}
|