Add external libraries

This commit is contained in:
sylvieee-iot 2024-05-02 20:28:41 +03:00 committed by GitHub
parent 70f443b06e
commit e8dc11cc31
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
17 changed files with 2010 additions and 0 deletions

View file

@ -0,0 +1,423 @@
#include "../include/buttplugclient.h"
/*
TODO: Let the user access the devices in more details, that is, how many scalar cmds,
how many sensor cmds and their types. Implement some kind of logging to track whether
commands are successful. Implement Linear and Rotation cmds. Port to Linux.
Investigate whether push back won't ruin sending scalar and sensor cmds, since the
device list does not provide scalar or sensor indices (don't think it will).
*/
// Connection function with a function parameter which acts as a callback.
int Client::connect(void (*callFunc)(const mhl::Messages)) {
FullUrl = lUrl + ":" + std::to_string(lPort);
webSocket.setUrl(FullUrl);
// Ping interval option.
webSocket.setPingInterval(10);
// Per message deflate connection is enabled by default. You can tweak its parameters or disable it
webSocket.disablePerMessageDeflate();
// Set the callback function of the websocket
std::function<void(const ix::WebSocketMessagePtr&)> callback = std::bind(&Client::callbackFunction, this, std::placeholders::_1);
messageCallback = callFunc;
webSocket.setOnMessageCallback(callback);
// Start websocket and indicate that it is connecting (non blocking function, other functions must wait for it to connect).
webSocket.start();
isConnecting = 1;
// Start a message handler thread and detach it.
std::thread messageHandler(&Client::messageHandling, this);
messageHandler.detach();
// Connect to server, specifically send a RequestServerInfo
connectServer();
return 0;
}
// Websocket callback function.
void Client::callbackFunction(const ix::WebSocketMessagePtr& msg) {
// If a message is received to the websocket, pass it to the message handler and notify to stop waiting.
if (msg->type == ix::WebSocketMessageType::Message)
{
// Mutex lock this scope.
std::lock_guard<std::mutex> lock{msgMx};
// Push message.
q.push(msg->str);
// Notify conditional variable to stop waiting.
cond.notify_one();
}
// Handle websocket errors.
if (msg->type == ix::WebSocketMessageType::Error)
{
std::stringstream ss;
ss << "Error: " << msg->errorInfo.reason << std::endl;
ss << "#retries: " << msg->errorInfo.retries << std::endl;
ss << "Wait time(ms): " << msg->errorInfo.wait_time << std::endl;
ss << "HTTP Status: " << msg->errorInfo.http_status << std::endl;
std::cout << ss.str() << std::endl;
}
// Set atomic variable that websocket is connected once it is open.
if (msg->type == ix::WebSocketMessageType::Open) {
wsConnected = 1;
condWs.notify_all();
}
// Set atomic variable that websocket is not connected if socket closes.
if (msg->type == ix::WebSocketMessageType::Close) {
wsConnected = 0;
}
}
// Function to start scanning in the server.
void Client::startScan() {
// Mutex lock scope.
std::lock_guard<std::mutex> lock{msgMx};
// Get a request class from message handling header.
mhl::Requests req;
// Set the ID of message according to the message enum in message handling header.
req.startScanning.Id = static_cast<unsigned int>(mhl::MessageTypes::StartScanning);
// Set message type for the handler to recognize what message it is.
messageHandler.messageType = mhl::MessageTypes::StartScanning;
// Convert the returned handled request message class to json.
json j = json::array({ messageHandler.handleClientRequest(req) });
std::cout << j << std::endl;
// Start a thread that sends the message.
std::thread sendHandler(&Client::sendMessage, this, j, messageHandler.messageType);
sendHandler.detach();
}
// Function to stop scanning, same as before but different type.
void Client::stopScan() {
std::lock_guard<std::mutex> lock{msgMx};
mhl::Requests req;
req.stopScanning.Id = static_cast<unsigned int>(mhl::MessageTypes::StopScanning);
messageHandler.messageType = mhl::MessageTypes::StopScanning;
json j = json::array({ messageHandler.handleClientRequest(req) });
std::cout << j << std::endl;
std::thread sendHandler(&Client::sendMessage, this, j, messageHandler.messageType);
sendHandler.detach();
}
// Function to get device list, same as before but different type.
void Client::requestDeviceList() {
std::lock_guard<std::mutex> lock{msgMx};
mhl::Requests req;
req.stopScanning.Id = static_cast<unsigned int>(mhl::MessageTypes::RequestDeviceList);
messageHandler.messageType = mhl::MessageTypes::RequestDeviceList;
json j = json::array({ messageHandler.handleClientRequest(req) });
std::cout << j << std::endl;
std::thread sendHandler(&Client::sendMessage, this, j, messageHandler.messageType);
sendHandler.detach();
}
// Function to send RequestServerInfo, same as before but different type.
void Client::connectServer() {
std::lock_guard<std::mutex> lock{msgMx};
mhl::Requests req;
req.requestServerInfo.Id = static_cast<unsigned int>(mhl::MessageTypes::RequestServerInfo);
req.requestServerInfo.ClientName = "Testing";
req.requestServerInfo.MessageVersion = 3;
messageHandler.messageType = mhl::MessageTypes::RequestServerInfo;
json j = json::array({ messageHandler.handleClientRequest(req) });
std::cout << j << std::endl;
std::thread sendHandler(&Client::sendMessage, this, j, messageHandler.messageType);
sendHandler.detach();
}
// Function that actually sends the message.
void Client::sendMessage(json msg, mhl::MessageTypes mType) {
// First check whether a connection process is started.
if (!isConnecting && !wsConnected) {
std::cout << "Client is not connected and not started, start before sending a message" << std::endl;
return;
}
// If started, wait for the socket to connect first.
if (!wsConnected && isConnecting) {
std::unique_lock<std::mutex> lock{msgMx};
DEBUG_MSG("Waiting for socket to connect");
auto wsConnStatus = [this]() {return wsConnected == 1; };
condWs.wait(lock, wsConnStatus);
std::cout << "Connected to socket" << std::endl;
//webSocket.send(msg.dump());
}
// Once socket is connected, either wait for client to connect, or send a message if the message type
// is a request server info, since this is our client connection message.
if (!clientConnected && isConnecting) {
std::cout << "Waiting for client to connect" << std::endl;
if (mType == mhl::MessageTypes::RequestServerInfo) {
webSocket.send(msg.dump());
if (logging) logInfo.logSentMessage("RequestServerInfo", static_cast<unsigned int>(mType));
std::cout << "Started connection to client" << std::endl;
return;
}
std::unique_lock<std::mutex> lock{msgMx};
auto clientConnStatus = [this]() {return clientConnected == 1; };
condClient.wait(lock, clientConnStatus);
std::cout << "Connected to client" << std::endl;
webSocket.send(msg.dump());
}
// If everything is connected, simply send message and log request if enabled.
else if (wsConnected && clientConnected) webSocket.send(msg.dump());
if (logging) {
auto result = std::find_if(
messageHandler.messageMap.begin(),
messageHandler.messageMap.end(),
[mType](std::pair<const mhl::MessageTypes, std::basic_string<char> > mo) {return mo.first == mType; });
std::string msgTypeText = result->second;
logInfo.logSentMessage(msgTypeText, static_cast<unsigned int>(mType));
}
}
// This takes the device data from message handler and puts it in to main device class
// for user access.
void Client::updateDevices() {
std::vector<DeviceClass> tempDeviceVec;
// Iterate through available devices.
for (auto& el : messageHandler.deviceList.Devices) {
DeviceClass tempDevice;
// Set the appropriate class variables.
tempDevice.deviceID = el.DeviceIndex;
tempDevice.deviceName = el.DeviceName;
tempDevice.displayName = el.DeviceDisplayName;
if (el.DeviceMessages.size() > 0) {
for (auto& el2 : el.DeviceMessages) tempDevice.commandTypes.push_back(el2.CmdType);
}
// Push back the device in vector.
tempDeviceVec.push_back(tempDevice);
}
devices = tempDeviceVec;
}
// Mutex locked function to provide the user with available devices.
std::vector<DeviceClass> Client::getDevices() {
std::lock_guard<std::mutex> lock{msgMx};
return devices;
}
SensorClass Client::getSensors() {
std::lock_guard<std::mutex> lock{msgMx};
return sensorData;
}
int Client::findDevice(DeviceClass dev) {
for (int i = 0; i < messageHandler.deviceList.Devices.size(); i++)
if (messageHandler.deviceList.Devices[i].DeviceIndex == dev.deviceID)
return i;
return -1;
}
void Client::stopDevice(DeviceClass dev) {
std::lock_guard<std::mutex> lock{msgMx};
mhl::Requests req;
req.stopDeviceCmd.Id = static_cast<unsigned int>(mhl::MessageTypes::StopDeviceCmd);
req.stopDeviceCmd.DeviceIndex = dev.deviceID;
messageHandler.messageType = mhl::MessageTypes::StopDeviceCmd;
json j = json::array({ messageHandler.handleClientRequest(req) });
std::cout << j << std::endl;
std::thread sendHandler(&Client::sendMessage, this, j, messageHandler.messageType);
sendHandler.detach();
}
void Client::stopAllDevices() {
std::lock_guard<std::mutex> lock{msgMx};
mhl::Requests req;
req.stopDeviceCmd.Id = static_cast<unsigned int>(mhl::MessageTypes::StopAllDevices);
messageHandler.messageType = mhl::MessageTypes::StopAllDevices;
json j = json::array({ messageHandler.handleClientRequest(req) });
std::cout << j << std::endl;
std::thread sendHandler(&Client::sendMessage, this, j, messageHandler.messageType);
sendHandler.detach();
}
void Client::sendScalar(DeviceClass dev, double str) {
std::lock_guard<std::mutex> lock{msgMx};
int idx = findDevice(dev);
if (idx > -1) {
mhl::Requests req;
for (auto& el1 : messageHandler.deviceList.Devices[idx].DeviceMessages) {
std::string testScalar = "ScalarCmd";
if (!el1.CmdType.compare(testScalar)) {
req.scalarCmd.DeviceIndex = messageHandler.deviceList.Devices[idx].DeviceIndex;
req.scalarCmd.Id = static_cast<unsigned int>(mhl::MessageTypes::ScalarCmd);
int i = 0;
for (auto& el2: el1.DeviceCmdAttributes) {
Scalar sc;
sc.ActuatorType = el2.ActuatorType;
sc.ScalarVal = str;
sc.Index = i;
req.scalarCmd.Scalars.push_back(sc);
i++;
}
messageHandler.messageType = mhl::MessageTypes::ScalarCmd;
json j = json::array({ messageHandler.handleClientRequest(req) });
std::cout << j << std::endl;
std::thread sendHandler(&Client::sendMessage, this, j, messageHandler.messageType);
sendHandler.detach();
}
}
}
}
void Client::sensorRead(DeviceClass dev, int senIndex) {
std::lock_guard<std::mutex> lock{msgMx};
int idx = findDevice(dev);
if (idx > -1) {
mhl::Requests req;
for (auto& el1 : messageHandler.deviceList.Devices[idx].DeviceMessages) {
std::string testSensor = "SensorReadCmd";
if (!el1.CmdType.compare(testSensor)) {
req.sensorReadCmd.DeviceIndex = messageHandler.deviceList.Devices[idx].DeviceIndex;
req.sensorReadCmd.Id = static_cast<unsigned int>(mhl::MessageTypes::SensorReadCmd);
req.sensorReadCmd.SensorIndex = senIndex;
req.sensorReadCmd.SensorType = el1.DeviceCmdAttributes[senIndex].SensorType;
int i = 0;
messageHandler.messageType = mhl::MessageTypes::SensorReadCmd;
json j = json::array({ messageHandler.handleClientRequest(req) });
std::cout << j << std::endl;
std::thread sendHandler(&Client::sendMessage, this, j, messageHandler.messageType);
sendHandler.detach();
}
}
}
}
void Client::sensorSubscribe(DeviceClass dev, int senIndex) {
std::lock_guard<std::mutex> lock{msgMx};
int idx = findDevice(dev);
if (idx > -1) {
mhl::Requests req;
for (auto& el1 : messageHandler.deviceList.Devices[idx].DeviceMessages) {
std::string testSensor = "SensorReadCmd";
if (!el1.CmdType.compare(testSensor)) {
req.sensorSubscribeCmd.DeviceIndex = messageHandler.deviceList.Devices[idx].DeviceIndex;
req.sensorSubscribeCmd.Id = static_cast<unsigned int>(mhl::MessageTypes::SensorSubscribeCmd);
req.sensorSubscribeCmd.SensorIndex = senIndex;
req.sensorSubscribeCmd.SensorType = el1.DeviceCmdAttributes[senIndex].SensorType;
int i = 0;
messageHandler.messageType = mhl::MessageTypes::SensorSubscribeCmd;
json j = json::array({ messageHandler.handleClientRequest(req) });
std::cout << j << std::endl;
std::thread sendHandler(&Client::sendMessage, this, j, messageHandler.messageType);
sendHandler.detach();
}
}
}
}
void Client::sensorUnsubscribe(DeviceClass dev, int senIndex) {
std::lock_guard<std::mutex> lock{msgMx};
int idx = findDevice(dev);
if (idx > -1) {
mhl::Requests req;
for (auto& el1 : messageHandler.deviceList.Devices[idx].DeviceMessages) {
std::string testSensor = "SensorReadCmd";
if (!el1.CmdType.compare(testSensor)) {
req.sensorUnsubscribeCmd.DeviceIndex = messageHandler.deviceList.Devices[idx].DeviceIndex;
req.sensorUnsubscribeCmd.Id = static_cast<unsigned int>(mhl::MessageTypes::SensorUnsubscribeCmd);
req.sensorUnsubscribeCmd.SensorIndex = senIndex;
req.sensorUnsubscribeCmd.SensorType = el1.DeviceCmdAttributes[senIndex].SensorType;
int i = 0;
messageHandler.messageType = mhl::MessageTypes::SensorUnsubscribeCmd;
json j = json::array({ messageHandler.handleClientRequest(req) });
std::cout << j << std::endl;
std::thread sendHandler(&Client::sendMessage, this, j, messageHandler.messageType);
sendHandler.detach();
}
}
}
}
// Message handling function.
// TODO: add client disconnect which stops this thread too.
void Client::messageHandling() {
// Start infinite loop.
while (1) {
std::unique_lock<std::mutex> lock{msgMx};
// A lambda that waits to receive messages in the queue.
cond.wait(
lock,
[this] {
return !q.empty();
}
);
// If received, grab the message and pop it out.
std::string value = q.front();
q.pop();
// Handle the message.
json j = json::parse(value);
// Iterate through messages since server can send array.
for (auto& el : j.items()) {
// Pass the message to actual handler.
messageHandler.handleServerMessage(el.value());
// If server info received, it means client is connected so set the connection atomic variables
// and notify all send threads that they are good to go.
if (messageHandler.messageType == mhl::MessageTypes::ServerInfo) {
isConnecting = 0;
clientConnected = 1;
condClient.notify_all();
}
// If a device updated message, make sure to update the devices for the user.
if (messageHandler.messageType == mhl::MessageTypes::DeviceAdded ||
messageHandler.messageType == mhl::MessageTypes::DeviceList ||
messageHandler.messageType == mhl::MessageTypes::DeviceRemoved) updateDevices();
if (messageHandler.messageType == mhl::MessageTypes::SensorReading) sensorData = messageHandler.sensorReading;
// Log if logging is enabled.
if (logging)
logInfo.logReceivedMessage(el.value().begin().key(), static_cast<unsigned int>(messageHandler.messageType));
// Callback function for the user.
messageCallback(messageHandler);
}
lock.unlock();
std::cout << "[subscriber] Received " << value << std::endl;
}
}

