int DeviceManager::doGroupSceneAction(int deviceId, int action, unsigned char data) { std::set<int> parsedDevices; std::queue<int> devicesToParse; devicesToParse.push(deviceId); while (!devicesToParse.empty()) { int deviceId = devicesToParse.front(); devicesToParse.pop(); if (parsedDevices.count(deviceId)) { continue; } parsedDevices.insert(deviceId); TelldusCore::MutexLocker deviceListLocker(&d->lock); DeviceMap::iterator it = d->devices.find(deviceId); if (it == d->devices.end()) { // Not found continue; } if (it->second->isMethodSupported(action) <= 0) { return TELLSTICK_ERROR_METHOD_NOT_SUPPORTED; } TelldusCore::MutexLocker deviceLocker(it->second); if (it->second->getType() == TELLSTICK_TYPE_DEVICE) { ExecuteActionEventData *eventData = new ExecuteActionEventData(); eventData->deviceId = deviceId; eventData->method = action; eventData->data = data; d->executeActionEvent->signal(eventData); continue; } if (it->second->getType() == TELLSTICK_TYPE_GROUP) { std::string devices = TelldusCore::wideToString(it->second->getParameter(L"devices")); std::stringstream devicesstream(devices); std::string singledevice; while(std::getline(devicesstream, singledevice, ',')) { devicesToParse.push(TelldusCore::charToInteger(singledevice.c_str())); } // Update state if(it->second->getMethods() & action) { // if method isn't explicitly supported by device, but used anyway as a fallback (i.e. bell), don't change state std::wstring datastring = TelldusCore::charUnsignedToWstring(data); if (this->triggerDeviceStateChange(deviceId, action, datastring)) { it->second->setLastSentCommand(action, datastring); d->set.setDeviceState(deviceId, action, datastring); } } } if (it->second->getType() == TELLSTICK_TYPE_SCENE) { // TODO(micke): Not supported yet Log::warning("Scenes are not supported yet!"); } } return TELLSTICK_SUCCESS; }
void DeviceManager::executeActionEvent() { Device *device = 0; TelldusCore::EventDataRef eventData = d->executeActionEvent->takeSignal(); ExecuteActionEventData *data = dynamic_cast<ExecuteActionEventData*>(eventData.get()); if (!data) { Log::error("Could not cast executeAction data"); return; } Log::notice("Execute a TellStick Action for device %i", data->deviceId); std::auto_ptr<TelldusCore::MutexLocker> deviceLocker(0); { // devicelist locked TelldusCore::MutexLocker deviceListLocker(&d->lock); DeviceMap::iterator it = d->devices.find(data->deviceId); if (it == d->devices.end()) { return; } // device locked deviceLocker = std::auto_ptr<TelldusCore::MutexLocker>(new TelldusCore::MutexLocker(it->second)); device = it->second; } // devicelist unlocked Controller *controller = d->controllerManager->getBestControllerById(device->getPreferredControllerId()); if(!controller) { return; } int retval = device->doAction(data->method, data->data, controller); if(retval == TELLSTICK_ERROR_BROKEN_PIPE) { Log::warning("Error in communication with TellStick when executing action. Resetting USB"); d->controllerManager->resetController(controller); } if(retval == TELLSTICK_ERROR_BROKEN_PIPE || retval == TELLSTICK_ERROR_NOT_FOUND) { Log::warning("Rescanning USB ports"); d->controllerManager->loadControllers(); controller = d->controllerManager->getBestControllerById(device->getPreferredControllerId()); if(!controller) { Log::error("No contoller (TellStick) found, even after reset. Giving up."); return; } retval = device->doAction(data->method, data->data, controller); // retry one more time } if(retval == TELLSTICK_SUCCESS && device->getMethods() & data->method) { // if method isn't explicitly supported by device, but used anyway as a fallback (i.e. bell), don't change state std::wstring datastring = TelldusCore::charUnsignedToWstring(data->data); if (this->triggerDeviceStateChange(data->deviceId, data->method, datastring)) { device->setLastSentCommand(data->method, datastring); d->set.setDeviceState(data->deviceId, data->method, datastring); } } }
~LoggerPrivate() { // Cleanup appenders QReadLocker appendersLocker(&m_appendersLock); foreach (AbstractAppender* appender, m_appenders) delete appender; // Cleanup device QReadLocker deviceLocker(&m_logDeviceLock); delete m_logDevice; }
int DeviceManager::getDeviceType(int deviceId) { TelldusCore::MutexLocker deviceListLocker(&d->lock); if (!d->devices.size()) { return TELLSTICK_ERROR_DEVICE_NOT_FOUND; } DeviceMap::iterator it = d->devices.find(deviceId); if (it != d->devices.end()) { TelldusCore::MutexLocker deviceLocker(it->second); return it->second->getType(); } return TELLSTICK_ERROR_DEVICE_NOT_FOUND; }
std::wstring DeviceManager::getDeviceProtocol(int deviceId) { TelldusCore::MutexLocker deviceListLocker(&d->lock); if (!d->devices.size()) { return L"UNKNOWN"; } DeviceMap::iterator it = d->devices.find(deviceId); if (it != d->devices.end()) { TelldusCore::MutexLocker deviceLocker(it->second); return it->second->getProtocolName(); } return L"UNKNOWN"; }
int DeviceManager::getDeviceLastSentCommand(int deviceId, int methodsSupported) { TelldusCore::MutexLocker deviceListLocker(&d->lock); if (!d->devices.size()) { return TELLSTICK_ERROR_DEVICE_NOT_FOUND; } DeviceMap::iterator it = d->devices.find(deviceId); if (it != d->devices.end()) { TelldusCore::MutexLocker deviceLocker(it->second); return it->second->getLastSentCommand(methodsSupported); } return TELLSTICK_ERROR_DEVICE_NOT_FOUND; }
int DeviceManager::getDeviceMethods(int deviceId, std::set<int> *duplicateDeviceIds) { int type = 0; int methods = 0; std::wstring deviceIds; std::wstring protocol; { // devices locked TelldusCore::MutexLocker deviceListLocker(&d->lock); if (!d->devices.size()) { return TELLSTICK_ERROR_DEVICE_NOT_FOUND; } DeviceMap::iterator it = d->devices.find(deviceId); if (it != d->devices.end()) { { TelldusCore::MutexLocker deviceLocker(it->second); type = it->second->getType(); methods = it->second->getMethods(); deviceIds = it->second->getParameter(L"devices"); protocol = it->second->getProtocolName(); } } } if(type == 0) { return 0; } if(type == TELLSTICK_TYPE_GROUP) { // get all methods that some device in the groups supports std::wstring deviceIdBuffer; std::wstringstream devicesstream(deviceIds); methods = 0; duplicateDeviceIds->insert(deviceId); while(std::getline(devicesstream, deviceIdBuffer, L',')) { int deviceIdInGroup = TelldusCore::wideToInteger(deviceIdBuffer); if(duplicateDeviceIds->count(deviceIdInGroup) == 1) { // action for device already executed, or will execute, do nothing to avoid infinite loop continue; } duplicateDeviceIds->insert(deviceIdInGroup); int deviceMethods = getDeviceMethods(deviceIdInGroup, duplicateDeviceIds); if(deviceMethods > 0) { methods |= deviceMethods; } } } return methods; }
DeviceManager::~DeviceManager(void) { { TelldusCore::MutexLocker deviceListLocker(&d->lock); for (DeviceMap::iterator it = d->devices.begin(); it != d->devices.end(); ++it) { {TelldusCore::MutexLocker deviceLocker(it->second);} // aquire lock, and release it, just to see that the device it's not in use anywhere delete(it->second); } for (std::list<Sensor *>::iterator it = d->sensorList.begin(); it != d->sensorList.end(); ++it) { {TelldusCore::MutexLocker sensorLocker(*it);} // aquire lock, and release it, just to see that the device it's not in use anywhere delete(*it); } } delete d; }
std::wstring DeviceManager::getDeviceParameter(int deviceId, const std::wstring &name, const std::wstring &defaultValue) { TelldusCore::MutexLocker deviceListLocker(&d->lock); if (!d->devices.size()) { return defaultValue; } DeviceMap::iterator it = d->devices.find(deviceId); if (it != d->devices.end()) { TelldusCore::MutexLocker deviceLocker(it->second); std::wstring returnString = it->second->getParameter(name); if(returnString != L"") { return returnString; } } return defaultValue; }
int DeviceManager::setDeviceLastSentCommand(int deviceId, int command, const std::wstring &value) { TelldusCore::MutexLocker deviceListLocker(&d->lock); if (!d->devices.size()) { return TELLSTICK_ERROR_DEVICE_NOT_FOUND; } DeviceMap::iterator it = d->devices.find(deviceId); if (it != d->devices.end()) { TelldusCore::MutexLocker deviceLocker(it->second); d->set.setDeviceState(deviceId, command, value); it->second->setLastSentCommand(command, value); } else { return TELLSTICK_ERROR_DEVICE_NOT_FOUND; } return TELLSTICK_SUCCESS; }
void DeviceManager::handleControllerMessage(const ControllerEventData &eventData) { // Trigger raw-event EventUpdateData *eventUpdateData = new EventUpdateData(); eventUpdateData->messageType = L"TDRawDeviceEvent"; eventUpdateData->controllerId = eventData.controllerId; eventUpdateData->eventValue = TelldusCore::charToWstring(eventData.msg.c_str()); d->deviceUpdateEvent->signal(eventUpdateData); ControllerMessage msg(eventData.msg); if (msg.msgClass().compare("sensor") == 0) { handleSensorMessage(msg); return; } TelldusCore::MutexLocker deviceListLocker(&d->lock); for (DeviceMap::iterator it = d->devices.begin(); it != d->devices.end(); ++it) { TelldusCore::MutexLocker deviceLocker(it->second); if (!TelldusCore::comparei(it->second->getProtocolName(), msg.protocol())) { continue; } if ( !(it->second->getMethods() & msg.method()) ) { continue; } std::list<std::string> parameters = it->second->getParametersForProtocol(); bool thisDevice = true; for (std::list<std::string>::iterator paramIt = parameters.begin(); paramIt != parameters.end(); ++paramIt) { if(!TelldusCore::comparei(it->second->getParameter(TelldusCore::charToWstring((*paramIt).c_str())), TelldusCore::charToWstring(msg.getParameter(*paramIt).c_str()))) { thisDevice = false; break; } } if(!thisDevice) { continue; } if (this->triggerDeviceStateChange(it->first, msg.method(), L"")) { d->set.setDeviceState(it->first, msg.method(), L""); it->second->setLastSentCommand(msg.method(), L""); } } }
int DeviceManager::setDeviceProtocol(int deviceId, const std::wstring &protocol) { TelldusCore::MutexLocker deviceListLocker(&d->lock); if (!d->devices.size()) { return TELLSTICK_ERROR_DEVICE_NOT_FOUND; } DeviceMap::iterator it = d->devices.find(deviceId); if (it != d->devices.end()) { TelldusCore::MutexLocker deviceLocker(it->second); int ret = d->set.setProtocol(deviceId, protocol); if (ret != TELLSTICK_SUCCESS) { return ret; } it->second->setProtocolName(protocol); } else { return TELLSTICK_ERROR_DEVICE_NOT_FOUND; } return TELLSTICK_SUCCESS; }
int DeviceManager::doAction(int deviceId, int action, unsigned char data) { int deviceType = 0; { // devicelist locked TelldusCore::MutexLocker deviceListLocker(&d->lock); DeviceMap::iterator it = d->devices.find(deviceId); if (it == d->devices.end()) { return TELLSTICK_ERROR_DEVICE_NOT_FOUND; // not found } // device locked TelldusCore::MutexLocker deviceLocker(it->second); deviceType = it->second->getType(); if (it->second->isMethodSupported(action) <= 0) { return TELLSTICK_ERROR_METHOD_NOT_SUPPORTED; } } if (d->controllerManager->count() == 0) { return TELLSTICK_ERROR_NOT_FOUND; } // The device exists and there is at least one connected controller if(deviceType == TELLSTICK_TYPE_GROUP || deviceType == TELLSTICK_TYPE_SCENE) { return this->doGroupSceneAction(deviceId, action, data); } ExecuteActionEventData *eventData = new ExecuteActionEventData(); eventData->deviceId = deviceId; eventData->method = action; eventData->data = data; d->executeActionEvent->signal(eventData); return TELLSTICK_SUCCESS; }