diff --git a/telldus-core/common/Message.cpp b/telldus-core/common/Message.cpp index 818110d9..e38f887d 100644 --- a/telldus-core/common/Message.cpp +++ b/telldus-core/common/Message.cpp @@ -48,6 +48,13 @@ std::wstring Message::charToWstring(const char *value) { return st.str(); } +std::wstring Message::charUnsignedToWstring(const unsigned char value) { + //todo move? + std::wstringstream st; + st << value; + return st.str(); +} + std::wstring Message::intToWstring(int value) { //todo move? std::wstringstream st; diff --git a/telldus-core/common/Message.h b/telldus-core/common/Message.h index 9c8f13e5..e75a23e5 100644 --- a/telldus-core/common/Message.h +++ b/telldus-core/common/Message.h @@ -19,6 +19,7 @@ namespace TelldusCore { std::wstring getClientWStringFromSocket(); static std::wstring charToWstring(const char *value); + static std::wstring charUnsignedToWstring(const unsigned char value); static std::wstring intToWstring(int value); static bool nextIsInt(const std::wstring &); static bool nextIsString(const std::wstring &); @@ -26,8 +27,10 @@ namespace TelldusCore { static std::wstring takeString(std::wstring *); static int takeInt(std::wstring *); - private: static int wideToInteger(const std::wstring &input); + + private: + }; } diff --git a/telldus-core/service/ClientCommunicationHandler.cpp b/telldus-core/service/ClientCommunicationHandler.cpp index f2c01efc..84e7166a 100644 --- a/telldus-core/service/ClientCommunicationHandler.cpp +++ b/telldus-core/service/ClientCommunicationHandler.cpp @@ -93,12 +93,11 @@ void ClientCommunicationHandler::parseMessage(const std::wstring &clientMessage, } else if (function == L"tdLastSentCommand") { int deviceId = TelldusCore::Message::takeInt(&msg); int methodsSupported = TelldusCore::Message::takeInt(&msg); - (*intReturn) = 0; // tdLastSentCommand(deviceId, methodsSupported); TODO + (*intReturn) = d->deviceManager->getDeviceLastSentCommand(deviceId, methodsSupported); } else if (function == L"tdLastSentValue") { int deviceId = TelldusCore::Message::takeInt(&msg); - const char *value = ""; //tdLastSentValue(deviceId); TODO - (*wstringReturn) = TelldusCore::Message::charToWstring(value); + (*wstringReturn) = d->deviceManager->getDeviceStateValue(deviceId); } else if(function == L"tdGetNumberOfDevices"){ diff --git a/telldus-core/service/Device.cpp b/telldus-core/service/Device.cpp index a8639ffe..006bf1ee 100644 --- a/telldus-core/service/Device.cpp +++ b/telldus-core/service/Device.cpp @@ -9,6 +9,8 @@ public: Protocol *protocol; std::wstring protocolName; int preferredControllerId; + int state; + std::wstring stateValue; }; Device::Device(int id) @@ -17,6 +19,7 @@ Device::Device(int id) d = new PrivateData; d->protocol = 0; d->preferredControllerId = 0; + d->state = 0; //när något uppdateras, spara också till registret //obs, kunna hantera om alla värden inte är satta } @@ -29,6 +32,27 @@ Device::~Device(void) { /** * Get-/Set-methods */ + +int Device::getLastSentCommand(int methodsSupported){ + + int lastSentCommand = Device::maskUnsupportedMethods(d->state, methodsSupported); + + if (lastSentCommand == TELLSTICK_BELL) { + //Bell is not a state + lastSentCommand = TELLSTICK_TURNOFF; + } + if (lastSentCommand == 0) { + lastSentCommand = TELLSTICK_TURNOFF; + } + return lastSentCommand; + +} + +void Device::setLastSentCommand(int command, std::wstring value){ + d->state = command; + d->stateValue = value; +} + std::wstring Device::getModel(){ return d->model; } @@ -69,6 +93,10 @@ void Device::setProtocolName(const std::wstring &protocolName){ d->protocolName = protocolName; } +std::wstring Device::getStateValue(){ + return d->stateValue; +} + /** * End Get-/Set */ @@ -78,9 +106,9 @@ int Device::doAction(int action, unsigned char data, Controller *controller) { Protocol *p = this->retrieveProtocol(); if(p){ std::string code = p->getStringForMethod(action, data, controller); - controller->send(code); + return controller->send(code); } - return 0; + return TELLSTICK_ERROR_UNKNOWN; } Protocol* Device::retrieveProtocol() { @@ -96,4 +124,13 @@ Protocol* Device::retrieveProtocol() { } return 0; +} + +int Device::maskUnsupportedMethods(int methods, int supportedMethods) { + // Bell -> On + if ((methods & TELLSTICK_BELL) && !(supportedMethods & TELLSTICK_BELL)) { + methods |= TELLSTICK_TURNON; + } + //Cut of the rest of the unsupported methods we don't have a fallback for + return methods & supportedMethods; } \ No newline at end of file diff --git a/telldus-core/service/Device.h b/telldus-core/service/Device.h index 1f108b40..cbeaa306 100644 --- a/telldus-core/service/Device.h +++ b/telldus-core/service/Device.h @@ -12,6 +12,9 @@ public: Device(int id); ~Device(void); + int doAction(int action, unsigned char data, Controller *controller); + std::wstring getStateValue(); + int getLastSentCommand(int methodsSupported); std::wstring getModel(); void setModel(const std::wstring &model); std::wstring getName(); @@ -22,10 +25,12 @@ public: void setPreferredControllerId(int controllerId); std::wstring getProtocolName(); void setProtocolName(const std::wstring &name); - int doAction(int action, unsigned char data, Controller *controller); + void setStateValue(int stateValue); + void setLastSentCommand(int command, std::wstring value); + + static int maskUnsupportedMethods(int methods, int supportedMethods); private: - Protocol *retrieveProtocol(); class PrivateData; diff --git a/telldus-core/service/DeviceManager.cpp b/telldus-core/service/DeviceManager.cpp index 144b0bf9..de96605a 100644 --- a/telldus-core/service/DeviceManager.cpp +++ b/telldus-core/service/DeviceManager.cpp @@ -1,6 +1,7 @@ #include "DeviceManager.h" #include "Mutex.h" #include "Settings.h" +#include "Message.h" #include @@ -22,7 +23,7 @@ DeviceManager::DeviceManager(ControllerManager *controllerManager){ DeviceManager::~DeviceManager(void) { - TelldusCore::MutexLocker locker(&d->lock); + TelldusCore::MutexLocker deviceLocker(&d->lock); for (DeviceMap::iterator it = d->devices.begin(); it != d->devices.end(); ++it) { {TelldusCore::MutexLocker lock(it->second);} //aquire lock, and release it, just to see that the device it's not in use anywhere delete(it->second); @@ -31,7 +32,7 @@ DeviceManager::~DeviceManager(void) { } void DeviceManager::fillDevices(){ - TelldusCore::MutexLocker locker(&d->lock); + TelldusCore::MutexLocker deviceLocker(&d->lock); int numberOfDevices = d->set.getNumberOfDevices(); for (int i = 0; i < numberOfDevices; ++i) { @@ -41,6 +42,7 @@ void DeviceManager::fillDevices(){ d->devices[id]->setModel(d->set.getModel(id)); d->devices[id]->setProtocolName(d->set.getProtocol(id)); d->devices[id]->setPreferredControllerId(d->set.getPreferredControllerId(id)); + d->devices[id]->setLastSentCommand(d->set.getDeviceState(id), d->set.getDeviceStateValue(id)); d->devices[id]->setParameter(L"house", d->set.getDeviceParameter(id, L"house")); d->devices[id]->setParameter(L"unit", d->set.getDeviceParameter(id, L"unit")); d->devices[id]->setParameter(L"code", d->set.getDeviceParameter(id, L"code")); @@ -50,9 +52,63 @@ void DeviceManager::fillDevices(){ } } +int DeviceManager::getDeviceLastSentCommand(int deviceId, int methodsSupported){ + TelldusCore::MutexLocker deviceLocker(&d->lock); + if (!d->devices.size()) { + return TELLSTICK_ERROR_DEVICE_NOT_FOUND; + } + DeviceMap::iterator it = d->devices.find(deviceId); + if (it != d->devices.end()) { + //TODO: Is it ok NOT to get a lock here? Should be, since the list is locked, and it's an fast operation? + return it->second->getLastSentCommand(methodsSupported); + } + return TELLSTICK_ERROR_DEVICE_NOT_FOUND; +} + +int DeviceManager::setDeviceLastSentCommand(int deviceId, int command, std::wstring value) +{ + //TODO: check this locking, ok? + Device *device = 0; + { + TelldusCore::MutexLocker deviceLocker(&d->lock); + if (!d->devices.size()) { + return TELLSTICK_ERROR_DEVICE_NOT_FOUND; + } + DeviceMap::iterator it = d->devices.find(deviceId); + if (it != d->devices.end()) { + device = it->second; + d->set.setDeviceState(deviceId, command,value); + } + else{ + return TELLSTICK_ERROR_DEVICE_NOT_FOUND; + } + } + if(device){ + TelldusCore::MutexLocker lock(device); + device->setLastSentCommand(command, value); + } + + return TELLSTICK_SUCCESS; +} + + + +std::wstring DeviceManager::getDeviceStateValue(int deviceId){ + TelldusCore::MutexLocker deviceLocker(&d->lock); + if (!d->devices.size()) { + return L"UNKNOWN"; //TODO, what? + } + DeviceMap::iterator it = d->devices.find(deviceId); + if (it != d->devices.end()) { + //TODO: Is it ok NOT to get a lock here? Should be, since the list is locked, and it's an fast operation? + return it->second->getStateValue(); + } + return L"UNKNOWN"; //TODO, what? +} + std::wstring DeviceManager::getDeviceModel(int deviceId){ - TelldusCore::MutexLocker locker(&d->lock); + TelldusCore::MutexLocker deviceLocker(&d->lock); if (!d->devices.size()) { return L"UNKNOWN"; //TODO, what? } @@ -69,7 +125,7 @@ int DeviceManager::setDeviceModel(int deviceId, std::wstring model) //TODO: check this locking, ok? Device *device = 0; { - TelldusCore::MutexLocker locker(&d->lock); + TelldusCore::MutexLocker deviceLocker(&d->lock); if (!d->devices.size()) { return TELLSTICK_ERROR_DEVICE_NOT_FOUND; } @@ -93,7 +149,7 @@ int DeviceManager::setDeviceModel(int deviceId, std::wstring model) std::wstring DeviceManager::getDeviceName(int deviceId){ - TelldusCore::MutexLocker locker(&d->lock); + TelldusCore::MutexLocker deviceLocker(&d->lock); if (!d->devices.size()) { return L"UNKNOWN"; //TODO, what? } @@ -110,7 +166,7 @@ int DeviceManager::setDeviceName(int deviceId, std::wstring name){ //TODO: check this locking, ok? Device *device = 0; { - TelldusCore::MutexLocker locker(&d->lock); + TelldusCore::MutexLocker deviceLocker(&d->lock); if (!d->devices.size()) { return TELLSTICK_ERROR_DEVICE_NOT_FOUND; } @@ -133,7 +189,7 @@ int DeviceManager::setDeviceName(int deviceId, std::wstring name){ std::wstring DeviceManager::getDeviceParameter(int deviceId, std::wstring name, std::wstring defaultValue){ - TelldusCore::MutexLocker locker(&d->lock); + TelldusCore::MutexLocker deviceLocker(&d->lock); if (!d->devices.size()) { return defaultValue; } @@ -153,7 +209,7 @@ int DeviceManager::setDeviceParameter(int deviceId, std::wstring name, std::wstr //TODO: check this locking, ok? Device *device = 0; { - TelldusCore::MutexLocker locker(&d->lock); + TelldusCore::MutexLocker deviceLocker(&d->lock); if (!d->devices.size()) { return TELLSTICK_ERROR_DEVICE_NOT_FOUND; } @@ -177,7 +233,7 @@ int DeviceManager::setDeviceParameter(int deviceId, std::wstring name, std::wstr std::wstring DeviceManager::getDeviceProtocol(int deviceId){ - TelldusCore::MutexLocker locker(&d->lock); + TelldusCore::MutexLocker deviceLocker(&d->lock); if (!d->devices.size()) { return L"UNKNOWN"; //TODO, what? } @@ -194,7 +250,7 @@ int DeviceManager::setDeviceProtocol(int deviceId, std::wstring protocol) //TODO: check this locking, ok? Device *device = 0; { - TelldusCore::MutexLocker locker(&d->lock); + TelldusCore::MutexLocker deviceLocker(&d->lock); if (!d->devices.size()) { return TELLSTICK_ERROR_DEVICE_NOT_FOUND; } @@ -216,12 +272,12 @@ int DeviceManager::setDeviceProtocol(int deviceId, std::wstring protocol) } int DeviceManager::getNumberOfDevices(){ - TelldusCore::MutexLocker locker(&d->lock); + TelldusCore::MutexLocker deviceLocker(&d->lock); return (int)d->devices.size(); } int DeviceManager::addDevice(){ - TelldusCore::MutexLocker locker(&d->lock); + TelldusCore::MutexLocker deviceLocker(&d->lock); int id = d->set.addDevice(); if(id == -1){ @@ -236,7 +292,7 @@ int DeviceManager::addDevice(){ } int DeviceManager::getDeviceId(int deviceIndex) { - TelldusCore::MutexLocker locker(&d->lock); + TelldusCore::MutexLocker deviceLocker(&d->lock); return d->set.getDeviceId(deviceIndex); } @@ -247,7 +303,7 @@ int DeviceManager::getDeviceType(int deviceId){ int DeviceManager::getPreferredControllerId(int deviceId){ - TelldusCore::MutexLocker locker(&d->lock); + TelldusCore::MutexLocker deviceLocker(&d->lock); if (!d->devices.size()) { return TELLSTICK_ERROR_DEVICE_NOT_FOUND; @@ -264,7 +320,7 @@ int DeviceManager::removeDevice(int deviceId){ Device *device = 0; { - TelldusCore::MutexLocker locker(&d->lock); + TelldusCore::MutexLocker deviceLocker(&d->lock); if(!d->set.removeDevice(deviceId)){ //remove from register/settings return TELLSTICK_ERROR_UNKNOWN; } @@ -306,7 +362,7 @@ int DeviceManager::doAction(int deviceId, int action, unsigned char data){ } DeviceMap::iterator it = d->devices.find(deviceId); if (it != d->devices.end()) { - it->second->lock(); //device locked + it->second->lock(); //device locked TODO, nog här... device = it->second; } //devices unlocked @@ -320,6 +376,18 @@ int DeviceManager::doAction(int deviceId, int action, unsigned char data){ Controller *controller = d->controllerManager->getBestControllerById(this->getPreferredControllerId(deviceId)); if(controller){ int retval = device->doAction(action, data, controller); + if(retval == TELLSTICK_SUCCESS){ + std::wstring datastring = TelldusCore::Message::charUnsignedToWstring(data); + device->setLastSentCommand(action, datastring); + device->unlock(); + { + //new lock, for setting (all other locks are unlocked) + //TODO, it MAY be inconsistency between stored values and device values here... change something? + TelldusCore::MutexLocker deviceLocker(&d->lock); + d->set.setDeviceState(deviceId, action, datastring); + } + //TODO: Signal event, status change? + } device->unlock(); return retval; } diff --git a/telldus-core/service/DeviceManager.h b/telldus-core/service/DeviceManager.h index d47ce1f1..8354b031 100644 --- a/telldus-core/service/DeviceManager.h +++ b/telldus-core/service/DeviceManager.h @@ -12,6 +12,8 @@ public: int getNumberOfDevices(void); int addDevice(); int getDeviceId(int deviceIndex); + int getDeviceLastSentCommand(int deviceId, int methodsSupported); + int setDeviceLastSentCommand(int deviceId, int command, std::wstring value); std::wstring getDeviceModel(int deviceId); int setDeviceModel(int deviceId, std::wstring model); std::wstring getDeviceName(int deviceId); @@ -20,6 +22,7 @@ public: int setDeviceParameter(int deviceId, std::wstring name, std::wstring value); std::wstring getDeviceProtocol(int deviceId); int setDeviceProtocol(int deviceId, std::wstring name); + std::wstring getDeviceStateValue(int deviceId); int getDeviceType(int deviceId); int getPreferredControllerId(int deviceId); int removeDevice(int deviceId);