20
third_party/open-bp-cpp/source/log.cpp vendored Normal file
View file

@ -0,0 +1,20 @@
#include "../include/log.h"
void Logger::init(std::string filename) {
logFile.open(filename, std::fstream::out);
}
void Logger::logSentMessage(std::string rqType, unsigned int id) {
end = std::chrono::system_clock::now();
std::chrono::duration<double> elapsed_seconds = end - start;
RequestQueue tempQ;
tempQ.id = id;
tempQ.requestType = rqType;
rQueue.push_back(tempQ);
logFile << elapsed_seconds.count() << " s, Request type sent: " << rqType << ", ID: " << id << std::endl;
}
void Logger::logReceivedMessage(std::string repType, unsigned int id) {
//end = std::chrono::system_clock::now();
}

View file

@ -0,0 +1,100 @@
#include "../include/messageHandler.h"
namespace mhl {
// Function that handles messages received from server.
void Messages::handleServerMessage(json& msg) {
// Grab the string of message type and find it in the map.
auto msgType = msg.begin().key();
auto result = std::find_if(
messageMap.begin(),
messageMap.end(),
[msgType](std::pair<const mhl::MessageTypes, std::basic_string<char> > mo) {return mo.second == msgType; });
auto msgEnumType = result->first;
int i = 0;
// Switch that converts message to class.
switch (msgEnumType) {
case mhl::MessageTypes::Ok:
messageType = mhl::MessageTypes::Ok;
ok = msg.get<msg::Ok>();
break;
case mhl::MessageTypes::Error:
messageType = mhl::MessageTypes::Error;
error = msg.get<msg::Error>();
break;
case mhl::MessageTypes::ServerInfo:
// Set message type and convert to class from json.
std::cout << "Server info!" << std::endl;
messageType = mhl::MessageTypes::ServerInfo;
serverInfo = msg.get<msg::ServerInfo>();
break;
case mhl::MessageTypes::ScanningFinished:
break;
case mhl::MessageTypes::DeviceList:
std::cout << "Device list!" << std::endl;
messageType = mhl::MessageTypes::DeviceList;
deviceList = msg.get<msg::DeviceList>();
break;
case mhl::MessageTypes::DeviceAdded:
deviceAdded = msg.get<msg::DeviceAdded>();
messageType = mhl::MessageTypes::DeviceAdded;
// Push back to message handler class device list the newly added device.
deviceList.Devices.push_back(deviceAdded.device);
break;
case mhl::MessageTypes::DeviceRemoved:
deviceRemoved = msg.get<msg::DeviceRemoved>();
messageType = mhl::MessageTypes::DeviceRemoved;
// Erase device from message handler class device list.
for (auto& el : deviceList.Devices) {
if (deviceRemoved.DeviceIndex == el.DeviceIndex) {
deviceList.Devices.erase(deviceList.Devices.begin() + i);
break;
}
i++;
}
break;
case mhl::MessageTypes::SensorReading:
sensorReading = msg.get<msg::SensorReading>();
messageType = mhl::MessageTypes::SensorReading;
break;
}
}
// Convert client request classes to json.
json Messages::handleClientRequest(Requests req) {
json j;
switch (messageType) {
case mhl::MessageTypes::RequestServerInfo:
j = req.requestServerInfo;
break;
case mhl::MessageTypes::RequestDeviceList:
j = req.requestDeviceList;
break;
case mhl::MessageTypes::StartScanning:
j = req.startScanning;
break;
case mhl::MessageTypes::StopScanning:
j = req.stopScanning;
break;
case mhl::MessageTypes::StopDeviceCmd:
j = req.stopDeviceCmd;
break;
case mhl::MessageTypes::StopAllDevices:
j = req.stopAllDevices;
break;
case mhl::MessageTypes::ScalarCmd:
j = req.scalarCmd;
break;
case mhl::MessageTypes::SensorReadCmd:
j = req.sensorReadCmd;
break;
case mhl::MessageTypes::SensorSubscribeCmd:
j = req.sensorSubscribeCmd;
break;
case mhl::MessageTypes::SensorUnsubscribeCmd:
j = req.sensorUnsubscribeCmd;
break;
}
return j;
}
}

