.
This commit is contained in:
@@ -10,6 +10,14 @@
|
||||
<param name="color/command" textfile="$(find hos_core_types)/schema/core/types/color/command.json"/>
|
||||
</group>
|
||||
|
||||
<group ns="/hos/types/repository/core/devices">
|
||||
<param name="switch/status" textfile="$(find hos_core_types)/schema/core/devices/switch/status.json"/>
|
||||
<param name="switch/command" textfile="$(find hos_core_types)/schema/core/devices/switch/command.json"/>
|
||||
|
||||
<param name="dimmer/status" textfile="$(find hos_core_types)/schema/core/devices/dimmer/status.json"/>
|
||||
<param name="dimmer/command" textfile="$(find hos_core_types)/schema/core/devices/dimmer/command.json"/>
|
||||
</group>
|
||||
|
||||
<group ns="/hos/types/repository/core/msgs">
|
||||
<param name="hosstatusupdate" textfile="$(find hos_core_types)/schema/core/msgs/hosstatusupdate.json"/>
|
||||
</group>
|
||||
|
||||
@@ -0,0 +1,19 @@
|
||||
{
|
||||
"$schema": "http://json-schema.org/draft-04/schema#",
|
||||
"title": "Dimmer Command",
|
||||
"description": "",
|
||||
"version": "1.0.0",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"type": {
|
||||
"description": "",
|
||||
"type": "string",
|
||||
"pattern": "core/devices/switch/command"
|
||||
},
|
||||
"dimmer": {
|
||||
"$ref": "hos:schema://core/types/percentage/command"
|
||||
}
|
||||
},
|
||||
"additionalProperties": false,
|
||||
"required": ["dimmer"]
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
{
|
||||
"$schema": "http://json-schema.org/draft-04/schema#",
|
||||
"title": "Dimmer Status",
|
||||
"description": "",
|
||||
"version": "1.0.0",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"type": {
|
||||
"description": "",
|
||||
"type": "string",
|
||||
"pattern": "core/devices/switch/status"
|
||||
},
|
||||
"dimmer": {
|
||||
"$ref": "hos:schema://core/types/percentage/status"
|
||||
}
|
||||
},
|
||||
"additionalProperties": false,
|
||||
"required": ["dimmer"]
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
{
|
||||
"$schema": "http://json-schema.org/draft-04/schema#",
|
||||
"title": "Switch Command",
|
||||
"description": "",
|
||||
"version": "1.0.0",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"type": {
|
||||
"description": "",
|
||||
"type": "string",
|
||||
"pattern": "core/devices/switch/command"
|
||||
},
|
||||
"switch": {
|
||||
"$ref": "hos:schema://core/types/boolean/command"
|
||||
}
|
||||
},
|
||||
"additionalProperties": false,
|
||||
"required": ["switch"]
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
{
|
||||
"$schema": "http://json-schema.org/draft-04/schema#",
|
||||
"title": "Switch Status",
|
||||
"description": "",
|
||||
"version": "1.0.0",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"type": {
|
||||
"description": "",
|
||||
"type": "string",
|
||||
"pattern": "core/devices/switch/status"
|
||||
},
|
||||
"switch": {
|
||||
"$ref": "hos:schema://core/types/boolean/status"
|
||||
}
|
||||
},
|
||||
"additionalProperties": false,
|
||||
"required": ["switch"]
|
||||
}
|
||||
@@ -22,7 +22,7 @@
|
||||
},
|
||||
"additionalProperties": false,
|
||||
"anyOf": [
|
||||
{ "required": [ "type", "set" ] },
|
||||
{ "required": [ "type", "command" ] }
|
||||
{ "required": [ "set" ] },
|
||||
{ "required": [ "command" ] }
|
||||
]
|
||||
}
|
||||
@@ -16,5 +16,5 @@
|
||||
}
|
||||
},
|
||||
"additionalProperties": false,
|
||||
"required": ["type", "value"]
|
||||
"required": ["value"]
|
||||
}
|
||||
@@ -25,8 +25,8 @@
|
||||
},
|
||||
"additionalProperties": false,
|
||||
"anyOf": [
|
||||
{ "required": [ "type", "set" ] },
|
||||
{ "required": [ "type", "add" ] },
|
||||
{ "required": [ "type", "sub" ] }
|
||||
{ "required": [ "set" ] },
|
||||
{ "required": [ "add" ] },
|
||||
{ "required": [ "sub" ] }
|
||||
]
|
||||
}
|
||||
@@ -16,5 +16,5 @@
|
||||
}
|
||||
},
|
||||
"additionalProperties": false,
|
||||
"required": ["type", "value"]
|
||||
"required": ["value"]
|
||||
}
|
||||
+3
@@ -6,6 +6,7 @@
|
||||
#include <hos/cosgi/service/interface.h>
|
||||
#include <Variant/Variant.h>
|
||||
#include <string>
|
||||
#include <set>
|
||||
#include <vector>
|
||||
#include <memory>
|
||||
|
||||
@@ -100,6 +101,8 @@ public:
|
||||
|
||||
virtual std::shared_ptr<Device> getDevice(std::string device_id) = 0;
|
||||
virtual size_t getDevices(std::vector<std::shared_ptr<Device>>& devices) = 0;
|
||||
virtual size_t deviceCount() = 0;
|
||||
virtual std::set<std::string> deviceIDs() = 0;
|
||||
};
|
||||
|
||||
|
||||
|
||||
+14
@@ -167,6 +167,20 @@ size_t DeviceRepositoryServiceImpl::getDevices(std::vector<std::shared_ptr<Devic
|
||||
}
|
||||
|
||||
|
||||
size_t DeviceRepositoryServiceImpl::deviceCount() {
|
||||
return devices.size();
|
||||
}
|
||||
|
||||
|
||||
std::set<std::string> DeviceRepositoryServiceImpl::deviceIDs() {
|
||||
std::set<std::string> retval;
|
||||
for (auto d : devices) {
|
||||
retval.insert(d.first);
|
||||
}
|
||||
return retval;
|
||||
}
|
||||
|
||||
|
||||
void DeviceRepositoryServiceImpl::statusMsgCallback(const hos_core_msgs::DeviceStatusUpdate::ConstPtr& msg) {
|
||||
std::lock_guard<std::recursive_mutex> lock(serviceMutex);
|
||||
std::cout << "HOSDeviceRepositoryServiceImpl::statusMsgCallback" << std::endl;
|
||||
|
||||
+2
@@ -127,6 +127,8 @@ public:
|
||||
|
||||
virtual std::shared_ptr<Device> getDevice(std::string device_id) override;
|
||||
virtual size_t getDevices(std::vector<std::shared_ptr<Device>>& devices) override;
|
||||
virtual size_t deviceCount() override;
|
||||
virtual std::set<std::string> deviceIDs() override;
|
||||
|
||||
/* Message Callbacks */
|
||||
|
||||
|
||||
+21
-7
@@ -262,7 +262,7 @@ void DeviceStatusMsgCondition::notificationReceived(interface::Observer<devicere
|
||||
if (msgPointer.empty()) {
|
||||
value = e2->statusMsg;
|
||||
} else if (e2->statusMsg.HasPath(msgPointer)) {
|
||||
value = e2->statusMsg.Get(msgPointer);
|
||||
value = e2->statusMsg.GetPath(msgPointer);
|
||||
} else {
|
||||
notify = false;
|
||||
}
|
||||
@@ -321,7 +321,7 @@ void DeviceCommandMsgCondition::notificationReceived(interface::Observer<devicer
|
||||
if (msgPointer.empty()) {
|
||||
value = e2->cmdMsg;
|
||||
} else if (e2->cmdMsg.HasPath(msgPointer)) {
|
||||
value = e2->cmdMsg.Get(msgPointer);
|
||||
value = e2->cmdMsg.GetPath(msgPointer);
|
||||
} else {
|
||||
notify = false;
|
||||
}
|
||||
@@ -362,7 +362,15 @@ std::shared_ptr<rule::RuleCondition> DeviceStateChangeConditionFactory::createCo
|
||||
throw std::runtime_error("Malformed JSON: property msgpointer is not an string.");
|
||||
}
|
||||
}
|
||||
retval = std::make_shared<DeviceStateChangeCondition>(parent, deviceID, statePointer);
|
||||
Variant fromValue;
|
||||
if (raw.HasPath("fromvalue")) {
|
||||
fromValue = raw["fromvalue"];
|
||||
}
|
||||
Variant toValue;
|
||||
if (raw.HasPath("tovalue")) {
|
||||
toValue = raw["tovalue"];
|
||||
}
|
||||
retval = std::make_shared<DeviceStateChangeCondition>(parent, deviceID, statePointer, fromValue, toValue);
|
||||
return retval;
|
||||
}
|
||||
|
||||
@@ -378,13 +386,19 @@ void DeviceStateChangeCondition::notificationReceived(interface::Observer<device
|
||||
current = device->getCurrentState();
|
||||
last = device->getLastState();
|
||||
} else if (device->getCurrentState().HasPath(msgPointer) && device->getLastState().HasPath(msgPointer)) {
|
||||
current = device->getCurrentState().Get(msgPointer);
|
||||
last = device->getLastState().Get(msgPointer);
|
||||
current = device->getCurrentState().GetPath(msgPointer);
|
||||
last = device->getLastState().GetPath(msgPointer);
|
||||
} else {
|
||||
notify = false;
|
||||
}
|
||||
if (notify && current == last) {
|
||||
notify = false;
|
||||
if (notify) {
|
||||
if (current == last) {
|
||||
notify = false;
|
||||
} else if (!fromValue.IsNull() && fromValue != last) {
|
||||
notify = false;
|
||||
} else if (!msgValue.IsNull() && msgValue != current) {
|
||||
notify = false;
|
||||
}
|
||||
}
|
||||
if (notify) {
|
||||
Variant lcontext;
|
||||
|
||||
@@ -115,9 +115,11 @@ public:
|
||||
|
||||
|
||||
class DeviceStateChangeCondition : public DeviceMsgCondition {
|
||||
protected:
|
||||
const Variant fromValue;
|
||||
public:
|
||||
DeviceStateChangeCondition(Rule* parent, const std::string deviceID, const std::string statePointer) :
|
||||
DeviceMsgCondition(parent, Category::Event, "devicestatechange", deviceID, statePointer, Variant()) {}
|
||||
DeviceStateChangeCondition(Rule* parent, const std::string deviceID, const std::string statePointer, const Variant fromValue, const Variant toValue) :
|
||||
DeviceMsgCondition(parent, Category::Event, "devicestatechange", deviceID, statePointer, toValue), fromValue(fromValue) {}
|
||||
|
||||
virtual void notificationReceived(interface::Observer<devicerepository::DeviceEvent>::observable_type* o, const devicerepository::DeviceEvent* e) override;
|
||||
};
|
||||
|
||||
@@ -9,31 +9,19 @@
|
||||
"conditions" : [
|
||||
{
|
||||
"type": "devicestatusmsg",
|
||||
"deviceid": "huelight3"
|
||||
},
|
||||
{
|
||||
"type": "devicestatechange",
|
||||
"deviceid": "huelight4"
|
||||
"deviceid": "dummySwitch0",
|
||||
"msgpointer": "/switch/value",
|
||||
"msgvalue": true
|
||||
}
|
||||
]
|
||||
},
|
||||
"script": { "code": "global var2\nprint \"Hello World1: \" + str(var2)\nvar2 = var2 + 1\nimport __main__\nprint \"__main__.__dict__: \" + str(__main__.__dict__)\nprint \"test: \" + event_type\ndev1 = Devices.getDevice(\"huelight1\")\nprint \"device: \" + dev1.deviceID()" },
|
||||
"script": { "code": "global var2\nprint \"Hello World1: \" + str(var2)\nvar2 = var2 + 1\nimport __main__\nprint \"__main__.__dict__: \" + str(__main__.__dict__)\nprint \"event_type: \" + event_type\nprint \"devices: \" + str(Devices.keys())\nprint \"DeviceCount: \" + str(len(Devices))\nprint \"test: \" + str(Devices[\"dummySwitch1\"])" },
|
||||
"exitscript": { "code": "print \"Hello from exitscript1\"" }
|
||||
},
|
||||
"rule02": {
|
||||
"condition": {
|
||||
"type": "logical_or",
|
||||
"$schema": "hos:schema://core/configs/rulepackage#/definitions/LogicalOrCondition",
|
||||
"conditions" : [
|
||||
{
|
||||
"type": "devicecommandmsg",
|
||||
"deviceid": "huelight4"
|
||||
},
|
||||
{
|
||||
"type": "devicestatechange",
|
||||
"deviceid": "huelight3"
|
||||
}
|
||||
]
|
||||
"type": "devicestatechange",
|
||||
"deviceid": "dummySwitch0"
|
||||
},
|
||||
"script": { "code": "print \"Hello World2: \" + str(var2)\nvar2 = var2 + 1\nimport __main__\nprint \"__main__.__dict__: \" + str(__main__.__dict__)\nprint \"test: \" + event_type" },
|
||||
"exitscript": { "code": "print \"Hello from exitscript2\"" }
|
||||
@@ -45,16 +33,42 @@
|
||||
"conditions" : [
|
||||
{
|
||||
"type": "devicecommandmsg",
|
||||
"deviceid": "huelight1"
|
||||
},
|
||||
{
|
||||
"type": "devicestatechange",
|
||||
"deviceid": "huelight2"
|
||||
"deviceid": "dummySwitch0"
|
||||
}
|
||||
]
|
||||
},
|
||||
"script": { "code": "print \"Hello World3: \" + str(var2)\nvar2 = var2 + 1\nimport __main__\nprint \"__main__.__dict__: \" + str(__main__.__dict__)\nprint \"test: \" + event_type" },
|
||||
"exitscript": { "code": "print \"Hello from exitscript2\"" }
|
||||
},
|
||||
"rule04": {
|
||||
"condition": {
|
||||
"type": "logical_or",
|
||||
"$schema": "hos:schema://core/configs/rulepackage#/definitions/LogicalOrCondition",
|
||||
"conditions" : [
|
||||
{
|
||||
"type": "devicestatechange",
|
||||
"deviceid": "dummyDimmer0",
|
||||
"msgpointer": "/dimmer/value",
|
||||
"tovalue": 1.0
|
||||
}
|
||||
]
|
||||
},
|
||||
"script": { "code": "print \"Dimmer 0 reached 100\"" }
|
||||
},
|
||||
"rule05": {
|
||||
"condition": {
|
||||
"type": "logical_or",
|
||||
"$schema": "hos:schema://core/configs/rulepackage#/definitions/LogicalOrCondition",
|
||||
"conditions" : [
|
||||
{
|
||||
"type": "devicestatechange",
|
||||
"deviceid": "dummyDimmer0",
|
||||
"msgpointer": "/dimmer",
|
||||
"fromvalue": { "value": 1.0 }
|
||||
}
|
||||
]
|
||||
},
|
||||
"script": { "code": "print \"Dimmer 0 left 100\"" }
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -123,6 +123,7 @@ bundle(hos_cosgi_scripting_python
|
||||
SOURCES
|
||||
${PROJECT_SOURCE_DIR}/src/bundle_activator
|
||||
${PROJECT_SOURCE_DIR}/src/hos/cosgi/service/scripting/python/scripting_serviceimpl
|
||||
${PROJECT_SOURCE_DIR}/src/hos/cosgi/service/scripting/python/PyHOSAPI
|
||||
)
|
||||
target_link_libraries(hos_cosgi_scripting_python
|
||||
${catkin_LIBRARIES}
|
||||
|
||||
@@ -0,0 +1,72 @@
|
||||
/*
|
||||
* PyHOSAPI.cpp
|
||||
*
|
||||
* Created on: 19.05.2015
|
||||
* Author: matzman
|
||||
*/
|
||||
|
||||
|
||||
|
||||
#include "PyHOSAPI.h"
|
||||
#include <ros/ros.h>
|
||||
|
||||
|
||||
namespace hos {
|
||||
namespace cosgi {
|
||||
namespace service {
|
||||
namespace scripting {
|
||||
namespace python {
|
||||
|
||||
|
||||
BOOST_PYTHON_MODULE(hos)
|
||||
{
|
||||
using namespace boost::python;
|
||||
|
||||
class_<PyDeviceWrapper>("Device", no_init)
|
||||
.def("deviceID", &PyDeviceWrapper::deviceID) ;
|
||||
|
||||
class_<PyDeviceRepositoryWrapper>("DeviceRepository", no_init)
|
||||
.def("getDevice", &PyDeviceRepositoryWrapper::getDevice)
|
||||
.def("__getitem__", &PyDeviceRepositoryWrapper::getDevice)
|
||||
.def("__len__", &PyDeviceRepositoryWrapper::deviceCount)
|
||||
.def("keys", &PyDeviceRepositoryWrapper::deviceIDs) ;
|
||||
}
|
||||
|
||||
boost::python::object convertVariantToBoostPython(Variant var) {
|
||||
if (var.IsBool()) {
|
||||
return boost::python::object(var.AsBool());
|
||||
} else if (var.IsFloat()) {
|
||||
return boost::python::object(var.AsDouble());
|
||||
} else if (var.IsInt()) {
|
||||
return boost::python::object(var.AsInt());
|
||||
} else if (var.IsString()) {
|
||||
return boost::python::str(var.AsString());
|
||||
} else if (var.IsUnsigned()) {
|
||||
return boost::python::object(var.AsUnsigned());
|
||||
} else if (var.IsList()) {
|
||||
boost::python::list list;
|
||||
for (auto e : var.AsList()) {
|
||||
list.append(convertVariantToBoostPython(e));
|
||||
}
|
||||
return list;
|
||||
} else if (var.IsMap()) {
|
||||
boost::python::dict map;
|
||||
for (auto e : var.AsMap()) {
|
||||
map[e.first] = convertVariantToBoostPython(e.second);
|
||||
}
|
||||
return map;
|
||||
} else {
|
||||
ROS_ERROR("Unknown Variant type encountered while converting to python");
|
||||
return boost::python::object();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
} // namespace python
|
||||
} // namespace scripting
|
||||
} // namespace service
|
||||
} // namespace cosgi
|
||||
} // namespace hos
|
||||
|
||||
|
||||
@@ -0,0 +1,71 @@
|
||||
/*
|
||||
* PyHOSAPI.h
|
||||
*
|
||||
* Created on: 19.05.2015
|
||||
* Author: matzman
|
||||
*/
|
||||
|
||||
#ifndef SRC_HOS_COSGI_SERVICE_SCRIPTING_PYTHON_PYHOSAPI_H_
|
||||
#define SRC_HOS_COSGI_SERVICE_SCRIPTING_PYTHON_PYHOSAPI_H_
|
||||
|
||||
#include <boost/python.hpp>
|
||||
#include <hos/cosgi/service/scripting/scripting_service.h>
|
||||
#include <hos/cosgi/service/devicerepository/devicerepository_service.h>
|
||||
|
||||
|
||||
namespace hos {
|
||||
namespace cosgi {
|
||||
namespace service {
|
||||
namespace scripting {
|
||||
namespace python {
|
||||
|
||||
class PyScriptingService;
|
||||
|
||||
|
||||
boost::python::object convertVariantToBoostPython(Variant var);
|
||||
|
||||
class PyDeviceWrapper {
|
||||
private:
|
||||
devicerepository::Device* device;
|
||||
public:
|
||||
PyDeviceWrapper(devicerepository::Device* device) : device(device) {}
|
||||
|
||||
std::string deviceID() { return device->getDeviceID(); }
|
||||
};
|
||||
|
||||
|
||||
class PyDeviceRepositoryWrapper {
|
||||
private:
|
||||
devicerepository::DeviceRepositoryService* service;
|
||||
public:
|
||||
PyDeviceRepositoryWrapper(devicerepository::DeviceRepositoryService* service) : service(service) {}
|
||||
|
||||
PyDeviceWrapper getDevice(std::string name) {
|
||||
return PyDeviceWrapper(service->getDevice(name).get());
|
||||
}
|
||||
|
||||
size_t deviceCount() {
|
||||
return service->deviceCount();
|
||||
}
|
||||
|
||||
boost::python::list deviceIDs() {
|
||||
boost::python::list retval;
|
||||
for (auto d : service->deviceIDs()) {
|
||||
retval.append(d);
|
||||
}
|
||||
return retval;
|
||||
}
|
||||
};
|
||||
|
||||
extern "C" void inithos();
|
||||
|
||||
|
||||
} // namespace python
|
||||
} // namespace scripting
|
||||
} // namespace service
|
||||
} // namespace cosgi
|
||||
} // namespace hos
|
||||
|
||||
|
||||
|
||||
#endif /* SRC_HOS_COSGI_SERVICE_SCRIPTING_PYTHON_PYHOSAPI_H_ */
|
||||
+1
-63
@@ -6,6 +6,7 @@
|
||||
*/
|
||||
|
||||
#include "scripting_serviceimpl.h"
|
||||
#include "PyHOSAPI.h"
|
||||
|
||||
#include <hos/cosgi/service/core/core_service.h>
|
||||
#include <hos/cosgi/service/devicerepository/devicerepository_service.h>
|
||||
@@ -81,39 +82,6 @@ std::shared_ptr<service::scripting::Script> PyScriptingService::createScript(ser
|
||||
}
|
||||
|
||||
|
||||
class PyDeviceWrapper {
|
||||
private:
|
||||
devicerepository::Device* device;
|
||||
public:
|
||||
PyDeviceWrapper(devicerepository::Device* device) : device(device) {}
|
||||
|
||||
std::string deviceID() { return device->getDeviceID(); }
|
||||
};
|
||||
|
||||
|
||||
class PyDeviceRepositoryWrapper {
|
||||
private:
|
||||
devicerepository::DeviceRepositoryService* service;
|
||||
public:
|
||||
PyDeviceRepositoryWrapper(devicerepository::DeviceRepositoryService* service) : service(service) {}
|
||||
|
||||
PyDeviceWrapper getDevice(std::string name) {
|
||||
return PyDeviceWrapper(service->getDevice(name).get());
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
BOOST_PYTHON_MODULE(hos)
|
||||
{
|
||||
using namespace boost::python;
|
||||
|
||||
class_<PyDeviceWrapper>("Device", no_init)
|
||||
.def("deviceID", &PyDeviceWrapper::deviceID) ;
|
||||
|
||||
class_<PyDeviceRepositoryWrapper>("DeviceRepository", no_init)
|
||||
.def("getDevice", &PyDeviceRepositoryWrapper::getDevice) ;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void PyScript::exec(service::scripting::GlobalScriptContext* gContext, Variant lContext) {
|
||||
@@ -141,36 +109,6 @@ void PyScript::exec(service::scripting::GlobalScriptContext* gContext, Variant l
|
||||
}
|
||||
|
||||
|
||||
boost::python::object convertVariantToBoostPython(Variant var) {
|
||||
if (var.IsBool()) {
|
||||
return boost::python::object(var.AsBool());
|
||||
} else if (var.IsFloat()) {
|
||||
return boost::python::object(var.AsDouble());
|
||||
} else if (var.IsInt()) {
|
||||
return boost::python::object(var.AsInt());
|
||||
} else if (var.IsString()) {
|
||||
return boost::python::str(var.AsString());
|
||||
} else if (var.IsUnsigned()) {
|
||||
return boost::python::object(var.AsUnsigned());
|
||||
} else if (var.IsList()) {
|
||||
boost::python::list list;
|
||||
for (auto e : var.AsList()) {
|
||||
list.append(convertVariantToBoostPython(e));
|
||||
}
|
||||
return list;
|
||||
} else if (var.IsMap()) {
|
||||
boost::python::dict map;
|
||||
for (auto e : var.AsMap()) {
|
||||
map[e.first] = convertVariantToBoostPython(e.second);
|
||||
}
|
||||
return map;
|
||||
} else {
|
||||
ROS_ERROR("Unknown Variant type encountered while converting to python");
|
||||
return boost::python::object();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
} // namespace python
|
||||
} // namespace ruleengine
|
||||
|
||||
-1
@@ -99,7 +99,6 @@ public:
|
||||
};
|
||||
|
||||
|
||||
boost::python::object convertVariantToBoostPython(Variant var);
|
||||
|
||||
|
||||
} // namespace python
|
||||
|
||||
@@ -0,0 +1,169 @@
|
||||
cmake_minimum_required(VERSION 2.8.3)
|
||||
project(hos_dummy)
|
||||
|
||||
## Find catkin macros and libraries
|
||||
## if COMPONENTS list like find_package(catkin REQUIRED COMPONENTS xyz)
|
||||
## is used, also find other catkin packages
|
||||
find_package(catkin REQUIRED COMPONENTS
|
||||
hos_core_msgs
|
||||
hos_python_json
|
||||
rospy
|
||||
)
|
||||
|
||||
## System dependencies are found with CMake's conventions
|
||||
# find_package(Boost REQUIRED COMPONENTS system)
|
||||
|
||||
|
||||
## Uncomment this if the package has a setup.py. This macro ensures
|
||||
## modules and global scripts declared therein get installed
|
||||
## See http://ros.org/doc/api/catkin/html/user_guide/setup_dot_py.html
|
||||
catkin_python_setup()
|
||||
|
||||
################################################
|
||||
## Declare ROS messages, services and actions ##
|
||||
################################################
|
||||
|
||||
## To declare and build messages, services or actions from within this
|
||||
## package, follow these steps:
|
||||
## * Let MSG_DEP_SET be the set of packages whose message types you use in
|
||||
## your messages/services/actions (e.g. std_msgs, actionlib_msgs, ...).
|
||||
## * In the file package.xml:
|
||||
## * add a build_depend and a run_depend tag for each package in MSG_DEP_SET
|
||||
## * If MSG_DEP_SET isn't empty the following dependencies might have been
|
||||
## pulled in transitively but can be declared for certainty nonetheless:
|
||||
## * add a build_depend tag for "message_generation"
|
||||
## * add a run_depend tag for "message_runtime"
|
||||
## * In this file (CMakeLists.txt):
|
||||
## * add "message_generation" and every package in MSG_DEP_SET to
|
||||
## find_package(catkin REQUIRED COMPONENTS ...)
|
||||
## * add "message_runtime" and every package in MSG_DEP_SET to
|
||||
## catkin_package(CATKIN_DEPENDS ...)
|
||||
## * uncomment the add_*_files sections below as needed
|
||||
## and list every .msg/.srv/.action file to be processed
|
||||
## * uncomment the generate_messages entry below
|
||||
## * add every package in MSG_DEP_SET to generate_messages(DEPENDENCIES ...)
|
||||
|
||||
## Generate messages in the 'msg' folder
|
||||
# add_message_files(
|
||||
# FILES
|
||||
# Message1.msg
|
||||
# Message2.msg
|
||||
# )
|
||||
|
||||
## Generate services in the 'srv' folder
|
||||
# add_service_files(
|
||||
# FILES
|
||||
# Service1.srv
|
||||
# Service2.srv
|
||||
# )
|
||||
|
||||
## Generate actions in the 'action' folder
|
||||
# add_action_files(
|
||||
# FILES
|
||||
# Action1.action
|
||||
# Action2.action
|
||||
# )
|
||||
|
||||
## Generate added messages and services with any dependencies listed here
|
||||
# generate_messages(
|
||||
# DEPENDENCIES
|
||||
# hos_core_msgs
|
||||
# )
|
||||
|
||||
###################################
|
||||
## catkin specific configuration ##
|
||||
###################################
|
||||
## The catkin_package macro generates cmake config files for your package
|
||||
## Declare things to be passed to dependent projects
|
||||
## INCLUDE_DIRS: uncomment this if you package contains header files
|
||||
## LIBRARIES: libraries you create in this project that dependent projects also need
|
||||
## CATKIN_DEPENDS: catkin_packages dependent projects also need
|
||||
## DEPENDS: system dependencies of this project that dependent projects also need
|
||||
catkin_package(
|
||||
# INCLUDE_DIRS include
|
||||
# LIBRARIES hos_dummy
|
||||
CATKIN_DEPENDS hos_core_msgs hos_python_json rospy
|
||||
# DEPENDS system_lib
|
||||
)
|
||||
|
||||
###########
|
||||
## Build ##
|
||||
###########
|
||||
|
||||
## Specify additional locations of header files
|
||||
## Your package locations should be listed before other locations
|
||||
# include_directories(include)
|
||||
include_directories(
|
||||
${catkin_INCLUDE_DIRS}
|
||||
)
|
||||
|
||||
## Declare a cpp library
|
||||
# add_library(hos_dummy
|
||||
# src/${PROJECT_NAME}/hos_dummy.cpp
|
||||
# )
|
||||
|
||||
## Declare a cpp executable
|
||||
# add_executable(hos_dummy_node src/hos_dummy_node.cpp)
|
||||
|
||||
## Add cmake target dependencies of the executable/library
|
||||
## as an example, message headers may need to be generated before nodes
|
||||
# add_dependencies(hos_dummy_node hos_dummy_generate_messages_cpp)
|
||||
|
||||
## Specify libraries to link a library or executable target against
|
||||
# target_link_libraries(hos_dummy_node
|
||||
# ${catkin_LIBRARIES}
|
||||
# )
|
||||
|
||||
#############
|
||||
## Install ##
|
||||
#############
|
||||
|
||||
|
||||
#And this will install python nodes
|
||||
catkin_install_python(PROGRAMS
|
||||
nodes/hos_dummy_devices.py
|
||||
DESTINATION ${CATKIN_PACKAGE_BIN_DESTINATION})
|
||||
|
||||
# all install targets should use catkin DESTINATION variables
|
||||
# See http://ros.org/doc/api/catkin/html/adv_user_guide/variables.html
|
||||
|
||||
## Mark executable scripts (Python etc.) for installation
|
||||
## in contrast to setup.py, you can choose the destination
|
||||
# install(PROGRAMS
|
||||
# scripts/my_python_script
|
||||
# DESTINATION ${CATKIN_PACKAGE_BIN_DESTINATION}
|
||||
# )
|
||||
|
||||
## Mark executables and/or libraries for installation
|
||||
# install(TARGETS hos_dummy hos_dummy_node
|
||||
# ARCHIVE DESTINATION ${CATKIN_PACKAGE_LIB_DESTINATION}
|
||||
# LIBRARY DESTINATION ${CATKIN_PACKAGE_LIB_DESTINATION}
|
||||
# RUNTIME DESTINATION ${CATKIN_PACKAGE_BIN_DESTINATION}
|
||||
# )
|
||||
|
||||
## Mark cpp header files for installation
|
||||
# install(DIRECTORY include/${PROJECT_NAME}/
|
||||
# DESTINATION ${CATKIN_PACKAGE_INCLUDE_DESTINATION}
|
||||
# FILES_MATCHING PATTERN "*.h"
|
||||
# PATTERN ".svn" EXCLUDE
|
||||
# )
|
||||
|
||||
## Mark other files for installation (e.g. launch and bag files, etc.)
|
||||
# install(FILES
|
||||
# # myfile1
|
||||
# # myfile2
|
||||
# DESTINATION ${CATKIN_PACKAGE_SHARE_DESTINATION}
|
||||
# )
|
||||
|
||||
#############
|
||||
## Testing ##
|
||||
#############
|
||||
|
||||
## Add gtest based cpp test target and link libraries
|
||||
# catkin_add_gtest(${PROJECT_NAME}-test test/test_hos_dummy.cpp)
|
||||
# if(TARGET ${PROJECT_NAME}-test)
|
||||
# target_link_libraries(${PROJECT_NAME}-test ${PROJECT_NAME})
|
||||
# endif()
|
||||
|
||||
## Add folders to be run by python nosetests
|
||||
# catkin_add_nosetests(test)
|
||||
Executable
+28
@@ -0,0 +1,28 @@
|
||||
#!/usr/bin/env python
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
import sys
|
||||
import socket
|
||||
import rospy
|
||||
import traceback
|
||||
from hos_core_msgs.msg import DeviceCommand
|
||||
from hos_dummy.HosDummyController import HosDummyController
|
||||
|
||||
import Tkinter as tk
|
||||
import Tkconstants
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
try:
|
||||
root = tk.Tk();
|
||||
app = HosDummyController(root)
|
||||
root.geometry("+200+200")
|
||||
app.master.title('HOS Dummy Controller')
|
||||
|
||||
app.mainloop()
|
||||
except socket.error as e:
|
||||
print "Could not connect to master"
|
||||
except Exception as inst:
|
||||
print type(inst) # the exception instance
|
||||
print inst # __str__ allows args to be printed directly
|
||||
traceback.print_exc()
|
||||
Executable
+33
@@ -0,0 +1,33 @@
|
||||
#!/usr/bin/env python
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
import sys
|
||||
import socket
|
||||
import rospy
|
||||
import traceback
|
||||
from hos_core_msgs.msg import DeviceCommand
|
||||
from hos_dummy.HosDummyDevices import HosDummyDevices
|
||||
|
||||
import Tkinter as tk
|
||||
import Tkconstants
|
||||
|
||||
|
||||
def deviceCmdCallback(data):
|
||||
app.deviceCmdCallback(data)
|
||||
|
||||
if __name__ == '__main__':
|
||||
try:
|
||||
root = tk.Tk();
|
||||
app = HosDummyDevices(root)
|
||||
root.geometry("+200+200")
|
||||
app.master.title('HOS Dummy Devices')
|
||||
|
||||
rospy.Subscriber(app.cmd_topic, DeviceCommand, deviceCmdCallback)
|
||||
|
||||
app.mainloop()
|
||||
except socket.error as e:
|
||||
print "Could not connect to master"
|
||||
except Exception as inst:
|
||||
print type(inst) # the exception instance
|
||||
print inst # __str__ allows args to be printed directly
|
||||
traceback.print_exc()
|
||||
@@ -0,0 +1,56 @@
|
||||
<?xml version="1.0"?>
|
||||
<package>
|
||||
<name>hos_dummy</name>
|
||||
<version>0.0.0</version>
|
||||
<description>The hos_dummy package</description>
|
||||
|
||||
<!-- One maintainer tag required, multiple allowed, one person per tag -->
|
||||
<!-- Example: -->
|
||||
<!-- <maintainer email="jane.doe@example.com">Jane Doe</maintainer> -->
|
||||
<maintainer email="matzman@todo.todo">matzman</maintainer>
|
||||
|
||||
|
||||
<!-- One license tag required, multiple allowed, one license per tag -->
|
||||
<!-- Commonly used license strings: -->
|
||||
<!-- BSD, MIT, Boost Software License, GPLv2, GPLv3, LGPLv2.1, LGPLv3 -->
|
||||
<license>TODO</license>
|
||||
|
||||
|
||||
<!-- Url tags are optional, but mutiple are allowed, one per tag -->
|
||||
<!-- Optional attribute type can be: website, bugtracker, or repository -->
|
||||
<!-- Example: -->
|
||||
<!-- <url type="website">http://wiki.ros.org/hos_dummy</url> -->
|
||||
|
||||
|
||||
<!-- Author tags are optional, mutiple are allowed, one per tag -->
|
||||
<!-- Authors do not have to be maintianers, but could be -->
|
||||
<!-- Example: -->
|
||||
<!-- <author email="jane.doe@example.com">Jane Doe</author> -->
|
||||
|
||||
|
||||
<!-- The *_depend tags are used to specify dependencies -->
|
||||
<!-- Dependencies can be catkin packages or system dependencies -->
|
||||
<!-- Examples: -->
|
||||
<!-- Use build_depend for packages you need at compile time: -->
|
||||
<!-- <build_depend>message_generation</build_depend> -->
|
||||
<!-- Use buildtool_depend for build tool packages: -->
|
||||
<!-- <buildtool_depend>catkin</buildtool_depend> -->
|
||||
<!-- Use run_depend for packages you need at runtime: -->
|
||||
<!-- <run_depend>message_runtime</run_depend> -->
|
||||
<!-- Use test_depend for packages you need only for testing: -->
|
||||
<!-- <test_depend>gtest</test_depend> -->
|
||||
<buildtool_depend>catkin</buildtool_depend>
|
||||
<build_depend>hos_core_msgs</build_depend>
|
||||
<build_depend>hos_python_json</build_depend>
|
||||
<build_depend>rospy</build_depend>
|
||||
<run_depend>hos_core_msgs</run_depend>
|
||||
<run_depend>hos_python_json</run_depend>
|
||||
<run_depend>rospy</run_depend>
|
||||
|
||||
|
||||
<!-- The export tag contains other, unspecified, tags -->
|
||||
<export>
|
||||
<!-- Other tools can request additional information be placed here -->
|
||||
|
||||
</export>
|
||||
</package>
|
||||
@@ -0,0 +1,144 @@
|
||||
#!/usr/bin/env python
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
import sys
|
||||
import rospy
|
||||
import json
|
||||
from hos_pyhue import pyhue
|
||||
from hos_core_msgs.msg import DeviceCommand
|
||||
from hos_core_msgs.msg import DeviceStatusUpdate
|
||||
from hos_core_msgs.msg import HosStatusUpdate
|
||||
from jsonspec_hos.reference.providers import HOSParamServerProvider
|
||||
from jsonspec.validators import load
|
||||
from time import sleep
|
||||
|
||||
import Tkinter as tk
|
||||
import Tkconstants
|
||||
|
||||
|
||||
class HosDummyController(tk.Frame):
|
||||
def __init__(self, master=None):
|
||||
# Init ROS node
|
||||
rospy.init_node('hos_dummy_controller', argv=sys.argv)
|
||||
# Get ROS parameter
|
||||
self.status_topic = rospy.get_param('~status_topic', "/hos/devices/status")
|
||||
self.cmd_topic = rospy.get_param('~cmd_topic', "/hos/devices/cmd")
|
||||
self.hos_update_topic = rospy.get_param('~hos_update_topic', "/hos/status/updates")
|
||||
self.loop_frequency = rospy.get_param('~loop_frequency', 100)
|
||||
self.statusmsg_interval = rospy.get_param('~statusmsg_interval', 6000000)
|
||||
# Init Variables
|
||||
self.msg_sequence = 0
|
||||
# Init devices
|
||||
self.switches = dict()
|
||||
self.dimmers = dict()
|
||||
for i in range(4):
|
||||
# switches
|
||||
name = "dummySwitch" + str(i)
|
||||
self.switches[i] = dict()
|
||||
self.switches[i]["value"] = False
|
||||
self.switches[i]["id"] = name
|
||||
self.switches[i]["name"] = "Switch " + str(i)
|
||||
key_base = "/hos/devices/repository/" + name
|
||||
rospy.set_param(key_base + "/type", "core/devices/switch")
|
||||
rospy.set_param(key_base + "/status_topic", self.status_topic)
|
||||
rospy.set_param(key_base + "/cmd_topic", self.cmd_topic)
|
||||
print "Added dummy switch \"" + name + "\""
|
||||
# dimmers
|
||||
name = "dummyDimmer" + str(i)
|
||||
self.dimmers[i] = dict()
|
||||
self.dimmers[i]["value"] = 0.0
|
||||
self.dimmers[i]["id"] = name
|
||||
self.dimmers[i]["name"] = "Dimmer " + str(i)
|
||||
key_base = "/hos/devices/repository/" + name
|
||||
rospy.set_param(key_base + "/type", "core/devices/switch")
|
||||
rospy.set_param(key_base + "/status_topic", self.status_topic)
|
||||
rospy.set_param(key_base + "/cmd_topic", self.cmd_topic)
|
||||
print "Added dummy dimmer \"" + name + "\""
|
||||
# Create JSON schema provider
|
||||
self.schemaProvider = HOSParamServerProvider()
|
||||
# Create message publisher
|
||||
self.commandPublisher = rospy.Publisher(self.cmd_topic, DeviceCommand, queue_size=10)
|
||||
# Init GUI
|
||||
tk.Frame.__init__(self, master, padx="10px", pady="10px")
|
||||
self.grid()
|
||||
self.createWidgets()
|
||||
|
||||
|
||||
def createWidgets(self):
|
||||
self.switchframe = tk.LabelFrame(self, text = "Switches", relief=Tkconstants.SUNKEN, bd=1)
|
||||
self.switchframe.grid(column=0, row=0)
|
||||
for i in range(4):
|
||||
self.switches[i]["intvar"] = tk.IntVar(value=int(self.switches[i]["value"]))
|
||||
self.switches[i]["checkbutton"] = tk.Checkbutton(self.switchframe, text=self.switches[i]["name"], variable = self.switches[i]["intvar"], onvalue = 1, offvalue = 0, height=5, width = 20, command=self.switchCallback)
|
||||
self.switches[i]["checkbutton"].grid(column=0, row=i)
|
||||
|
||||
self.dimmerframe = tk.LabelFrame(self, text = "Dimmers", relief=Tkconstants.SUNKEN, bd=1)
|
||||
self.dimmerframe.grid(column=1, row=0)
|
||||
for i in range(4):
|
||||
self.dimmers[i]["doublevar"] = tk.DoubleVar(value=float(self.dimmers[i]["value"]))
|
||||
self.dimmers[i]["label"] = tk.Label(self.dimmerframe, text=self.dimmers[i]["name"])
|
||||
self.dimmers[i]["label"].grid(column=0, row=i)
|
||||
self.dimmers[i]["scale"] = tk.Scale( self.dimmerframe, variable = self.dimmers[i]["doublevar"], from_=0.0, to=100.0, command=self.scaleCallback)
|
||||
self.dimmers[i]["scale"].grid(column=1, row=i)
|
||||
|
||||
#self.quitButton = tk.Button(self, text='Quit', command=self.quit)
|
||||
#self.quitButton.grid()
|
||||
|
||||
|
||||
def createSwitchMsg(self, switch, seq, stamp):
|
||||
msg = DeviceCommand()
|
||||
msg.seq = seq
|
||||
msg.device_id = switch["id"]
|
||||
msg.device_type = "core/devices/switch"
|
||||
msg.stamp = stamp
|
||||
|
||||
msg_body = dict()
|
||||
|
||||
msg_body["switch"] = dict()
|
||||
msg_body["switch"]["set"] = switch["value"]
|
||||
|
||||
msg_schema = self.schemaProvider.getTypeSchema("core/devices/switch/command")
|
||||
validator = load(msg_schema, provider=self.schemaProvider)
|
||||
|
||||
validator.validate(msg_body)
|
||||
|
||||
msg.msg_body = json.dumps(msg_body)
|
||||
return msg
|
||||
|
||||
|
||||
def createDimmerMsg(self, dimmer, seq, stamp):
|
||||
msg = DeviceCommand()
|
||||
msg.seq = seq
|
||||
msg.device_id = dimmer["id"]
|
||||
msg.device_type = "core/devices/dimmer"
|
||||
msg.stamp = stamp
|
||||
|
||||
msg_body = dict()
|
||||
|
||||
msg_body["dimmer"] = dict()
|
||||
msg_body["dimmer"]["set"] = dimmer["value"]/100.0
|
||||
|
||||
msg_schema = self.schemaProvider.getTypeSchema("core/devices/dimmer/command")
|
||||
validator = load(msg_schema, provider=self.schemaProvider)
|
||||
validator.validate(msg_body)
|
||||
|
||||
msg.msg_body = json.dumps(msg_body)
|
||||
return msg
|
||||
|
||||
|
||||
def scaleCallback(self, newvalue):
|
||||
stamp = rospy.get_rostime()
|
||||
for i in self.dimmers:
|
||||
if (self.dimmers[i]["value"] != self.dimmers[i]["doublevar"].get()):
|
||||
self.dimmers[i]["value"] = float(self.dimmers[i]["doublevar"].get())
|
||||
self.commandPublisher.publish(self.createDimmerMsg(self.dimmers[i], self.msg_sequence, stamp))
|
||||
self.msg_sequence += 1
|
||||
|
||||
|
||||
def switchCallback(self):
|
||||
stamp = rospy.get_rostime()
|
||||
for i in self.switches:
|
||||
if (self.switches[i]["value"] != bool(self.switches[i]["intvar"].get())):
|
||||
self.switches[i]["value"] = bool(self.switches[i]["intvar"].get())
|
||||
self.commandPublisher.publish(self.createSwitchMsg(self.switches[i], self.msg_sequence, stamp))
|
||||
self.msg_sequence += 1
|
||||
@@ -0,0 +1,206 @@
|
||||
#!/usr/bin/env python
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
import sys
|
||||
import rospy
|
||||
import json
|
||||
from hos_pyhue import pyhue
|
||||
from hos_core_msgs.msg import DeviceCommand
|
||||
from hos_core_msgs.msg import DeviceStatusUpdate
|
||||
from hos_core_msgs.msg import HosStatusUpdate
|
||||
from jsonspec_hos.reference.providers import HOSParamServerProvider
|
||||
from jsonspec.validators import load
|
||||
from time import sleep
|
||||
|
||||
import Tkinter as tk
|
||||
import Tkconstants
|
||||
|
||||
|
||||
class HosDummyDevices(tk.Frame):
|
||||
def __init__(self, master=None):
|
||||
# Init ROS node
|
||||
rospy.init_node('hos_dummy_devices', argv=sys.argv)
|
||||
# Get ROS parameter
|
||||
self.status_topic = rospy.get_param('~status_topic', "/hos/devices/status")
|
||||
self.cmd_topic = rospy.get_param('~cmd_topic', "/hos/devices/cmd")
|
||||
self.hos_update_topic = rospy.get_param('~hos_update_topic', "/hos/status/updates")
|
||||
self.loop_frequency = rospy.get_param('~loop_frequency', 100)
|
||||
self.statusmsg_interval = rospy.get_param('~statusmsg_interval', 6000000)
|
||||
# Init Variables
|
||||
self.msg_sequence = 0
|
||||
# Init devices
|
||||
new_devices = list()
|
||||
self.switches = dict()
|
||||
self.dimmers = dict()
|
||||
for i in range(4):
|
||||
# switches
|
||||
name = "dummySwitch" + str(i)
|
||||
self.switches[i] = dict()
|
||||
self.switches[i]["value"] = False
|
||||
self.switches[i]["id"] = name
|
||||
self.switches[i]["name"] = "Switch " + str(i)
|
||||
key_base = "/hos/devices/repository/" + name
|
||||
rospy.set_param(key_base + "/type", "core/devices/switch")
|
||||
rospy.set_param(key_base + "/status_topic", self.status_topic)
|
||||
rospy.set_param(key_base + "/cmd_topic", self.cmd_topic)
|
||||
print "Added dummy switch \"" + name + "\""
|
||||
new_devices.append(name)
|
||||
# dimmers
|
||||
name = "dummyDimmer" + str(i)
|
||||
self.dimmers[i] = dict()
|
||||
self.dimmers[i]["value"] = 0.0
|
||||
self.dimmers[i]["id"] = name
|
||||
self.dimmers[i]["name"] = "Dimmer " + str(i)
|
||||
key_base = "/hos/devices/repository/" + name
|
||||
rospy.set_param(key_base + "/type", "core/devices/switch")
|
||||
rospy.set_param(key_base + "/status_topic", self.status_topic)
|
||||
rospy.set_param(key_base + "/cmd_topic", self.cmd_topic)
|
||||
print "Added dummy dimmer \"" + name + "\""
|
||||
new_devices.append(name)
|
||||
# Create JSON schema provider
|
||||
self.schemaProvider = HOSParamServerProvider()
|
||||
# Create message publisher
|
||||
self.statusPublisher = rospy.Publisher(self.status_topic, DeviceStatusUpdate, queue_size=10)
|
||||
self.hosUpdatePublisher = rospy.Publisher(self.hos_update_topic, HosStatusUpdate, queue_size=10)
|
||||
# Send HOS Status Update Message
|
||||
updMsg = HosStatusUpdate()
|
||||
stamp = rospy.get_rostime()
|
||||
updMsg.stamp = stamp
|
||||
updMsg.tags.append("devices")
|
||||
updBody = dict()
|
||||
updBody["type"] = "core/msgs/hosstatusupdate"
|
||||
updBody["devices"] = dict()
|
||||
updBody["devices"]["type"] = "core/msgs/hosstatusupdate/devices";
|
||||
updBody["devices"]["added"] = new_devices
|
||||
|
||||
msg_schema = self.schemaProvider.getTypeSchema("core/msgs/hosstatusupdate")
|
||||
validator = load(msg_schema, provider=self.schemaProvider)
|
||||
validator.validate(updBody)
|
||||
|
||||
updMsg.msg_body = json.dumps(updBody)
|
||||
sleep(1) # Apparently we need to wait before we can send messages
|
||||
self.hosUpdatePublisher.publish(updMsg)
|
||||
|
||||
# Init GUI
|
||||
tk.Frame.__init__(self, master, padx="10px", pady="10px")
|
||||
self.grid()
|
||||
self.createWidgets()
|
||||
|
||||
self.deviceStatusCallback()
|
||||
|
||||
|
||||
def createWidgets(self):
|
||||
self.switchframe = tk.LabelFrame(self, text = "Switches", relief=Tkconstants.SUNKEN, bd=1)
|
||||
self.switchframe.grid(column=0, row=0)
|
||||
for i in range(4):
|
||||
self.switches[i]["stringvar"] = tk.StringVar(value=str(self.switches[i]["value"]))
|
||||
self.switches[i]["label1"] = tk.Label(self.switchframe, text=self.switches[i]["name"])
|
||||
self.switches[i]["label1"].grid(column=0, row=i)
|
||||
self.switches[i]["label2"] = tk.Label(self.switchframe, textvariable=self.switches[i]["stringvar"], relief=Tkconstants.GROOVE, width = 4)
|
||||
self.switches[i]["label2"].grid(column=1, row=i)
|
||||
|
||||
self.dimmerframe = tk.LabelFrame(self, text = "Dimmers", relief=Tkconstants.SUNKEN, bd=1)
|
||||
self.dimmerframe.grid(column=1, row=0)
|
||||
for i in range(4):
|
||||
self.dimmers[i]["stringvar"] = tk.StringVar(value=str(self.dimmers[i]["value"]))
|
||||
self.dimmers[i]["label1"] = tk.Label(self.dimmerframe, text=self.dimmers[i]["name"])
|
||||
self.dimmers[i]["label1"].grid(column=0, row=i)
|
||||
self.dimmers[i]["label2"] = tk.Label(self.dimmerframe, textvariable=self.dimmers[i]["stringvar"], relief=Tkconstants.GROOVE, width = 4)
|
||||
self.dimmers[i]["label2"].grid(column=1, row=i)
|
||||
|
||||
#self.quitButton = tk.Button(self, text='Quit', command=self.quit)
|
||||
#self.quitButton.grid()
|
||||
|
||||
|
||||
def createSwitchMsg(self, switch, seq, stamp):
|
||||
msg = DeviceStatusUpdate()
|
||||
msg.seq = seq
|
||||
msg.device_id = switch["id"]
|
||||
msg.device_type = "core/devices/switch"
|
||||
msg.stamp = stamp
|
||||
|
||||
msg_body = dict()
|
||||
|
||||
msg_body["switch"] = dict()
|
||||
msg_body["switch"]["value"] = switch["value"]
|
||||
|
||||
msg_schema = self.schemaProvider.getTypeSchema("core/devices/switch/status")
|
||||
validator = load(msg_schema, provider=self.schemaProvider)
|
||||
|
||||
validator.validate(msg_body)
|
||||
|
||||
msg.msg_body = json.dumps(msg_body)
|
||||
return msg
|
||||
|
||||
|
||||
def createDimmerMsg(self, dimmer, seq, stamp):
|
||||
msg = DeviceStatusUpdate()
|
||||
msg.seq = seq
|
||||
msg.device_id = dimmer["id"]
|
||||
msg.device_type = "core/devices/dimmer"
|
||||
msg.stamp = stamp
|
||||
|
||||
msg_body = dict()
|
||||
|
||||
msg_body["dimmer"] = dict()
|
||||
msg_body["dimmer"]["value"] = dimmer["value"]
|
||||
|
||||
msg_schema = self.schemaProvider.getTypeSchema("core/devices/dimmer/status")
|
||||
validator = load(msg_schema, provider=self.schemaProvider)
|
||||
validator.validate(msg_body)
|
||||
|
||||
msg.msg_body = json.dumps(msg_body)
|
||||
return msg
|
||||
|
||||
|
||||
def deviceStatusCallback(self):
|
||||
stamp = rospy.get_rostime()
|
||||
for switch in self.switches:
|
||||
self.statusPublisher.publish(self.createSwitchMsg(self.switches[switch], self.msg_sequence, stamp))
|
||||
for dimmer in self.dimmers:
|
||||
self.statusPublisher.publish(self.createDimmerMsg(self.dimmers[dimmer], self.msg_sequence, stamp))
|
||||
self.msg_sequence += 1
|
||||
self.after(10000, self.deviceStatusCallback)
|
||||
|
||||
|
||||
def deviceCmdCallback(self, data):
|
||||
rospy.loginfo(rospy.get_caller_id() + ": I heard %s", str(data))
|
||||
for i in self.switches:
|
||||
if self.switches[i]["id"] == data.device_id:
|
||||
self.deviceSwitchCmdCallback(self.switches[i], data)
|
||||
return
|
||||
for i in self.dimmers:
|
||||
if self.dimmers[i]["id"] == data.device_id:
|
||||
self.deviceDimmerCmdCallback(self.dimmers[i], data)
|
||||
return
|
||||
|
||||
|
||||
def deviceSwitchCmdCallback(self, switch, data):
|
||||
msg_body = json.loads(data.msg_body)
|
||||
msg_schema = self.schemaProvider.getTypeSchema("core/devices/switch/command")
|
||||
validator = load(msg_schema, provider=self.schemaProvider)
|
||||
validator.validate(msg_body)
|
||||
|
||||
value = msg_body["switch"]["set"]
|
||||
switch["value"] = bool(value)
|
||||
switch["stringvar"].set(str(value))
|
||||
|
||||
stamp = rospy.get_rostime()
|
||||
self.statusPublisher.publish(self.createSwitchMsg(switch, self.msg_sequence, stamp))
|
||||
self.msg_sequence += 1
|
||||
|
||||
|
||||
def deviceDimmerCmdCallback(self, dimmer, data):
|
||||
print
|
||||
msg_body = json.loads(data.msg_body)
|
||||
msg_schema = self.schemaProvider.getTypeSchema("core/devices/dimmer/command")
|
||||
validator = load(msg_schema, provider=self.schemaProvider)
|
||||
validator.validate(msg_body)
|
||||
value = msg_body["dimmer"]["set"]
|
||||
dimmer["value"] = float(value)
|
||||
dimmer["stringvar"].set(value)
|
||||
|
||||
stamp = rospy.get_rostime()
|
||||
self.statusPublisher.publish(self.createDimmerMsg(dimmer, self.msg_sequence, stamp))
|
||||
self.msg_sequence += 1
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
from distutils.core import setup
|
||||
from catkin_pkg.python_setup import generate_distutils_setup
|
||||
|
||||
package_info = generate_distutils_setup(
|
||||
packages=['hos_dummy'],
|
||||
package_dir={'': 'python'},
|
||||
)
|
||||
|
||||
setup(**package_info)
|
||||
@@ -10,13 +10,13 @@ from hos_core_msgs.msg import DeviceCommand
|
||||
from hos_huecontroller.huecontroller import HueController
|
||||
|
||||
|
||||
controller = HueController()
|
||||
|
||||
def deviceCmdCallback(data):
|
||||
controller.deviceCmdCallback(data)
|
||||
|
||||
if __name__ == '__main__':
|
||||
try:
|
||||
controller = HueController()
|
||||
rospy.Subscriber(controller.cmd_topic, DeviceCommand, deviceCmdCallback)
|
||||
controller.mainLoop()
|
||||
except socket.error as e:
|
||||
|
||||
@@ -1,19 +0,0 @@
|
||||
{
|
||||
"$schema": "http://json-schema.org/draft-04/schema#",
|
||||
"title": "Color Capability",
|
||||
"description": "",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"colormode": {
|
||||
"description": "",
|
||||
"type": "string",
|
||||
"persistent": "True",
|
||||
"volatile": "False"
|
||||
},
|
||||
"prop1": {
|
||||
"$ref" : "hos:schema://core/capabilities/switch/command#"
|
||||
}
|
||||
},
|
||||
"test" : "bla",
|
||||
"persistent": ["bla1", "bla2"]
|
||||
}
|
||||
Reference in New Issue
Block a user