Beispiel #1
0
bool DHASWifiNodesModule:: processDataFromMulticastSocket()
{
    char buf[2000];
    struct sockaddr_in src;
    socklen_t addrlen;

    addrlen = sizeof(struct sockaddr_in);
    int n = recvfrom(mSocket, buf, 2000, 0, (struct sockaddr*)&src, &addrlen);
    if(n<0)
    {
        if (errno == EAGAIN) return true; // Why would this happen?
        close(mSocket);
        LOG("Multicast listener read returned " << n << "(" << errno << "). Socket closed.");
        return false;
    }
    else if (n>0)
    {
        std::string str(buf,n);
        Dumais::JSON::JSON json;
        json.parse(str);
        char* ip = inet_ntoa(src.sin_addr);
        this->discoverNode(json["name"].str(),ip,json["id"].str());
    }

    return true;
}
Beispiel #2
0
void KeypadLinc::toJSON(Dumais::JSON::JSON& obj)
{
        std::stringstream ss;
        ss << "0x" << std::hex << std::setfill('0') << std::setw(6) << mID;
        obj.addValue(ss.str(),"id");
        obj.addValue(this->getName(),"name");
        obj.addValue(this->getDeviceType(),"type");
//        obj.addValue(this->getState()?255:0,"level");
}
Beispiel #3
0
void RESTCallBack::getDescription(Dumais::JSON::JSON& json)
{
    json.addValue(mDescription,"description");
    Dumais::JSON::JSON& params = json.addList("params");
    for (ParamMap::const_iterator it = mParamList.begin(); it!=mParamList.end(); it++)
    {
        Dumais::JSON::JSON& j = params.addObject("param");
        j.addValue(it->first,"name");
        j.addValue(it->second.mDescription, "description");
    }
}
Beispiel #4
0
RESTEngine::ResponseCode RESTCallBack::call(Dumais::JSON::JSON& json, const std::string& paramString,
                                            const std::string& dataString, std::smatch& matches,
                                            std::shared_ptr<void> userData)
{
    RESTParameters params(paramString, mParamList);
    // Let's check required params
    for (ParamMap::const_iterator it = mParamList.begin(); it != mParamList.end(); ++it) {
        // todo later : handle/check in "path" parameters: http://server:port/param1/param2
        if (it->second.mRequired && (it->second.mLocation == "query") ) {
            if (params.getParam(it->first).empty()) {
                std::cerr << "Missing mandatory parameter " <<  it->first << std::endl;
                // todo : replace empty parameter value by default parameter value
                json.addValue("Missing required parameter " + it->first, "error");
                return RESTEngine::ResponseCode::BadRequest;
            }
        }
    }

    RESTEngine::ResponseCode responseCode = RESTEngine::ResponseCode::OK;
    RESTContext context ={
        json,
        &params,
        dataString,
        matches,
        responseCode,
        userData
    };
    assert(mCallback);
    if (mCallback)
        mCallback(&context);
    return responseCode;
}
Beispiel #5
0
void Subscription::toJSON(Dumais::JSON::JSON& json)
{
    Dumais::JSON::JSON& j = json.addObject("subscription");
    j.addValue(getID(),"id");
    j.addValue(mDevice,"device");
    j.addValue(mDeviceStatus,"devicestate");
}
Beispiel #6
0
void Thermostat::toJSON(Dumais::JSON::JSON& obj)
{
        std::stringstream ss;
        ss << "0x" << std::hex << std::setfill('0') << std::setw(6) << mID;
        obj.addValue(ss.str(),"id");
        obj.addValue(this->getName(),"name");
        obj.addValue(this->getDeviceType(),"type");
        obj.addValue((unsigned int)this->getTemperature(),"temperature");
        obj.addValue((unsigned int)this->getHeatSetPoint(),"heatpoint");
        obj.addValue((unsigned int)this->getCoolSetPoint(),"coolpoint");
        obj.addValue((unsigned int)this->getHumidity(),"humidity");
        obj.addValue((unsigned int)this->getOperatingMode(),"operatingmode");
        obj.addValue((unsigned int)this->getOperatingState(),"operatingstate");
        obj.addValue((unsigned int)mThermostatProgram.isActive(),"programactive");
}
Beispiel #7
0
void Insteon::listModules(Dumais::JSON::JSON& json)
{

    for (std::map<InsteonID,InsteonDevice*>::iterator it=mModules.begin();it!=mModules.end();it++)
    {
        Dumais::JSON::JSON& obj = json.addObject("module");
        it->second->toJSON(obj);
//        printf("TEST %s\r\n",obj.stringify(false).c_str());
    }
}
Beispiel #8
0
void DHASWifiNodesModule::checkHeartBeats()
{
    time_t t;
    time(&t);
    t -= (3*NODE_HEARTBEAT);
    for (auto& it : mNodes)
    {
        DHASWifiNode* node = &it.second;
        if (node->lastHeartBeat <= t)
        {
            LOG("Node [" << node->driver->getName() <<"] @ " << node->driver->getInfo().ip << " heartbeat failure. Disconnecting");
            close(node->socket);

            Dumais::JSON::JSON json;
            json.addValue("dwn","event");
            json.addValue("closed","type");
            json.addValue(node->driver->getInfo().ip,"ip");
            json.addValue(node->driver->getName(),"name");
            json.addValue(node->driver->getInfo().id,"id");
            mpEventProcessor->processEvent(json);

            std::string ip = node->driver->getInfo().ip;
            node->driver->unRegisterCallBacks(mpRestEngine);
            delete node->driver;
            node->driver = 0;

            this->mNodesListLock.lock();
            mNodes.erase(ip);
            this->mNodesListLock.unlock();
        }
    }
}
Beispiel #9
0
void Thermostat::getProgramPoints(Dumais::JSON::JSON& json)
{
    json.addList("points");

    for (unsigned char i=0;i<(24*7);i++)
    {
        ProgramPoint point = mThermostatProgram.getPoint(i);
        if (point.mode > 0)
        {
            Dumais::JSON::JSON& obj = json["points"].addObject("ProgramPoint");
            obj.addValue(point.temp,"temperature");
            obj.addValue(point.mode,"mode");      
            obj.addValue(i,"hour");
        }
    }
}
void RESTEngine::documentInterface(Dumais::JSON::JSON& json)
{
    json.addList("api");
    for (CallbackMap::iterator it = mCallbacks.begin(); it != mCallbacks.end(); it++)
    {
        std::string method = it->first;
        std::transform(method.begin(),method.end(),method.begin(),::toupper);
        for (auto it2 = it->second.begin(); it2 != it->second.end(); ++it2)
        {
            Dumais::JSON::JSON& j = json["api"].addObject();
            it2->mpCallback->getDescription(j);
            j.addValue(it2->uri,"path");
            j.addValue(method,"method");
        }
    }

    return;
}
Beispiel #11
0
void KeypadLinc::processEvent(Dumais::JSON::JSON& json, unsigned char* buf)
{
    // Get the status
    unsigned char flags = buf[8];
    unsigned char status = (flags & 0b11100000)>>5;
    unsigned char cmd1 = buf[9];
    unsigned char cmd2 = buf[10];
    bool ackOfDirectMessage = (status==0b001);

    if (status==0b010)    // Group cleanup direct message
    {
        json.addValue("insteon","event");
        json.addValue(mID,"id");
        json.addValue(this->getName(),"name");
        json.addValue("unsolicited","trigger");

        unsigned char level = 0;
        if (cmd1==0x11){
            level = 255;
            json.addValue("keypad","type");
            json.addValue(cmd2,"button");
            json.addValue(level,"value");

            /* we turn button off again so that it gets updated by script instead. This is a hack
             * otherwise the button is on, but if nothing reacts to it, it will stay on
             */
            //turnOnOrOff(false,0,cmd2);
        } else if (cmd1==0x13) {
            level = 0;
            json.addValue("keypad","type");
            json.addValue(cmd2,"button");
            json.addValue(level,"value");

            /* we turn button on again so that it gets updated by script instead. This is a hack
             * otherwise the button is on, but if nothing reacts to it, it will stay on
             */
            //turnOnOrOff(true,0,cmd2);
        }
     }

}
Beispiel #12
0
void DHASWifiNodesModule::discoverNode(std::string name, std::string ip, std::string id)
{
    if (ip == "0.0.0.0") return;

    if (mNodes.find(ip) == mNodes.end())
    {
        LOG("Found an advertisement from [" << name << "] at " << ip);
        if (mNodes.size() >= MAX_NODES_COUNT)
        {
            LOG("ERROR: The number of nodes registered in the system has reached maximum capacity");
            return;
        }

        IDWN* driver = IDWN::createDriverInstance(name);
        if (driver == 0)
        {
            // TODO: should probably ignore all further broadcasts.
            LOG("ERROR: No suitable driver found for wifi node [" << name << "]");
            return;
        }

        DHASWifiNode node;
        node.driver = driver;
        node.driver->getInfo().ip = ip;
        node.driver->getInfo().id = id;
        node.driver->getInfo().sendQueue = &mSendQueue;
        time(&node.lastHeartBeat);

        if (connectNode(&node))
        {
            LOG("Node [" << name << "] @ " << ip << " connected.");
            this->mNodesListLock.lock();
            mNodes[ip] = node;
            this->mNodesListLock.unlock();

            node.driver->registerCallBacks(mpRestEngine);

            Dumais::JSON::JSON json;
            json.addValue("dwn","event");
            json.addValue("new","type");
            json.addValue(ip,"ip");
            json.addValue(name,"name");
            json.addValue(id,"id");
            mpEventProcessor->processEvent(json);
        }
        else
        {
            LOG("Could not connect to node [" << name << "] @ " << ip);
        }
    }
}
Beispiel #13
0
void DHASWifiNodesModule::receiveFromNode(DHASWifiNode* node)
{

    //TODO: we could be receiving two messages in the same packet. we should accumulate in buffer until we find a terminating 0.
    //      and all DWN devices should terminate a message with 0
    char buf[2000];
    int n = recv(node->socket,buf,2000,0);
    //LOG("receiving from node: " << n << "  " << errno);
    if (n<=0)
    {
        if (n==-1 && errno == EAGAIN) return;

        LOG("Node failed [" << node->driver->getName() << "] @ " << node->driver->getInfo().ip << " (" << errno << "). Removing");
        close(node->socket);

        Dumais::JSON::JSON json;
        json.addValue("dwn","event");
        json.addValue("closed","type");
        json.addValue(node->driver->getInfo().ip,"ip");
        json.addValue(node->driver->getName(),"name");
        json.addValue(node->driver->getInfo().id,"id");
        mpEventProcessor->processEvent(json);

        std::string ip = node->driver->getInfo().ip;
        node->driver->unRegisterCallBacks(mpRestEngine);
        delete node->driver;
        node->driver = 0;

        this->mNodesListLock.lock();
        mNodes.erase(ip);
        this->mNodesListLock.unlock();
        return;
    }

    std::string payload (buf,n);
    //LOG("payload (" << n << "): " << payload);
    if (payload == "yo!\r\n")
    {
        time(&node->lastHeartBeat);
    }
    else
    {
        if (node->driver == 0)
        {
            LOG("ERROR: Can't process data from " << node->driver->getName() <<" ("<<node->driver->getInfo().id<<". Driver not associated");
        }
        else
        {
            Dumais::JSON::JSON j;
            if (node->driver->processData(buf,n,j))
            {
                j.addValue("dwn","event");
                j.addValue(node->driver->getInfo().ip,"ip");
                j.addValue(node->driver->getName(),"name");
                j.addValue(node->driver->getInfo().id,"id");
                mpEventProcessor->processEvent(j);
            }
        }
    }
}