View file

@ -0,0 +1,218 @@
#include "../include/messages.h"
// Function definitions for json conversions.
namespace msg {
void to_json(json& j, const RequestServerInfo& k) {
j["RequestServerInfo"] = { {"Id", k.Id}, {"ClientName", k.ClientName}, {"MessageVersion", k.MessageVersion} };
}
void to_json(json& j, const StartScanning& k) {
j["StartScanning"] = { {"Id", k.Id} };
}
void to_json(json& j, const StopScanning& k) {
j["StopScanning"] = { {"Id", k.Id} };
}
void to_json(json& j, const RequestDeviceList& k) {
j["RequestDeviceList"] = { {"Id", k.Id} };
}
void to_json(json& j, const StopDeviceCmd& k) {
j["StopDeviceCmd"] = { {"Id", k.Id}, {"DeviceIndex", k.DeviceIndex} };
}
void to_json(json& j, const StopAllDevices& k) {
j["StopAllDevices"] = { {"Id", k.Id} };
}
void to_json(json& j, const ScalarCmd& k) {
j["ScalarCmd"] = { {"Id", k.Id}, {"DeviceIndex", k.DeviceIndex} };
j["ScalarCmd"]["Scalars"] = json::array();
for (auto& vec : k.Scalars) {
json jTemp = { { "Index", vec.Index }, { "Scalar", vec.ScalarVal }, { "ActuatorType", vec.ActuatorType } };
j["ScalarCmd"]["Scalars"].insert(j["ScalarCmd"]["Scalars"].end(), jTemp);
}
}
void to_json(json& j, const SensorReadCmd& k) {
j["SensorReadCmd"] = { {"Id", k.Id}, {"DeviceIndex", k.DeviceIndex}, {"SensorIndex", k.SensorIndex}, {"SensorType", k.SensorType}};
}
void to_json(json& j, const SensorSubscribeCmd& k) {
j["SensorSubscribeCmd"] = { {"Id", k.Id}, {"DeviceIndex", k.DeviceIndex}, {"SensorIndex", k.SensorIndex}, {"SensorType", k.SensorType} };
}
void to_json(json& j, const SensorUnsubscribeCmd& k) {
j["SensorUnsubscribeCmd"] = { {"Id", k.Id}, {"DeviceIndex", k.DeviceIndex}, {"SensorIndex", k.SensorIndex}, {"SensorType", k.SensorType} };
}
void from_json(const json& j, ServerInfo& k) {
json jTemp;
j.at("ServerInfo").get_to(jTemp);
jTemp.at("Id").get_to(k.Id);
jTemp.at("ServerName").get_to(k.ServerName);
jTemp.at("MessageVersion").get_to(k.MessageVersion);
jTemp.at("MaxPingTime").get_to(k.MaxPingTime);
}
void from_json(const json& j, Ok& k) {
json jTemp;
j.at("Ok").get_to(jTemp);
jTemp.at("Id").get_to(k.Id);
}
void from_json(const json& j, Error& k) {
json jTemp;
j.at("Error").get_to(jTemp);
jTemp.at("Id").get_to(k.Id);
jTemp.at("ErrorCode").get_to(k.ErrorCode);
jTemp.at("ErrorMessage").get_to(k.ErrorMessage);
}
void from_json(const json& j, DeviceRemoved& k) {
json jTemp;
j.at("DeviceRemoved").get_to(jTemp);
jTemp.at("Id").get_to(k.Id);
jTemp.at("DeviceIndex").get_to(k.DeviceIndex);
}
// The device conversion functions are slightly more complicated since they have some
// nested objects and arrays, but otherwise it is simply parsing, just a lot of it.
void from_json(const json& j, DeviceList& k) {
json jTemp;
j.at("DeviceList").get_to(jTemp);
jTemp.at("Id").get_to(k.Id);
if (jTemp["Devices"].size() > 0) {
for (auto& el : jTemp["Devices"].items()) {
Device tempD;
//std::cout << el.value() << std::endl;
auto test = el.value().contains("DeviceMessageTimingGap");
if (el.value().contains("DeviceName")) tempD.DeviceName = el.value()["DeviceName"];
if (el.value().contains("DeviceIndex")) tempD.DeviceIndex = el.value()["DeviceIndex"];
if (el.value().contains("DeviceMessageTimingGap")) tempD.DeviceMessageTimingGap = el.value()["DeviceMessageTimingGap"];
if (el.value().contains("DeviceDisplayName")) tempD.DeviceName = el.value()["DeviceDisplayName"];
if (el.value().contains("DeviceMessages")) {
json jTemp2;
jTemp2 = el.value()["DeviceMessages"];
for (auto& el2 : jTemp2.items()) {
DeviceCmd tempCmd;
tempCmd.CmdType = el2.key();
if (!el2.key().compare("StopDeviceCmd")) {
// Do something, not sure what yet
continue;
}
for (auto& el3 : el2.value().items()) {
DeviceCmdAttr tempAttr;
//std::cout << el3.value() << std::endl;
if (el3.value().contains("FeatureDescriptor")) tempAttr.FeatureDescriptor = el3.value()["FeatureDescriptor"];
if (el3.value().contains("StepCount")) tempAttr.StepCount = el3.value()["StepCount"];
if (el3.value().contains("ActuatorType")) tempAttr.ActuatorType = el3.value()["ActuatorType"];
if (el3.value().contains("SensorType")) tempAttr.SensorType = el3.value()["SensorType"];
if (el3.value().contains("SensorRange")) {
//std::cout << el3.value()["SensorRange"] << std::endl;
for (auto& el4 : el3.value()["SensorRange"].items()) {
tempAttr.SensorRange.push_back(el4.value()[0]);
tempAttr.SensorRange.push_back(el4.value()[1]);
}
//tempCmd.SensorRange.push_back(el2.value()["SensorRange"]);
}
//if (el2.value().contains("Endpoints")) tempCmd.Endpoints = el2.value()["Endpoints"];
//std::cout << el2.key() << std::endl;
//std::cout << el2.value() << std::endl;
tempCmd.DeviceCmdAttributes.push_back(tempAttr);
}
tempD.DeviceMessages.push_back(tempCmd);
}
}
k.Devices.push_back(tempD);
}
}
}
void from_json(const json& j, DeviceAdded& k) {
json jTemp;
j.at("DeviceAdded").get_to(jTemp);
jTemp.at("Id").get_to(k.Id);
Device tempD;
if (jTemp.contains("DeviceName")) k.device.DeviceName = jTemp["DeviceName"];
if (jTemp.contains("DeviceIndex")) k.device.DeviceIndex = jTemp["DeviceIndex"];
if (jTemp.contains("DeviceMessageTimingGap")) k.device.DeviceMessageTimingGap = jTemp["DeviceMessageTimingGap"];
if (jTemp.contains("DeviceDisplayName")) k.device.DeviceName = jTemp["DeviceDisplayName"];
if (jTemp.contains("DeviceMessages")) {
json jTemp2;
jTemp2 = jTemp["DeviceMessages"];
for (auto& el2 : jTemp2.items()) {
DeviceCmd tempCmd;
tempCmd.CmdType = el2.key();
if (!el2.key().compare("StopDeviceCmd")) {
// Do something, not sure what yet
continue;
}
for (auto& el3 : el2.value().items()) {
DeviceCmdAttr tempAttr;
//std::cout << el3.value() << std::endl;
if (el3.value().contains("FeatureDescriptor")) tempAttr.FeatureDescriptor = el3.value()["FeatureDescriptor"];
if (el3.value().contains("StepCount")) tempAttr.StepCount = el3.value()["StepCount"];
if (el3.value().contains("ActuatorType")) tempAttr.ActuatorType = el3.value()["ActuatorType"];
if (el3.value().contains("SensorType")) tempAttr.SensorType = el3.value()["SensorType"];
if (el3.value().contains("SensorRange")) {
//std::cout << el3.value()["SensorRange"] << std::endl;
for (auto& el4 : el3.value()["SensorRange"].items()) {
tempAttr.SensorRange.push_back(el4.value()[0]);
tempAttr.SensorRange.push_back(el4.value()[1]);
}
}
//if (el2.value().contains("Endpoints")) tempCmd.Endpoints = el2.value()["Endpoints"];
//std::cout << el2.key() << std::endl;
//std::cout << el2.value() << std::endl;
tempCmd.DeviceCmdAttributes.push_back(tempAttr);
}
k.device.DeviceMessages.push_back(tempCmd);
}
}
}
void from_json(const json& j, SensorReading& k) {
json jTemp;
j.at("SensorReading").get_to(jTemp);
jTemp.at("Id").get_to(k.Id);
jTemp.at("DeviceIndex").get_to(k.DeviceIndex);
jTemp.at("SensorIndex").get_to(k.SensorIndex);
jTemp.at("SensorType").get_to(k.SensorType);
for (auto& el : jTemp["Data"].items())
k.Data.push_back(el.value());
}
}