Execute a script from /usr/local/share/telldus/scripts on all events.
Closes #100
This commit is contained in:
parent
32f2d9f955
commit
d48ee1f02b
3 changed files with 124 additions and 0 deletions
|
@ -6,13 +6,28 @@
|
|||
//
|
||||
#include "service/EventUpdateManager.h"
|
||||
|
||||
#ifdef _LINUX
|
||||
#include <dirent.h>
|
||||
#include <errno.h>
|
||||
#include <stddef.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/wait.h>
|
||||
#endif // _LINUX
|
||||
#include <list>
|
||||
#include <memory>
|
||||
#ifdef _LINUX
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#endif // _LINUX
|
||||
|
||||
#include "service/ConnectionListener.h"
|
||||
#include "common/EventHandler.h"
|
||||
#include "common/Message.h"
|
||||
#include "common/Socket.h"
|
||||
#include "service/Log.h"
|
||||
#include "common/Strings.h"
|
||||
|
||||
typedef std::list<TelldusCore::Socket *> SocketList;
|
||||
|
||||
|
@ -68,6 +83,7 @@ void EventUpdateManager::run() {
|
|||
EventUpdateData *data = reinterpret_cast<EventUpdateData*>(eventData.get());
|
||||
if(data) {
|
||||
sendMessageToClients(data);
|
||||
executeScripts(data);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -120,3 +136,99 @@ void EventUpdateManager::sendMessageToClients(EventUpdateData *data) {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
void EventUpdateManager::executeScripts(EventUpdateData *data) {
|
||||
#ifdef _LINUX
|
||||
std::string dir;
|
||||
std::vector<std::string> env;
|
||||
|
||||
// Create a copy of the environment
|
||||
unsigned int size = 0;
|
||||
for(; ; ++size) {
|
||||
if (environ[size] == 0) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
env.reserve(size + 6); // 6 is the most used extra environmental variables any event uses
|
||||
for(unsigned int i = 0; i < size; ++i) {
|
||||
env.push_back(environ[i]);
|
||||
}
|
||||
|
||||
if(data->messageType == L"TDDeviceEvent") {
|
||||
dir = "deviceevent";
|
||||
env.push_back(TelldusCore::formatf("DEVICEID=%i", data->deviceId));
|
||||
env.push_back(TelldusCore::formatf("METHOD=%i", data->eventState));
|
||||
env.push_back(TelldusCore::formatf("METHODDATA=%s", TelldusCore::wideToString(data->eventValue).c_str()));
|
||||
} else if(data->messageType == L"TDDeviceChangeEvent") {
|
||||
dir = "devicechangeevent";
|
||||
env.push_back(TelldusCore::formatf("DEVICEID=%i", data->deviceId));
|
||||
env.push_back(TelldusCore::formatf("CHANGEEVENT=%i", data->eventDeviceChanges));
|
||||
env.push_back(TelldusCore::formatf("CHANGETYPE=%i", data->eventChangeType));
|
||||
} else if(data->messageType == L"TDRawDeviceEvent") {
|
||||
dir = "rawdeviceevent";
|
||||
env.push_back(TelldusCore::formatf("RAWDATA=%s", TelldusCore::wideToString(data->eventValue).c_str())); // string
|
||||
env.push_back(TelldusCore::formatf("CONTROLLERID=%i", data->controllerId));
|
||||
} else if (data->messageType == L"TDSensorEvent") {
|
||||
dir = "sensorevent";
|
||||
env.push_back(TelldusCore::formatf("PROTOCOL=%s", TelldusCore::wideToString(data->protocol).c_str()));
|
||||
env.push_back(TelldusCore::formatf("MODEL=%s", TelldusCore::wideToString(data->model).c_str()));
|
||||
env.push_back(TelldusCore::formatf("SENSORID=%i", data->sensorId));
|
||||
env.push_back(TelldusCore::formatf("DATATYPE=%i", data->dataType));
|
||||
env.push_back(TelldusCore::formatf("VALUE=%s", TelldusCore::wideToString(data->value).c_str()));
|
||||
env.push_back(TelldusCore::formatf("TIMESTAMP=%i", data->timestamp));
|
||||
} else if(data->messageType == L"TDControllerEvent") {
|
||||
dir = "controllerevent";
|
||||
env.push_back(TelldusCore::formatf("CONTROLLERID=%i", data->controllerId));
|
||||
env.push_back(TelldusCore::formatf("CHANGEEVENT=%i", data->eventState));
|
||||
env.push_back(TelldusCore::formatf("CHANGETYPE=%i", data->eventChangeType));
|
||||
env.push_back(TelldusCore::formatf("VALUE=%s", TelldusCore::wideToString(data->eventValue).c_str()));
|
||||
} else {
|
||||
// Unknown event, should not happen
|
||||
return;
|
||||
}
|
||||
|
||||
char *newEnv[env.size()+1]; // +1 for the last stop element
|
||||
for(int i = 0; i < env.size(); ++i) {
|
||||
newEnv[i] = new char[env.at(i).length()+1];
|
||||
snprintf(newEnv[i], env.at(i).length()+1, "%s", env.at(i).c_str());
|
||||
}
|
||||
newEnv[env.size()] = 0; // Mark end of array
|
||||
|
||||
// List files to execute
|
||||
std::string path = TelldusCore::formatf("/usr/local/share/telldus/scripts/%s", dir.c_str());
|
||||
struct dirent **namelist;
|
||||
int count = scandir(path.c_str(), &namelist, NULL, alphasort);
|
||||
if (count <= 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
for(int i = 0; i < count; ++i) {
|
||||
if (strcmp(namelist[i]->d_name, ".") == 0 || strcmp(namelist[i]->d_name, "..") == 0) {
|
||||
continue;
|
||||
}
|
||||
executeScript(TelldusCore::formatf("%s/%s", path.c_str(), namelist[i]->d_name), namelist[i]->d_name, newEnv);
|
||||
}
|
||||
|
||||
for(int i = 0; i < count; ++i) {
|
||||
free(namelist[i]);
|
||||
}
|
||||
free(namelist);
|
||||
#endif // _LINUX
|
||||
}
|
||||
|
||||
void EventUpdateManager::executeScript(std::string script, char *name, char ** env) {
|
||||
#ifdef _LINUX
|
||||
pid_t pid = fork();
|
||||
if (pid == -1) {
|
||||
Log::error("Could not fork() to execute script %s", script.c_str());
|
||||
return;
|
||||
}
|
||||
|
||||
if (pid == 0) {
|
||||
static char * argv[] = { name };
|
||||
execve(script.c_str(), argv, env);
|
||||
Log::error("Could not execute %s (%i): %s", script.c_str(), errno, strerror(errno));
|
||||
exit(1);
|
||||
}
|
||||
#endif // _LINUX
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue